{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":13451,"datasetId":654585,"databundleVersionId":1188070},{"sourceType":"datasetVersion","sourceId":7164777,"datasetId":4138741,"databundleVersionId":7253855},{"sourceType":"datasetVersion","sourceId":7171484,"datasetId":4143537,"databundleVersionId":7260601}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Important Libraries**","metadata":{}},{"cell_type":"markdown","source":"## normal instalation","metadata":{"execution":{"iopub.status.busy":"2023-12-05T20:31:51.893528Z","iopub.execute_input":"2023-12-05T20:31:51.894051Z","iopub.status.idle":"2023-12-05T20:31:51.898306Z","shell.execute_reply.started":"2023-12-05T20:31:51.894016Z","shell.execute_reply":"2023-12-05T20:31:51.897339Z"}}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport os\nimport pydicom\nimport pandas as pd\nfrom shutil import copy, copy2, make_archive\nimport json\nimport cv2\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms, utils, models\nfrom sklearn.model_selection import train_test_split\nfrom torch.utils.data import Subset\nfrom PIL import Image\n\n# from torchvision.datasets import YourDataset  # Replace with the actual dataset class\n\n\nfrom skimage import io, transform\nimport warnings\nwarnings.filterwarnings(\"ignore\")   # Ignore warnings\nplt.ion()   # interactive mode\n\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:31.390806Z","iopub.execute_input":"2023-12-11T17:17:31.391183Z","iopub.status.idle":"2023-12-11T17:17:37.203397Z","shell.execute_reply.started":"2023-12-11T17:17:31.391152Z","shell.execute_reply":"2023-12-11T17:17:37.20237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Kaggle and API","metadata":{}},{"cell_type":"code","source":"# api_key = {'username' : \"ahmedlgazzar\",\n#            'key' : \"bac8e1a5f16bc756253a2f44c8a4d992\"}\n# with open('/kaggle/working/api_key.json', 'w') as f:\n#     json.dump(api_key, f)\n\n# !mkdir -p /root/.kaggle\n# !cp /kaggle/working/api_key.json /root/.kaggle/kaggle.json\n# !chmod 600 /root/.kaggle/kaggle.json\n# !ls -l /root/.kaggle/","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.205446Z","iopub.execute_input":"2023-12-11T17:17:37.206014Z","iopub.status.idle":"2023-12-11T17:17:37.210603Z","shell.execute_reply.started":"2023-12-11T17:17:37.205978Z","shell.execute_reply":"2023-12-11T17:17:37.209762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip install kaggle\n# !pip install --upgrade kaggle\n# import kaggle","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.212107Z","iopub.execute_input":"2023-12-11T17:17:37.212495Z","iopub.status.idle":"2023-12-11T17:17:37.224808Z","shell.execute_reply.started":"2023-12-11T17:17:37.21243Z","shell.execute_reply":"2023-12-11T17:17:37.223859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Checking Device (Accelerator)","metadata":{}},{"cell_type":"code","source":"import torch\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(\"Using device:\", device)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.226583Z","iopub.execute_input":"2023-12-11T17:17:37.226864Z","iopub.status.idle":"2023-12-11T17:17:37.259722Z","shell.execute_reply.started":"2023-12-11T17:17:37.226838Z","shell.execute_reply":"2023-12-11T17:17:37.258776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Checking CUDA Memory","metadata":{}},{"cell_type":"code","source":"# !pip install GPUtil\n\n# from GPUtil import showUtilization as gpu_usage\n# gpu_usage()","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.261014Z","iopub.execute_input":"2023-12-11T17:17:37.261701Z","iopub.status.idle":"2023-12-11T17:17:37.279795Z","shell.execute_reply.started":"2023-12-11T17:17:37.261661Z","shell.execute_reply":"2023-12-11T17:17:37.278965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # https://www.kaggle.com/discussions/getting-started/140636\n\n# import torch\n# from GPUtil import showUtilization as gpu_usage\n# from numba import cuda\n\n# def free_gpu_cache():\n#     print(\"Initial GPU Usage\")\n#     gpu_usage()                             \n\n#     torch.cuda.empty_cache()\n\n#     cuda.select_device(0)\n#     cuda.close()\n#     cuda.select_device(0)\n\n#     print(\"GPU Usage after emptying the cache\")\n#     gpu_usage()\n    \n# free_gpu_cache()","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.280973Z","iopub.execute_input":"2023-12-11T17:17:37.281314Z","iopub.status.idle":"2023-12-11T17:17:37.29106Z","shell.execute_reply.started":"2023-12-11T17:17:37.281283Z","shell.execute_reply":"2023-12-11T17:17:37.290127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Dicom Dataset Manuplation Functions**","metadata":{}},{"cell_type":"markdown","source":"## Copied From another","metadata":{}},{"cell_type":"code","source":"def get_dicom_value(x, cast=int):\n    if type(x) in [pydicom.multival.MultiValue, tuple]:\n        return cast(x[0])\n    else:\n        return cast(x)\n\n\ndef cast(value):\n    if type(value) is pydicom.valuerep.MultiValue:\n        return tuple(value)\n    return value\n\n\ndef get_dicom_raw(dicom):\n    return {attr:cast(getattr(dicom,attr)) for attr in dir(dicom) if attr[0].isupper() and attr not in ['PixelData']}\n\n\ndef rescale_image(image, slope, intercept):\n    return image * slope + intercept\n\ndef apply_window(image, center, width):\n    image = image.copy()\n    min_value = center - width // 2\n    max_value = center + width // 2\n    image[image < min_value] = min_value\n    image[image > max_value] = max_value\n    return image\n\ndef apply_window_policy(image):\n\n    image1 = apply_window(image, 40, 80) # brain\n    image2 = apply_window(image, 80, 200) # subdural\n    image3 = apply_window(image, 40, 380) # bone\n    image1 = (image1 - 0) / 80\n    image2 = (image2 - (-20)) / 200\n    image3 = (image3 - (-150)) / 380\n    image = np.array([\n        image1 - image1.mean(),\n        image2 - image2.mean(),\n        image3 - image3.mean(),\n    ]).transpose(1,2,0)\n\n    return image\n\ndef convert_dicom_to_jpg(name):\n#     imgnm = (name.split('/')[-1]).replace('.dcm', '')\n#     dicom = pydicom.dcmread(DicomBytesIO(data))\n    dicom = pydicom.dcmread(name)\n    image = dicom.pixel_array\n    image = rescale_image(image,dicom.RescaleSlope, dicom.RescaleIntercept )\n    image = apply_window_policy(image)\n    image -= image.min((0,1))\n    image = (255*image).astype(np.uint8)\n    return image","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.292473Z","iopub.execute_input":"2023-12-11T17:17:37.292873Z","iopub.status.idle":"2023-12-11T17:17:37.305842Z","shell.execute_reply.started":"2023-12-11T17:17:37.292815Z","shell.execute_reply":"2023-12-11T17:17:37.304881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Our manuplation Functions","metadata":{}},{"cell_type":"code","source":"# csv functions\ndef get_train_csv(df1, filenames=None):\n\n    df1['filename'] = df1['ID'].apply(lambda x: '_'.join(x.split('_')[:-1]) + '.jpg')\n    df1['Illness'] = df1['ID'].apply(lambda x: x.split('_')[-1])\n    \n    # Drop the old 'ID' column as it's no longer needed\n    df1.drop(columns=['ID'], inplace=True)\n    \n    # Aggregate rows that have the same 'filename' and 'Illness' by summing up the 'Label'\n    df1 = df1.groupby(['filename', 'Illness']).agg('sum').reset_index()\n    \n    # Pivot the table to get Illness types as columns\n    df2 = df1.pivot(index='filename', columns='Illness', values='Label').reset_index()\n    \n    # Reorder the columns as per your requirements\n    columns = ['filename', 'any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n    df2 = df2.reindex(columns=columns)\n    \n    # Fill NaN with zeros since some filenames might not have all types of illnesses\n    df2.fillna(0, inplace=True)\n    \n    # Cast the label values to integers\n    label_columns = ['any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n    df2[label_columns] = df2[label_columns].astype(int)\n    \n    # Add the '.jpg' extension to filenames if not already there\n    if filenames:\n        filenames = [f if f.endswith('.jpg') else f + '.jpg' for f in filenames]\n        # Filter the DataFrame to only include filenames provided in the 'filenames' list\n        df2 = df2[df2['filename'].isin(filenames)]\n    \n    return df2","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.308533Z","iopub.execute_input":"2023-12-11T17:17:37.308819Z","iopub.status.idle":"2023-12-11T17:17:37.32125Z","shell.execute_reply.started":"2023-12-11T17:17:37.308793Z","shell.execute_reply":"2023-12-11T17:17:37.320326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Real Training**","metadata":{}},{"cell_type":"code","source":"class RSNA_jpg_Dataset(Dataset):\n    \"\"\"RSNA JPG dataset.\"\"\"\n\n    def __init__(self, csv_file, root_dir, size=None, transforms=None):\n        \"\"\"\n        Arguments:\n            csv_file (string): Path to the csv file with labels.\n            all_dir (dict): Dictionary with all the images directories.\n            transform (callable, optional): Optional transform to be applied\n                on a sample.\n        \"\"\"\n        self.labels_image = pd.read_csv(csv_file)\n        self.root_dir = root_dir\n        self.transforms = transforms\n        self.size = size if size else len(self.labels_image)\n\n    def __len__(self):\n        return self.size\n\n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n        \n        img_path = os.path.join(self.root_dir,\n                                self.labels_image.iloc[idx, 0])\n        image = Image.open(img_path)\n        image = cv2.imread(img_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        labels = self.labels_image.iloc[idx, 1:].astype(np.float32)\n        labels = torch.tensor(labels)\n#         labels = np.array(labels, dtype=int)\n        if self.transforms:\n            image = Image.fromarray(image)\n            image = self.transforms(image)\n            \n        sample = {'image': image, 'labels': labels}\n        return sample\n    \ndef show_samples(ourDataSet, start, end = None, rows = 1, columns = 1):\n    if end is None:\n        end = start\n    fig = plt.figure()\n    total = end - start + 1\n    exp_rows = total / columns\n    if(exp_rows > rows):\n        rows = int(np.ceil(exp_rows))\n        print (f'We extended the number of rows to be {rows}')\n    \n    for i in range(start, end + 1):\n        \n        sample = ourDataSet[i]\n        print(i, sample['image'].shape, sample['labels'].shape, sample['labels'])\n\n        ax = plt.subplot(rows, columns, (i - start) + 1)\n        plt.tight_layout()\n        ax.set_title('Sample #{}'.format(i))\n        ax.axis('off')\n        plt.imshow(sample['image'])\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.816381Z","iopub.execute_input":"2023-12-11T17:17:37.817293Z","iopub.status.idle":"2023-12-11T17:17:37.830355Z","shell.execute_reply.started":"2023-12-11T17:17:37.817256Z","shell.execute_reply":"2023-12-11T17:17:37.829517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class Rescale(object):\n#     \"\"\"Rescale the image in a sample to a given size.\n\n#     Args:\n#         output_size (tuple or int): Desired output size. If tuple, output is\n#             matched to output_size. If int, smaller of image edges is matched\n#             to output_size keeping aspect ratio the same.\n#     \"\"\"\n\n#     def __init__(self, output_size):\n#         assert isinstance(output_size, (int, tuple))\n#         self.output_size = output_size\n\n#     def __call__(self, sample):\n#         image, labels = sample['image'], sample['labels']\n\n#         h, w = image.shape[:2]\n#         if isinstance(self.output_size, int):\n#             if h > w:\n#                 new_h, new_w = self.output_size * h / w, self.output_size\n#             else:\n#                 new_h, new_w = self.output_size, self.output_size * w / h\n#         else:\n#             new_h, new_w = self.output_size\n\n#         new_h, new_w = int(new_h), int(new_w)\n\n#         img = transform.resize(image, (new_h, new_w))\n\n#         return {'image': img, 'labels': labels}\n\n\n# class RandomCrop(object):\n#     \"\"\"Crop randomly the image in a sample.\n\n#     Args:\n#         output_size (tuple or int): Desired output size. If int, square crop\n#             is made.\n#     \"\"\"\n\n#     def __init__(self, output_size):\n#         assert isinstance(output_size, (int, tuple))\n#         if isinstance(output_size, int):\n#             self.output_size = (output_size, output_size)\n#         else:\n#             assert len(output_size) == 2\n#             self.output_size = output_size\n\n#     def __call__(self, sample):\n#         image, labels = sample['image'], sample['labels']\n\n#         h, w = image.shape[:2]\n#         new_h, new_w = self.output_size\n\n#         top = np.random.randint(0, h - new_h + 1)\n#         left = np.random.randint(0, w - new_w + 1)\n\n#         image = image[top: top + new_h,\n#                       left: left + new_w]\n\n#         return {'image': image, 'labels': labels}\n\n\n# class ToTensor(object):\n#     \"\"\"Convert ndarrays in sample to Tensors.\"\"\"\n\n#     def __call__(self, sample):\n#         image, labels = sample['image'], sample['labels']\n\n#         # swap color axis because\n#         # numpy image: H x W x C\n#         # torch image: C x H x W\n#         image = image.transpose((2, 0, 1))\n#         return {'image': torch.from_numpy(image),\n#                 'labels': torch.from_numpy(labels)}\n","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:37.964409Z","iopub.execute_input":"2023-12-11T17:17:37.96472Z","iopub.status.idle":"2023-12-11T17:17:37.970783Z","shell.execute_reply.started":"2023-12-11T17:17:37.964692Z","shell.execute_reply":"2023-12-11T17:17:37.969883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_val_dataset(dataset, val_split=0.2):\n    train_idx, val_idx = train_test_split(list(range(len(dataset))), test_size=val_split)\n    datasets = {}\n    datasets['train'] = Subset(dataset, train_idx)\n    datasets['val'] = Subset(dataset, val_idx)\n    return datasets","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:38.198018Z","iopub.execute_input":"2023-12-11T17:17:38.198722Z","iopub.status.idle":"2023-12-11T17:17:38.203799Z","shell.execute_reply.started":"2023-12-11T17:17:38.198692Z","shell.execute_reply":"2023-12-11T17:17:38.202889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"root_dir = \"/kaggle/input/all-rsna-jpg/ALL_RSNA_JPG\"\ncsv_file = '/kaggle/input/all-rsna-jpg/labels.csv'\n\nfiles = os.listdir(root_dir)\nprint(len(files))\ncsv = pd.read_csv(csv_file)\nprint(len(csv))","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:17:38.385211Z","iopub.execute_input":"2023-12-11T17:17:38.385903Z","iopub.status.idle":"2023-12-11T17:18:14.540188Z","shell.execute_reply.started":"2023-12-11T17:17:38.38586Z","shell.execute_reply":"2023-12-11T17:18:14.539216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"############################# VISUALIZATION ######################################\nourDataSet = RSNA_jpg_Dataset(csv_file = csv_file, \n                              root_dir = root_dir, \n                              size=None, \n                              transforms=None)\n\nshow_samples(ourDataSet,\n            start = 1,\n            end = 12,\n            rows = 3,\n            columns = 4)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:14.542124Z","iopub.execute_input":"2023-12-11T17:18:14.542495Z","iopub.status.idle":"2023-12-11T17:18:17.308645Z","shell.execute_reply.started":"2023-12-11T17:18:14.542458Z","shell.execute_reply":"2023-12-11T17:18:17.307636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transforms = {\n    'train': transforms.Compose([\n        transforms.RandomResizedCrop(224),\n        transforms.RandomHorizontalFlip(),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n    'val': transforms.Compose([\n        transforms.Resize(228),\n        transforms.CenterCrop(224),\n        transforms.ToTensor(),\n#         transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n}\n    ","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:17.309746Z","iopub.execute_input":"2023-12-11T17:18:17.31005Z","iopub.status.idle":"2023-12-11T17:18:17.316054Z","shell.execute_reply.started":"2023-12-11T17:18:17.310024Z","shell.execute_reply":"2023-12-11T17:18:17.315186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transforms['val']","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:17.318729Z","iopub.execute_input":"2023-12-11T17:18:17.319497Z","iopub.status.idle":"2023-12-11T17:18:17.329296Z","shell.execute_reply.started":"2023-12-11T17:18:17.319462Z","shell.execute_reply":"2023-12-11T17:18:17.328555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"############################ VISUALIZATION ######################################\n# transformed_dataset = RSNA_jpg_Dataset(csv_file = csv_file,\n#                                        root_dir = root_dir,\n#                                        size=None,\n#                                        transforms=transforms.Compose([\n#                                            Rescale(256),\n#                                            RandomCrop(224),\n#                                            ToTensor()\n#                                        ]))\ntransformed_dataset = RSNA_jpg_Dataset(csv_file = csv_file,\n                                       root_dir = root_dir,\n                                       size=None,\n                                       transforms=data_transforms['val'])\n\n\n\nfor i, sample in enumerate(transformed_dataset):\n    print(i, sample['image'].size(), sample['labels'].size())\n#     print(sample['labels'].device)\n    if i == 11:\n        break","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:17.330327Z","iopub.execute_input":"2023-12-11T17:18:17.330557Z","iopub.status.idle":"2023-12-11T17:18:18.063344Z","shell.execute_reply.started":"2023-12-11T17:18:17.330536Z","shell.execute_reply":"2023-12-11T17:18:18.06228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"############################# VISUALIZATION ######################################\n\ndataloader = DataLoader(transformed_dataset, batch_size=12,\n                        shuffle=True, num_workers=0)\n\n\n# Helper function to show a batch\ndef show_batch(sample_batched):\n    \"\"\"Show image with labels for a batch of samples.\"\"\"\n    images_batch, labels_batch = \\\n            sample_batched['image'], sample_batched['labels']\n    batch_size = len(images_batch)\n    im_size = images_batch.size(2)\n    grid_border_size = 2\n\n    grid = utils.make_grid(images_batch)\n    plt.imshow(grid.numpy().transpose((1, 2, 0)))\n\n# if you are using Windows, uncomment the next line and indent the for loop.\n# you might need to go back and change ``num_workers`` to 0.\n\n# if __name__ == '__main__':\nfor i_batch, sample_batched in enumerate(dataloader):\n    print(i_batch, sample_batched['image'].size(),\n          sample_batched['labels'].size())\n\n    # observe 4th batch and stop.\n    if i_batch == 11:\n        plt.figure()\n        show_batch(sample_batched)\n        plt.axis('off')\n        plt.ioff()\n        plt.show()\n        break","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:18.06453Z","iopub.execute_input":"2023-12-11T17:18:18.064822Z","iopub.status.idle":"2023-12-11T17:18:21.108313Z","shell.execute_reply.started":"2023-12-11T17:18:18.064796Z","shell.execute_reply":"2023-12-11T17:18:21.107237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Define your neural network architecture (e.g., ResNet with modified output for multi-label classification)\n# class MultiLabelModel(nn.Module):\n#     def __init__(self, num_classes):\n#         super(MultiLabelModel, self).__init__()\n#         # Replace with your chosen architecture\n#         self.model = models.resnet18(pretrained=True )\n#         self.model.fc = nn.Linear(self.model.fc.in_features, num_classes)\n#     def forward(self, x):\n#         return self.model(x)\n\n# alternative approach for the model \n\nclass MultiLabelModel(nn.Module):\n    def __init__(self, num_classes):\n        super(MultiLabelModel, self).__init__()\n        # Load pre-trained ResNet-18 model with ImageNet weights\n        model_ft = models.resnet18(weights='IMAGENET1K_V1')\n        num_ftrs = model_ft.fc.in_features\n\n        # Replace the last fully connected layer\n        self.model = model_ft\n        self.model.fc = nn.Linear(num_ftrs, num_classes)\n\n    def forward(self, x):\n        return self.model(x)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:21.109865Z","iopub.execute_input":"2023-12-11T17:18:21.110187Z","iopub.status.idle":"2023-12-11T17:18:21.11657Z","shell.execute_reply.started":"2023-12-11T17:18:21.110158Z","shell.execute_reply":"2023-12-11T17:18:21.115615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Set your hyperparameters\nnum_classes = 6  # Replace with the actual number of classes\nbatch_size = 128\nnum_workers = 8\nepochs = 1\nlearning_rate = 0.001\n# prefetch_factor  = 60\n# Initialize your model, loss function, and optimizer\nmodel = MultiLabelModel(num_classes)\ncriterion = nn.BCEWithLogitsLoss()  # Binary Cross Entropy with Logits Loss for multi-label classification\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:21.117787Z","iopub.execute_input":"2023-12-11T17:18:21.118161Z","iopub.status.idle":"2023-12-11T17:18:21.693148Z","shell.execute_reply.started":"2023-12-11T17:18:21.118127Z","shell.execute_reply":"2023-12-11T17:18:21.69221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### IMP RUN THIS CELL IF YOU HAVE A SAVED MODEL ####\nmodel_path = '/kaggle/input/resnet18-model/multi_label_model.pth'\nmodel = torch.load(model_path)\n\nmodel = MultiLabelModel(num_classes)\n\n# Load the saved state dictionary\nmodel.load_state_dict(torch.load(model_path))\n\n# Set the model to evaluation mode\nmodel.eval()\n# Define other necessary parameters (e.g., device)\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:18:21.694346Z","iopub.execute_input":"2023-12-11T17:18:21.695194Z","iopub.status.idle":"2023-12-11T17:18:25.603018Z","shell.execute_reply.started":"2023-12-11T17:18:21.695165Z","shell.execute_reply":"2023-12-11T17:18:25.602126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"##### ( this is a way to visualize the model archeticture ) ############\n## COMMENT THE FOLLOWING CELLS IF NOT NEEDED ## \n!pip install torchsummary\n!pip install torchviz\n","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:19:23.262717Z","iopub.execute_input":"2023-12-11T17:19:23.263131Z","iopub.status.idle":"2023-12-11T17:19:50.122095Z","shell.execute_reply.started":"2023-12-11T17:19:23.2631Z","shell.execute_reply":"2023-12-11T17:19:50.12103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchviz import make_dot\nimport IPython\n\nx = torch.randn(1, 3, 224, 224).cuda()\ny = model(x)\nmake_dot(y, params=dict(model.named_parameters())).render(\"model_graph\", format=\"png\")\n\n# Display the image in IPython\nIPython.display.display(IPython.display.Image(filename='/kaggle/working/model_graph.png'))","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:19:50.124019Z","iopub.execute_input":"2023-12-11T17:19:50.124344Z","iopub.status.idle":"2023-12-11T17:19:55.872009Z","shell.execute_reply.started":"2023-12-11T17:19:50.124315Z","shell.execute_reply":"2023-12-11T17:19:55.871113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DD","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# another way to see model architecture\nfrom torchsummary import summary\n\nmodel = model.to(\"cuda\")  # If your model is on GPU\nsummary(model, input_size=(3, 224, 224))","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:19:55.873138Z","iopub.execute_input":"2023-12-11T17:19:55.873425Z","iopub.status.idle":"2023-12-11T17:19:55.925788Z","shell.execute_reply.started":"2023-12-11T17:19:55.873397Z","shell.execute_reply":"2023-12-11T17:19:55.924811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\n# Load your dataset\n# all_dataset = RSNA_jpg_Dataset(csv_file = csv_file,\n#                                root_dir = root_dir,\n#                                size=None,\n#                                transforms=transforms.Compose([\n#                                    Rescale(256),\n#                                    RandomCrop(224),\n#                                    ToTensor()\n#                                ]))\n\nall_dataset = RSNA_jpg_Dataset(csv_file = csv_file,\n                               root_dir = root_dir,\n                               size=None,\n                               transforms=data_transforms['val'])\n\n\n# trainDS, validationDS = all_dataset[0:4000], all_dataset[4000:]\n\nall_dataset = train_val_dataset(all_dataset)\ntrainDS, validationDS = all_dataset['train'], all_dataset['val']\n\ntrain_dataloader = DataLoader(trainDS, batch_size=batch_size,num_workers=num_workers , shuffle=True,pin_memory=True, drop_last=True)\nval_dataloader = DataLoader(validationDS, batch_size=batch_size,num_workers=num_workers ,shuffle=True,pin_memory=True, drop_last=False)\n\ndataloaders = {'train': train_dataloader,\n               'val': val_dataloader}\ndataset_sizes = {'train': len(trainDS),\n                 'val': len(validationDS)}\nbest_model_params_path = os.path.join('/kaggle/working', 'best_model_params.pt')\n\n# Move the model to GPU if available\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint (device) \nmodel.to(device)\nprint(\"Model Device:\", next(model.parameters()).device)\nif torch.cuda.is_available():\n    print(\"[INFO] Using GPU: {}\\n\".format(torch.cuda.get_device_name()))\n","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:19:55.927634Z","iopub.execute_input":"2023-12-11T17:19:55.927961Z","iopub.status.idle":"2023-12-11T17:19:56.830333Z","shell.execute_reply.started":"2023-12-11T17:19:55.927933Z","shell.execute_reply":"2023-12-11T17:19:56.829381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for epoch in range(epochs) :\n#     print(f'Epoch {epoch}/{epochs - 1}')\n#     print('-' * 20)\n\n#     # Each epoch has a training and validation phase\n#     for phase in ['train', 'val']:\n#         if phase == 'train':\n#             model.train()  # Set model to training mode\n#         else:\n#             model.eval()   # Set model to evaluate mode\n\n#         running_loss = 0.0\n#         running_corrects = 0\n\n#         # Iterate over data.\n#         for i, batch in enumerate(dataloaders[phase]):\n#             inputs, labels = batch['image'], batch['labels']\n#             inputs, labels = inputs.to(device, dtype=torch.float), labels.to(device, dtype=torch.float)\n\n#             # zero the parameter gradients\n#             optimizer.zero_grad()\n\n#             # forward\n#             # track history if only in train\n#             with torch.set_grad_enabled(phase == 'train'):\n#                 outputs = model(inputs)\n#                 _, preds = torch.max(outputs, 1)\n#                 loss = criterion(outputs, labels)\n\n#                 # backward + optimize only if in training phase\n#                 if phase == 'train':\n#                     loss.backward()\n#                     optimizer.step()\n            \n#             batch_loss = loss.item()\n#             print(f\"Phase: {phase},  Epoch [{epoch+1}/{epochs}], Batch [{i+1}/{int(len(dataloaders[phase]))}], Loss: {batch_loss:.4f}\")\n#             running_loss += batch_loss\n\n#         average_loss = running_loss / len(dataloaders[phase])\n#         print(f\"Phase: {phase},  Epoch [{epoch+1}/{epochs}], Loss: {average_loss:.4f}\")\n\n# # Save the trained model\n# torch.save(model.state_dict(), \"multi_label_model.pth\")","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:19:56.831616Z","iopub.execute_input":"2023-12-11T17:19:56.831942Z","iopub.status.idle":"2023-12-11T17:19:56.837427Z","shell.execute_reply.started":"2023-12-11T17:19:56.831915Z","shell.execute_reply":"2023-12-11T17:19:56.836379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# run this cell before the training loop to check performance while training\nimport multiprocessing\nimport subprocess\nfrom IPython import display\nimport time\n\ndef check_gpu_usage():\n    while True:\n        display.clear_output(wait=True)\n        print(subprocess.check_output('nvidia-smi').decode().strip())\n        time.sleep(1)\nrunner = multiprocessing.Process(target=check_gpu_usage)\nrunner.start()","metadata":{"execution":{"iopub.status.busy":"2023-12-11T17:19:56.839205Z","iopub.execute_input":"2023-12-11T17:19:56.839568Z","iopub.status.idle":"2023-12-11T17:19:56.880936Z","shell.execute_reply.started":"2023-12-11T17:19:56.839535Z","shell.execute_reply":"2023-12-11T17:19:56.87938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# this is the same like the above cell , just integrated tqdm \nfor epoch in range(epochs):\n    print(f'Epoch {epoch}/{epochs - 1}')\n    print('-' * 20)\n\n    # Each epoch has a training and validation phase\n    for phase in ['train', 'val']:\n        if phase == 'train':\n            model.train()  # Set model to training mode\n        else:\n            model.eval()   # Set model to evaluate mode\n\n        running_loss = 0.0\n        running_corrects = 0\n\n        # Wrap the data loader with tqdm for a progress bar\n        data_loader = tqdm(dataloaders[phase], desc=f\"Phase: {phase}, Epoch [{epoch+1}/{epochs}]\")\n        \n        # Iterate over data.\n        for i, batch in enumerate(data_loader):\n            inputs, labels = batch['image'], batch['labels']\n            inputs, labels = inputs.to(device, dtype=torch.float), labels.to(device, dtype=torch.float)\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward\n            # track history if only in train\n            with torch.set_grad_enabled(phase == 'train'):\n                outputs = model(inputs)\n                _, preds = torch.max(outputs, 1)\n                loss = criterion(outputs, labels)\n\n                # backward + optimize only if in training phase\n                if phase == 'train':\n                    loss.backward()\n                    optimizer.step()\n\n            batch_loss = loss.item()\n            running_loss += batch_loss\n\n            # Update the progress bar with the batch loss\n            data_loader.set_postfix(batch_loss=batch_loss, avg_loss=(running_loss / (i + 1)))\n\n        average_loss = running_loss / len(dataloaders[phase])\n        print(f\"Phase: {phase}, Epoch [{epoch+1}/{epochs}], Loss: {average_loss:.4f}\")\n\n# Save the trained model\ntorch.save(model.state_dict(), \"multi_label_model.pth\")","metadata":{"execution":{"iopub.status.busy":"2023-12-10T23:40:51.129716Z","iopub.execute_input":"2023-12-10T23:40:51.130145Z","iopub.status.idle":"2023-12-10T23:40:57.205396Z","shell.execute_reply.started":"2023-12-10T23:40:51.130103Z","shell.execute_reply":"2023-12-10T23:40:57.204078Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# > **visualization**","metadata":{"execution":{"iopub.status.busy":"2023-12-10T23:41:06.527604Z","iopub.execute_input":"2023-12-10T23:41:06.528013Z","iopub.status.idle":"2023-12-10T23:41:06.535073Z","shell.execute_reply.started":"2023-12-10T23:41:06.527977Z","shell.execute_reply":"2023-12-10T23:41:06.53411Z"}}},{"cell_type":"code","source":"# Helper function to show a batch\nimport matplotlib.patches as patches\n\nlabels = ['any','epidural','intraparenchymal','intraventricular','subarachnoid','subdural']\n\n        \ndef show_batch_annotated(sample_batched, predictions=None , wrong_predictions_only = False , images_per_row = 4):\n    \"\"\"Show image with labels and optional predictions for each sample in the batch.\"\"\"\n    images_batch, labels_batch = sample_batched['image'], sample_batched['labels']\n    batch_size = len(images_batch)\n\n    # Convert labels to numpy arrays with data type int\n    if isinstance(labels_batch, np.ndarray) :\n        labels_batch = labels_batch.astype(int)\n    else : \n        labels_batch = labels_batch.numpy().astype(int)\n\n    if predictions is not None:\n        # Calculate accuracy \n        matches = (predictions == labels_batch).all(axis=1)\n        num_correct = matches.sum() \n        accuracy = num_correct / len(matches)\n        print(f'Accuracy: {accuracy:.2f}    {num_correct}/{len(matches)} correct ')\n\n        \n    if wrong_predictions_only:\n        indices = np.where(matches==False)[0]\n        matches = matches[indices]  # Update match based on filtered indices\n\n        images_batch = images_batch[indices]\n        labels_batch = labels_batch[indices] \n        predictions = predictions[indices]\n        batch_size = len(images_batch)\n        print(f'there is { len(indices) }  bad images -- >  { indices }')\n#         print([(label, prediction) for label , prediction in zip(labels_batch  , predictions)])\n        if batch_size <= 2 : \n            return\n    # Calculate rows and columns based on batch size\n    images_per_row = min(images_per_row , batch_size -1 )\n    rows = batch_size // images_per_row + (1 if batch_size % images_per_row > 0 else 0)\n    columns = min(images_per_row, batch_size)\n\n    # Create figure and axes\n    fig, axes = plt.subplots(rows, columns, figsize=(20, 5 * rows))\n\n    # Initialize counter for image and prediction indexes\n    i = 0\n    pred_idx = 0\n\n    # Loop through each row\n    for row in range(rows):\n        # Loop through columns in the current row\n        for col in range(columns):\n            # Check if there are remaining images\n            if i >= batch_size:\n                break\n            # Retrieve image and label\n            image = images_batch[i]\n            label = labels_batch[i]\n\n            # Get prediction if available\n            pred = None\n            if predictions is not None:\n                pred = predictions[pred_idx]\n                pred_idx += 1\n                \n            # Create title text\n            title_text = f'Labels:        {label}'\n            if pred is not None:\n                # Check if prediction matches labels\n                match = (pred == label).all() \n                title_text += f\"\\nPredictions: {pred}\"\n\n            # Add image and title to corresponding axis\n            axes[row, col].imshow(image.numpy().transpose((1, 2, 0)))\n            if pred is not None:\n                axes[row, col].set_title(title_text, color=('green' if match else 'red'))\n            else : \n                axes[row, col].set_title(title_text, color='green')\n\n            axes[row, col].axis(\"off\")  # Hide the axis\n\n            # Increment image index\n            i += 1\n \n    # Adjust layout and show the figure\n    fig.tight_layout()\n    plt.show()\n    \n    \n    \n    \n    \ndef run_model_on_samples(model , number_of_samples , verbose = 0 , wrong_predictions_only = False ,images_per_row = 4):\n\n    inference_dataloader = DataLoader(validationDS, batch_size=number_of_samples,num_workers=0 ,shuffle=True)\n    iterator = iter(inference_dataloader)\n    sample_batched = next(iterator)\n    print(sample_batched['image'].size(),sample_batched['labels'].size())\n    images_batch, labels_batch = sample_batched['image'], sample_batched['labels']\n    model_outputs = model(images_batch.cuda())\n    labels_batch = labels_batch.numpy().astype(int)\n    model_outputs = model_outputs.cpu().detach().numpy()\n    predictions = np.where(model_outputs > 0, 1, 0)\n    \n#     for debugging to see the results\n    if verbose > 0 : \n        for output , temp_prediction  , prediction in zip(labels_batch , model_outputs , predictions):\n            print(output , \"\\t\"  ,prediction,'\\t', temp_prediction)\n    \n\n    show_batch_annotated(sample_batched ,predictions = predictions, wrong_predictions_only = wrong_predictions_only, images_per_row = images_per_row   )\n\n","metadata":{"execution":{"iopub.status.busy":"2023-12-11T20:38:10.192981Z","iopub.execute_input":"2023-12-11T20:38:10.193938Z","iopub.status.idle":"2023-12-11T20:38:10.213928Z","shell.execute_reply.started":"2023-12-11T20:38:10.193897Z","shell.execute_reply":"2023-12-11T20:38:10.213097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# better to choose sample size > 2 at least \nrun_model_on_samples(model  = model , number_of_samples = 20 , images_per_row = 5)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T20:40:01.514997Z","iopub.execute_input":"2023-12-11T20:40:01.51537Z","iopub.status.idle":"2023-12-11T20:40:05.18776Z","shell.execute_reply.started":"2023-12-11T20:40:01.51534Z","shell.execute_reply":"2023-12-11T20:40:05.186743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"run_model_on_samples(model  = model , number_of_samples = 100 , wrong_predictions_only = True)","metadata":{"execution":{"iopub.status.busy":"2023-12-11T20:35:57.229946Z","iopub.execute_input":"2023-12-11T20:35:57.230624Z","iopub.status.idle":"2023-12-11T20:36:01.157298Z","shell.execute_reply.started":"2023-12-11T20:35:57.230588Z","shell.execute_reply":"2023-12-11T20:36:01.156363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}