{"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":[{"sourceId":13451,"databundleVersionId":1188070,"sourceType":"competition"},{"sourceId":7171484,"sourceType":"datasetVersion","datasetId":4143537},{"sourceId":7211633,"sourceType":"datasetVersion","datasetId":4167795},{"sourceId":7211654,"sourceType":"datasetVersion","datasetId":4172963},{"sourceId":7234236,"sourceType":"datasetVersion","datasetId":4138741}],"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":"!pip install -U albumentations\n!pip install validators matplotlib\n!pip install torchsummary\n!pip install torchviz\n!pip install kaggle\n!pip install --upgrade kaggle\n!pip install GPUtil\n!pip install albumentations\n!pip install pydicom\n\nfrom albumentations import Compose, ElasticTransform, RandomCrop, HorizontalFlip, VerticalFlip, Rotate\nimport albumentations\nimport copy as COPY\nfrom GPUtil import showUtilization as gpu_usage\nfrom numba import cuda\n\nfrom torchviz import make_dot\nimport IPython\nfrom torchsummary import summary\n\nimport 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\nimport torchvision.transforms as transforms\nfrom sklearn.model_selection import train_test_split\nfrom torch.utils.data import Subset\nfrom PIL import Image\nfrom torch.optim.lr_scheduler import StepLR\nfrom tqdm import tqdm\n\nimport requests\n%matplotlib inline\n\nfrom skimage import io, transform\nimport warnings\nwarnings.filterwarnings(\"ignore\")   # Ignore warnings\nplt.ion()   # interactive mode","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:23:04.969431Z","iopub.execute_input":"2023-12-31T05:23:04.969773Z","iopub.status.idle":"2023-12-31T05:25:03.09506Z","shell.execute_reply.started":"2023-12-31T05:23:04.969744Z","shell.execute_reply":"2023-12-31T05:25:03.094117Z"},"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/\n\n# import kaggle","metadata":{"execution":{"iopub.status.busy":"2023-12-19T06:14:56.9281Z","iopub.execute_input":"2023-12-19T06:14:56.92855Z","iopub.status.idle":"2023-12-19T06:14:56.932691Z","shell.execute_reply.started":"2023-12-19T06:14:56.928523Z","shell.execute_reply":"2023-12-19T06:14:56.93177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Checking Device (Accelerator)","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(\"Using device:\", device)","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:25:25.286024Z","iopub.execute_input":"2023-12-31T05:25:25.286566Z","iopub.status.idle":"2023-12-31T05:25:25.323642Z","shell.execute_reply.started":"2023-12-31T05:25:25.286536Z","shell.execute_reply":"2023-12-31T05:25:25.322718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Checking CUDA Memory","metadata":{}},{"cell_type":"code","source":"# gpu_usage()","metadata":{"execution":{"iopub.status.busy":"2023-12-19T06:14:56.968803Z","iopub.execute_input":"2023-12-19T06:14:56.969107Z","iopub.status.idle":"2023-12-19T06:14:56.982714Z","shell.execute_reply.started":"2023-12-19T06:14:56.969071Z","shell.execute_reply":"2023-12-19T06:14:56.981873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://www.kaggle.com/discussions/getting-started/140636\ndef 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    \nfree_gpu_cache()","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:25:31.201236Z","iopub.execute_input":"2023-12-31T05:25:31.201761Z","iopub.status.idle":"2023-12-31T05:25:31.500938Z","shell.execute_reply.started":"2023-12-31T05:25:31.201724Z","shell.execute_reply":"2023-12-31T05:25:31.499748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Dicom Dataset Manuplation Functions**","metadata":{}},{"cell_type":"markdown","source":"","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-31T05:25:33.502781Z","iopub.execute_input":"2023-12-31T05:25:33.50314Z","iopub.status.idle":"2023-12-31T05:25:33.516089Z","shell.execute_reply.started":"2023-12-31T05:25:33.503113Z","shell.execute_reply":"2023-12-31T05:25:33.515109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Visualization functions","metadata":{}},{"cell_type":"code","source":"class RSNA_jpg_Dataset(Dataset):\n    \"\"\"RSNA JPG dataset.\"\"\"\n\n    def __init__(self, csv_file, root_dir, one_output=False, 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.labels_image.drop(\"Unnamed: 0\", axis=1, inplace=True)\n        self.root_dir = root_dir\n        self.transforms = transforms\n        self.size = len(self.labels_image)\n        self.one_output = one_output\n\n    def __len__(self):\n        return self.size\n    \n    def name_rot(self, idx):\n        image = self.labels_image.iloc[idx, 0]\n        if '_rot_90' in image:\n            image = image[:-11]+'.jpg'\n            rot = 90\n        elif '_rot_180' in image:\n            image = image[:-12]+'.jpg'\n            rot = 180\n        elif '_rot_270' in image:\n            image = image[:-12]+'.jpg'\n            rot = 270\n        else:\n            rot = 0\n            \n        return image, rot\n    \n    def rot_image(self, image, rot):\n        if rot == 0:\n            return image\n        \n        elif rot == 90:\n            image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)\n            return image\n        \n        elif rot == 180:\n            image = cv2.rotate(image, cv2.ROTATE_180)\n            return image\n        \n        elif rot == 270:\n            image = cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)\n            return image\n\n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n        \n        image_name, rot = self.name_rot(idx)\n        img_path = os.path.join(self.root_dir, image_name)\n        image = Image.open(img_path)\n        image = cv2.imread(img_path)\n        image = self.rot_image(image, rot)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        if self.one_output:\n            labels = [self.labels_image.iloc[idx, 1].astype(np.float32)]\n        else:\n            labels = self.labels_image.iloc[idx, 1:].astype(np.float32)\n        labels = torch.tensor(labels)\n\n        if self.transforms:\n            image = Image.fromarray(image)\n            image = self.transforms(image)\n            \n        sample = {'image': image, 'labels': labels}\n        return sample","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:25:35.070475Z","iopub.execute_input":"2023-12-31T05:25:35.070859Z","iopub.status.idle":"2023-12-31T05:25:35.08796Z","shell.execute_reply.started":"2023-12-31T05:25:35.070828Z","shell.execute_reply":"2023-12-31T05:25:35.086799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def train_val_dataset(dataset, val_split=0.2, seed=37):\n#     \"\"\"\n#     Splits a dataset into training and validation sets with a specified split and random seed.\n\n#     Args:\n#         dataset: The data set to split.\n#         val_split: The proportion of data to be used for validation (float between 0.0 and 1.0).\n#         seed: Optional random seed for reproducibility (int).\n\n#     Returns:\n#         A dictionary with keys 'train' and 'val', each containing a subset of the original dataset.\n#     \"\"\"\n#     train_idx, val_idx = train_test_split(list(range(len(dataset))), test_size=val_split, random_state=seed)\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-30T06:00:59.687813Z","iopub.execute_input":"2023-12-30T06:00:59.688696Z","iopub.status.idle":"2023-12-30T06:00:59.694485Z","shell.execute_reply.started":"2023-12-30T06:00:59.688661Z","shell.execute_reply":"2023-12-30T06:00:59.693547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def get_loaders(csv_file, root_dir, transforms, batch_size, num_workers, one_output=False, val_split = 0.2, seed = 37):\n    \n#     all_dataset = RSNA_jpg_Dataset(csv_file = csv_file,\n#                                    root_dir = root_dir,\n#                                    one_output=one_output,\n#                                    transforms=transforms)\n\n#     all_dataset = train_val_dataset(all_dataset, val_split = val_split, seed = seed)\n#     trainDS, validationDS = all_dataset['train'], all_dataset['val']\n\n#     train_dataloader = DataLoader(trainDS, batch_size=batch_size,num_workers=num_workers , shuffle=True,pin_memory=True, drop_last=True)\n#     val_dataloader = DataLoader(validationDS, batch_size=batch_size,num_workers=num_workers ,shuffle=True,pin_memory=True, drop_last=False)\n\n#     dataloaders = {'train': train_dataloader,\n#                    'val': val_dataloader}\n#     dataset_sizes = {'train': len(trainDS),\n#                      'val': len(validationDS)}\n    \n#     return dataloaders, dataset_sizes\n\n\ndef get_loaders(csv_file_train, csv_file_valid, root_dir, transforms, batch_size, num_workers, one_output=False, val_split = 0.2, seed = 37):\n    \n    trainDS = RSNA_jpg_Dataset(csv_file = csv_file_train,\n                               root_dir = root_dir,\n                               one_output=one_output,\n                               transforms=transforms['train'])\n\n    \n    validationDS = RSNA_jpg_Dataset(csv_file = csv_file_valid,\n                                    root_dir = root_dir,\n                                    one_output=one_output,\n                                    transforms=transforms['val'])\n\n    train_dataloader = DataLoader(trainDS, batch_size=batch_size,num_workers=num_workers , shuffle=True,pin_memory=True, drop_last=True)\n    val_dataloader = DataLoader(validationDS, batch_size=batch_size,num_workers=num_workers ,shuffle=True,pin_memory=True, drop_last=False)\n\n    dataloaders = {'train': train_dataloader,\n                   'val': val_dataloader}\n    dataset_sizes = {'train': len(trainDS),\n                     'val': len(validationDS)}\n    \n    return dataloaders, dataset_sizes","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:25:42.265473Z","iopub.execute_input":"2023-12-31T05:25:42.265855Z","iopub.status.idle":"2023-12-31T05:25:42.273809Z","shell.execute_reply.started":"2023-12-31T05:25:42.265826Z","shell.execute_reply":"2023-12-31T05:25:42.272876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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()\n    return\n\n\n\n\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    return","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:27:41.303003Z","iopub.execute_input":"2023-12-31T05:27:41.303401Z","iopub.status.idle":"2023-12-31T05:27:41.313949Z","shell.execute_reply.started":"2023-12-31T05:27:41.303368Z","shell.execute_reply":"2023-12-31T05:27:41.312946Z"},"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":"markdown","source":"# **Whole Training Process**","metadata":{}},{"cell_type":"code","source":"class MultiLabelModel(nn.Module):\n    def __init__(self, num_classes, backbone, device, freeze=False):\n        super(MultiLabelModel, self).__init__()\n\n        # Load pre-trained backbone model\n        if backbone == \"resnet18\":\n            model_ft = models.resnet18(weights=\"IMAGENET1K_V1\")\n        elif backbone == \"resnet50\":\n            model_ft = models.resnet50(weights=\"IMAGENET1K_V1\")\n        elif backbone == \"resnet101\":\n            model_ft = models.resnet101(weights=\"IMAGENET1K_V1\")\n        elif backbone == \"resnet152\":\n            model_ft = models.resnet152(weights=\"IMAGENET1K_V1\")\n        elif backbone == \"densenet121\":\n            model_ft = models.densenet121(weights=\"IMAGENET1K_V1\")\n        elif backbone == \"densenet169\":\n            model_ft = models.densenet169(weights=\"IMAGENET1K_V1\")\n        else:\n            raise ValueError(f\"Unsupported backbone: {backbone}\")\n\n        # Freeze all parameters except the last layer if specified\n        if freeze:\n            for param in model_ft.parameters():\n                param.requires_grad = False\n\n        # Extract relevant features and add new classifier\n        if \"resnet\" in backbone:\n            num_ftrs = model_ft.fc.in_features\n            self.model = model_ft\n            self.model.fc = nn.Linear(num_ftrs, num_classes)\n        elif \"densenet\" in backbone:\n            num_ftrs = model_ft.classifier.in_features\n            self.model = model_ft\n            self.model.classifier = nn.Linear(num_ftrs, num_classes)\n        else:\n            raise ValueError(f\"Unsupported backbone: {backbone}\")\n\n        # Move model to device\n        self.model.to(device)\n\n    def forward(self, x):\n        return self.model(x)","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:27:47.648964Z","iopub.execute_input":"2023-12-31T05:27:47.649346Z","iopub.status.idle":"2023-12-31T05:27:47.659503Z","shell.execute_reply.started":"2023-12-31T05:27:47.649316Z","shell.execute_reply":"2023-12-31T05:27:47.658566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# seresneXt = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub', 'nvidia_se_resnext101_32x4d')\n# utils = torch.hub.load('NVIDIA/DeepLearningExamples:torchhub', 'nvidia_convnets_processing_utils')\n# last_layer = seresneXt.fc\n# new_fc = torch.nn.Linear(last_layer.in_features, num_classes)\n# seresneXt.fc = new_fc\n# sigmoid = torch.nn.Sigmoid()\n# seresneXt.fc = torch.nn.Sequential(new_fc, sigmoid)\n# seresneXt.eval().to(device)\n# model = seresneXt","metadata":{"execution":{"iopub.status.busy":"2023-12-19T06:14:57.076825Z","iopub.execute_input":"2023-12-19T06:14:57.077295Z","iopub.status.idle":"2023-12-19T06:14:57.088261Z","shell.execute_reply.started":"2023-12-19T06:14:57.077269Z","shell.execute_reply":"2023-12-19T06:14:57.087459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transforms = {\n    'train': transforms.Compose([\n#         ElasticTransform(alpha=0.2, sigma=80),  # SET: alpha controls magnitude, sigma controls smoothness\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-31T05:27:50.311732Z","iopub.execute_input":"2023-12-31T05:27:50.312109Z","iopub.status.idle":"2023-12-31T05:27:50.319572Z","shell.execute_reply.started":"2023-12-31T05:27:50.31208Z","shell.execute_reply":"2023-12-31T05:27:50.318279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set your hyperparameters\nnum_classes = 6  \nbatch_size = 64\nnum_workers = 16\nepochs = 5\nlearning_rate = 0.0001\n\n# Initialize your model, loss function, and optimizer\nmodel = MultiLabelModel(num_classes, backbone = \"resnet18\", device = device, freeze = True)\n\n### IF YOU HAVE A SAVED MODEL ####\nmodel_path = '/kaggle/input/resnet18-model/multi_label_model.pth'\nmodel_dict = torch.load(model_path)\nmodel.load_state_dict(model_dict, strict=False)\n\ncriterion = nn.BCEWithLogitsLoss()  # Binary Cross Entropy with Logits Loss for multi-label classification\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\nscheduler = StepLR(optimizer, step_size=2, gamma=0.5)","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:34:23.429655Z","iopub.execute_input":"2023-12-31T05:34:23.430316Z","iopub.status.idle":"2023-12-31T05:34:23.684277Z","shell.execute_reply.started":"2023-12-31T05:34:23.430284Z","shell.execute_reply":"2023-12-31T05:34:23.683324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Visualize the model archeticture**\nCOMMENT THE FOLLOWING CELLS IF NOT NEEDED","metadata":{}},{"cell_type":"code","source":"x = 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-31T05:28:01.631276Z","iopub.execute_input":"2023-12-31T05:28:01.632224Z","iopub.status.idle":"2023-12-31T05:28:06.620183Z","shell.execute_reply.started":"2023-12-31T05:28:01.632189Z","shell.execute_reply":"2023-12-31T05:28:06.619287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# another way to see model architecture\nmodel = model.to(\"cuda\")  # If your model is on GPU\nsummary(model, input_size=(3, 224, 224))","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:28:09.713259Z","iopub.execute_input":"2023-12-31T05:28:09.714001Z","iopub.status.idle":"2023-12-31T05:28:09.760125Z","shell.execute_reply.started":"2023-12-31T05:28:09.713968Z","shell.execute_reply":"2023-12-31T05:28:09.759231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Monitor GPU Performance**","metadata":{}},{"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-31T05:28:12.995784Z","iopub.execute_input":"2023-12-31T05:28:12.99666Z","iopub.status.idle":"2023-12-31T05:28:13.030052Z","shell.execute_reply.started":"2023-12-31T05:28:12.996627Z","shell.execute_reply":"2023-12-31T05:28:13.028338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"root_dir = \"/kaggle/input/all-rsna-jpg/ALL_RSNA_JPG\"\ncsv_file_train = '/kaggle/input/all-rsna-jpg/df_train_aug_rand.csv'\ncsv_file_valid = '/kaggle/input/all-rsna-jpg/df_valid_aug_rand.csv'\n\ndataloaders, dataset_sizes = get_loaders(csv_file_train = csv_file_train,\n                                         csv_file_valid = csv_file_valid,\n                                         root_dir = root_dir,\n                                         one_output = False,\n                                         transforms = data_transforms, \n                                         batch_size = batch_size, \n                                         num_workers = num_workers, \n                                         val_split = 0.2, \n                                         seed = 37)","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:28:15.040419Z","iopub.execute_input":"2023-12-31T05:28:15.040853Z","iopub.status.idle":"2023-12-31T05:28:16.759835Z","shell.execute_reply.started":"2023-12-31T05:28:15.040802Z","shell.execute_reply":"2023-12-31T05:28:16.758844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(1, epochs + 1):\n    \n    best_model_params_path = os.path.join('/kaggle/working', f'resnet152_{epoch}E.pt')\n    \n    print(f'Epoch {epoch}/{epochs}')\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}/{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}/{epochs}], Loss: {average_loss:.4f}\")\n        scheduler.step()\n\n        # Save the trained model every epoch\n        torch.save(model.state_dict(), best_model_params_path)","metadata":{"execution":{"iopub.status.busy":"2023-12-30T15:19:04.361428Z","iopub.execute_input":"2023-12-30T15:19:04.36225Z","iopub.status.idle":"2023-12-30T22:53:39.986939Z","shell.execute_reply.started":"2023-12-30T15:19:04.362213Z","shell.execute_reply":"2023-12-30T22:53:39.985835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Visualization of model results**","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\ndef run_model_on_samples(model , number_of_samples, validationDS , verbose = 1 , 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   )","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:32:02.493893Z","iopub.execute_input":"2023-12-31T05:32:02.494238Z","iopub.status.idle":"2023-12-31T05:32:02.518639Z","shell.execute_reply.started":"2023-12-31T05:32:02.49421Z","shell.execute_reply":"2023-12-31T05:32:02.517752Z"},"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 = 10 , images_per_row = 5, validationDS = dataloaders['val'].dataset)","metadata":{"execution":{"iopub.status.busy":"2023-12-31T05:46:24.699594Z","iopub.execute_input":"2023-12-31T05:46:24.699957Z","iopub.status.idle":"2023-12-31T05:46:26.366106Z","shell.execute_reply.started":"2023-12-31T05:46:24.69993Z","shell.execute_reply":"2023-12-31T05:46:26.365212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"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":{"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":[]}]}