{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Import Necessary libraries","metadata":{}},{"cell_type":"code","source":"from pathlib import Path\nimport pydicom\nimport numpy as np\nimport cv2\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:28:39.473303Z","iopub.execute_input":"2023-05-07T13:28:39.473657Z","iopub.status.idle":"2023-05-07T13:28:39.850466Z","shell.execute_reply.started":"2023-05-07T13:28:39.473627Z","shell.execute_reply":"2023-05-07T13:28:39.849462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install torchvision","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:28:39.852600Z","iopub.execute_input":"2023-05-07T13:28:39.853370Z","iopub.status.idle":"2023-05-07T13:28:50.031438Z","shell.execute_reply.started":"2023-05-07T13:28:39.853339Z","shell.execute_reply":"2023-05-07T13:28:50.030554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install torch torchvision torchaudio torchmetrics\n","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:28:50.032704Z","iopub.execute_input":"2023-05-07T13:28:50.033065Z","iopub.status.idle":"2023-05-07T13:28:58.828859Z","shell.execute_reply.started":"2023-05-07T13:28:50.033028Z","shell.execute_reply":"2023-05-07T13:28:58.827626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install numpy==1.22.0","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:28:58.830288Z","iopub.execute_input":"2023-05-07T13:28:58.830576Z","iopub.status.idle":"2023-05-07T13:29:12.223942Z","shell.execute_reply.started":"2023-05-07T13:28:58.830549Z","shell.execute_reply":"2023-05-07T13:29:12.222444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision import transforms","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:12.227257Z","iopub.execute_input":"2023-05-07T13:29:12.227591Z","iopub.status.idle":"2023-05-07T13:29:15.541495Z","shell.execute_reply.started":"2023-05-07T13:29:12.227558Z","shell.execute_reply":"2023-05-07T13:29:15.540174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torchvision\nimport torchmetrics\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom pytorch_lightning.loggers import TensorBoardLogger","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:15.542924Z","iopub.execute_input":"2023-05-07T13:29:15.543623Z","iopub.status.idle":"2023-05-07T13:29:27.348815Z","shell.execute_reply.started":"2023-05-07T13:29:15.543590Z","shell.execute_reply":"2023-05-07T13:29:27.347656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Read the labels dataframe.","metadata":{}},{"cell_type":"code","source":"labels = pd.read_csv('/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-07T13:29:27.351459Z","iopub.execute_input":"2023-05-07T13:29:27.351865Z","iopub.status.idle":"2023-05-07T13:29:27.418161Z","shell.execute_reply.started":"2023-05-07T13:29:27.351832Z","shell.execute_reply":"2023-05-07T13:29:27.417494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:27.419060Z","iopub.execute_input":"2023-05-07T13:29:27.419530Z","iopub.status.idle":"2023-05-07T13:29:27.444880Z","shell.execute_reply.started":"2023-05-07T13:29:27.419503Z","shell.execute_reply":"2023-05-07T13:29:27.444249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"While looking at labels, we can see that there is a **patientid** column at first which is a unique patient id.\n\nColumns`x,y, left, right` represents the `x` and `y` coordinates and the `left` and `right` position of the classified pneumonia region.\n\nThe final column `Target` is used to denote whether patient is suffering from pneumonia or not.","metadata":{}},{"cell_type":"code","source":"# Dropping Duplicates\n\nlabels = labels.drop_duplicates(\"patientId\")","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:27.445701Z","iopub.execute_input":"2023-05-07T13:29:27.446712Z","iopub.status.idle":"2023-05-07T13:29:27.458289Z","shell.execute_reply.started":"2023-05-07T13:29:27.446689Z","shell.execute_reply":"2023-05-07T13:29:27.457702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's create a `ROOT_PATH` that takes a path to our train dataset.\n\nAdditionally, let's define a `SAVE_PATH` that defines path to the place where our processed images are saved.","metadata":{}},{"cell_type":"code","source":"ROOT_PATH = Path(\"/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_train_images/\")\nSAVE_PATH = Path(\"Processed\")","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:27.459382Z","iopub.execute_input":"2023-05-07T13:29:27.459643Z","iopub.status.idle":"2023-05-07T13:29:27.468378Z","shell.execute_reply.started":"2023-05-07T13:29:27.459622Z","shell.execute_reply":"2023-05-07T13:29:27.466723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's look at some example images.\n\nLet's create 3x3 subplots to view 9 images along with their labels.","metadata":{}},{"cell_type":"code","source":"fig, axis = plt.subplots(3, 3, figsize = (9, 9))\nc = 0\nfor i in range(3):\n    for j in range(3):\n        # Start reading the files.\n        patient_id = labels.patientId.iloc[c]\n        \n        # Create a path to the dicom file of this particular patient/\n        dcm_path = ROOT_PATH/patient_id\n        \n        # Add .dcm extension\n        dcm_path = dcm_path.with_suffix(\".dcm\")\n        \n        # Reading the dicom file\n        dcm = pydicom.read_file(dcm_path).pixel_array\n        \n        # Extract the labels of the particular patient from labels dataframe\n        label = labels['Target'].iloc[c]\n        \n        # Visualize the image\n        axis[i][j].imshow(dcm, cmap = \"bone\")\n        axis[i][j].set_title(label)\n        \n        c += 1\n        \n         \n        ","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:27.469886Z","iopub.execute_input":"2023-05-07T13:29:27.470204Z","iopub.status.idle":"2023-05-07T13:29:29.337362Z","shell.execute_reply.started":"2023-05-07T13:29:27.470180Z","shell.execute_reply":"2023-05-07T13:29:29.335960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"###  Preprocessing Images","metadata":{}},{"cell_type":"markdown","source":"First, we standardize each image pixels by dividing it by 255.\n\nAlso, our images are way too large for current neural network architectures to process. So, we need to resize them to shape of 224x224.\n\nTo use less space when storing the images, we convert them to `float16`","metadata":{}},{"cell_type":"code","source":"# Initialization \nsums, sums_squared = 0, 0\n\n# Loop over all patient ids\n# To decide if a data is used as training data or validation data\n# We can use the enumerate \n\nfor c, patient_id, in enumerate(tqdm(labels.patientId)):\n    # Start reading the files.\n    patient_id = labels.patientId.iloc[c]\n        \n    # Create a path to the dicom file of this particular patient/\n    dcm_path = ROOT_PATH/patient_id\n\n    # Add .dcm extension\n    dcm_path = dcm_path.with_suffix(\".dcm\")\n\n    # Reading the dicom file and dividing the pixel array by 255\n    dcm = pydicom.read_file(dcm_path).pixel_array\n    \n    # Resizing the image and converting it's type\n    dcm_array = cv2.resize(dcm, (224, 224)).astype(np.float16)\n    \n    # Storing the label in 'label'\n    label = labels.Target.iloc[c]\n    \n    # Identify training/validation\n    train_or_val = \"train\" if c < 24000 else \"val\"\n    \n    # Save preprocessed images\n    current_save_path = SAVE_PATH/train_or_val/str(label)\n    current_save_path.mkdir(parents = True, exist_ok = True)\n    np.save(current_save_path/patient_id, dcm_array)\n    \n    \n    # Update sums and sums_squared\n    normalizer = 224*224\n    ","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:29:29.339341Z","iopub.execute_input":"2023-05-07T13:29:29.339763Z","iopub.status.idle":"2023-05-07T13:35:14.718004Z","shell.execute_reply.started":"2023-05-07T13:29:29.339727Z","shell.execute_reply":"2023-05-07T13:35:14.716492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mean = 0.49\nstd = 0.24","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:14.720602Z","iopub.execute_input":"2023-05-07T13:35:14.720995Z","iopub.status.idle":"2023-05-07T13:35:14.726628Z","shell.execute_reply.started":"2023-05-07T13:35:14.720957Z","shell.execute_reply":"2023-05-07T13:35:14.725623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train and Validation Dataset","metadata":{}},{"cell_type":"markdown","source":"To load the generate the data in required format, we can make use of dataset class.","metadata":{}},{"cell_type":"code","source":"def load_file(path):\n    return np.load(path).astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:14.733419Z","iopub.execute_input":"2023-05-07T13:35:14.733706Z","iopub.status.idle":"2023-05-07T13:35:14.741930Z","shell.execute_reply.started":"2023-05-07T13:35:14.733677Z","shell.execute_reply":"2023-05-07T13:35:14.740834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next, we can define our train and validation transform:","metadata":{}},{"cell_type":"code","source":"# Transforms\n\ntrain_transforms = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(mean, std),\n    transforms.RandomAffine(degrees = (-5, 5), translate = (0, 0.05), scale = (0.9, 1.1)),\n    transforms.RandomResizedCrop((224, 224), scale = (0.35, 1))\n])\n\nval_transforms = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(mean, std)\n])","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:14.743270Z","iopub.execute_input":"2023-05-07T13:35:14.746198Z","iopub.status.idle":"2023-05-07T13:35:14.758313Z","shell.execute_reply.started":"2023-05-07T13:35:14.746155Z","shell.execute_reply":"2023-05-07T13:35:14.757017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# DataLoader\n\ntrain_dataset = torchvision.datasets.DatasetFolder(\"/kaggle/working/Processed/train/\", loader = load_file, extensions = \"npy\", transform = train_transforms)\n\nval_dataset = torchvision.datasets.DatasetFolder(\"/kaggle/working/Processed/val/\", loader = load_file, extensions = \"npy\", transform = val_transforms)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:14.759733Z","iopub.execute_input":"2023-05-07T13:35:14.760061Z","iopub.status.idle":"2023-05-07T13:35:14.856853Z","shell.execute_reply.started":"2023-05-07T13:35:14.760032Z","shell.execute_reply":"2023-05-07T13:35:14.855714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axis = plt.subplots(2, 2, figsize=(9, 9))\n\nfor i in range(2):\n    for j in range(2):\n        random_index = np.random.randint(0, 24000)\n        x_ray, label = train_dataset[random_index]\n        axis[i][j].imshow(x_ray[0], cmap = \"bone\")\n        axis[i][j].set_title(label)\n","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:14.858362Z","iopub.execute_input":"2023-05-07T13:35:14.859028Z","iopub.status.idle":"2023-05-07T13:35:15.926408Z","shell.execute_reply.started":"2023-05-07T13:35:14.858991Z","shell.execute_reply":"2023-05-07T13:35:15.925778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 64\nnum_workers = 4","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:15.927322Z","iopub.execute_input":"2023-05-07T13:35:15.929119Z","iopub.status.idle":"2023-05-07T13:35:15.933922Z","shell.execute_reply.started":"2023-05-07T13:35:15.929057Z","shell.execute_reply":"2023-05-07T13:35:15.932921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import DataLoader","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:15.935966Z","iopub.execute_input":"2023-05-07T13:35:15.937303Z","iopub.status.idle":"2023-05-07T13:35:15.948074Z","shell.execute_reply.started":"2023-05-07T13:35:15.937246Z","shell.execute_reply":"2023-05-07T13:35:15.946260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size = batch_size, num_workers = num_workers, shuffle = True)\nval_loader = DataLoader(val_dataset, batch_size = batch_size, num_workers = num_workers, shuffle = False)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:15.950336Z","iopub.execute_input":"2023-05-07T13:35:15.950784Z","iopub.status.idle":"2023-05-07T13:35:15.963068Z","shell.execute_reply.started":"2023-05-07T13:35:15.950746Z","shell.execute_reply":"2023-05-07T13:35:15.961635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.unique(train_dataset.targets, return_counts = True)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:15.964736Z","iopub.execute_input":"2023-05-07T13:35:15.965051Z","iopub.status.idle":"2023-05-07T13:35:15.980979Z","shell.execute_reply.started":"2023-05-07T13:35:15.965023Z","shell.execute_reply":"2023-05-07T13:35:15.979897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Our dataset is heavily imbalanced. So, we will be doing weighted loss.","metadata":{}},{"cell_type":"code","source":"# Observing the Resnet18 architecture\n\ntorchvision.models.resnet18()","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:15.982506Z","iopub.execute_input":"2023-05-07T13:35:15.982868Z","iopub.status.idle":"2023-05-07T13:35:16.214949Z","shell.execute_reply.started":"2023-05-07T13:35:15.982836Z","shell.execute_reply":"2023-05-07T13:35:16.213734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PneumoniaModel(pl.LightningModule):\n    \n    # Constructor\n    def __init__(self):\n        super(PneumoniaModel, self).__init__()\n        self.model = torchvision.models.resnet18()\n        self.model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n        self.model.fc = torch.nn.Linear(in_features = 512, out_features = 1, bias = True)\n        \n        self.optimizer = torch.optim.Adam(self.model.parameters(), lr = 1e-4)\n        self.loss_fn = torch.nn.BCEWithLogitsLoss(pos_weight = torch.tensor([3]))\n        \n        self.train_acc = torchmetrics.Accuracy(task = \"binary\")\n        self.val_acc = torchmetrics.Accuracy(task = \"binary\")\n        #self.test_acc = torchmetrics.Accuracy()\n        \n        \n        \n    # Activation\n    def forward(self, data):\n        pred = self.model(data)\n        return pred\n    \n    def training_step(self, batch, batch_idx):\n        x_ray, label = batch\n        label = label.float()\n        pred = self(x_ray)[:, 0]\n        loss = self.loss_fn(pred, label)\n        \n        self.log(\"Train Loss\", loss)\n        self.log(\"Step Train ACC\", self.train_acc(torch.sigmoid(pred), label.int()))\n        \n        return loss\n    \n    \n    \n    def on_train_epoch_end(self):\n        self.log(\"Train ACC\", self.train_acc.compute())\n        \n    \n    def validation_step(self, batch, batch_idx):\n        x_ray, label = batch\n        label = label.float()\n        pred = self(x_ray)[:, 0]\n        loss = self.loss_fn(pred, label)\n        \n        self.log(\"Val Loss\", loss)\n        self.log(\"Step Val ACC\", self.val_acc(torch.sigmoid(pred), label.int()))\n\n        \n        \n       \n    def on_validation_epoch_end(self):\n        self.log(\"Val ACC\", self.val_acc.compute())\n        \n        \n    def configure_optimizers(self):\n        return[self.optimizer]\n    ","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:16.216768Z","iopub.execute_input":"2023-05-07T13:35:16.217034Z","iopub.status.idle":"2023-05-07T13:35:16.229566Z","shell.execute_reply.started":"2023-05-07T13:35:16.217011Z","shell.execute_reply":"2023-05-07T13:35:16.227599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = PneumoniaModel()","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:16.231686Z","iopub.execute_input":"2023-05-07T13:35:16.232047Z","iopub.status.idle":"2023-05-07T13:35:16.468338Z","shell.execute_reply.started":"2023-05-07T13:35:16.232016Z","shell.execute_reply":"2023-05-07T13:35:16.467292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_callback = ModelCheckpoint(\n    monitor = \"Val ACC\",\n    save_top_k = 1,\n    mode = \"max\",\n    dirpath = \"./saved_models\"\n)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:16.469525Z","iopub.execute_input":"2023-05-07T13:35:16.470316Z","iopub.status.idle":"2023-05-07T13:35:16.478319Z","shell.execute_reply.started":"2023-05-07T13:35:16.470285Z","shell.execute_reply":"2023-05-07T13:35:16.477046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Configure the trainer\ntrainer = pl.Trainer(logger = TensorBoardLogger(save_dir = \"./logs\"), log_every_n_steps = 64, callbacks = checkpoint_callback, max_epochs = 1)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:16.479875Z","iopub.execute_input":"2023-05-07T13:35:16.480197Z","iopub.status.idle":"2023-05-07T13:35:17.429368Z","shell.execute_reply.started":"2023-05-07T13:35:16.480160Z","shell.execute_reply":"2023-05-07T13:35:17.428244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\ntrainer.fit(model, train_loader, val_loader)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T13:35:17.430531Z","iopub.execute_input":"2023-05-07T13:35:17.431437Z","iopub.status.idle":"2023-05-07T14:16:27.371646Z","shell.execute_reply.started":"2023-05-07T13:35:17.431405Z","shell.execute_reply":"2023-05-07T14:16:27.370392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check if GPU is available\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.373645Z","iopub.execute_input":"2023-05-07T14:16:27.373945Z","iopub.status.idle":"2023-05-07T14:16:27.380198Z","shell.execute_reply.started":"2023-05-07T14:16:27.373913Z","shell.execute_reply":"2023-05-07T14:16:27.378527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = PneumoniaModel.load_from_checkpoint(\"/kaggle/working/saved_models/epoch=0-step=375.ckpt\")","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:19:16.278147Z","iopub.execute_input":"2023-05-07T14:19:16.278556Z","iopub.status.idle":"2023-05-07T14:19:16.515919Z","shell.execute_reply.started":"2023-05-07T14:19:16.278525Z","shell.execute_reply":"2023-05-07T14:19:16.514371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:19:17.130887Z","iopub.execute_input":"2023-05-07T14:19:17.131212Z","iopub.status.idle":"2023-05-07T14:19:17.140296Z","shell.execute_reply.started":"2023-05-07T14:19:17.131182Z","shell.execute_reply":"2023-05-07T14:19:17.139010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.to(device)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:19:19.272043Z","iopub.execute_input":"2023-05-07T14:19:19.272431Z","iopub.status.idle":"2023-05-07T14:19:19.287695Z","shell.execute_reply.started":"2023-05-07T14:19:19.272405Z","shell.execute_reply":"2023-05-07T14:19:19.286124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = []\nlabels = []\n\nwith torch.no_grad():\n    for data, label in tqdm(val_dataset):\n        data = data.to(device).float().unsqueeze(0)\n        \n        # Calculate probabilities\n        pred = torch.sigmoid(model(data)[0].cpu())\n        \n        preds.append(pred)\n        labels.append(label)\npreds = torch.tensor(preds)\nlabels = torch.tensor(labels).int()","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:19:21.973296Z","iopub.execute_input":"2023-05-07T14:19:21.973740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Accuracy\nacc = torchmetrics.Accuracy(task = \"binary\")(preds, labels)\n\n# Precision\nprecision = torchmetrics.Precision(task = \"binary\")(preds, labels)\n\n# Recall\nrecall = torchmetrics.Recall(task = \"binary\")(preds, labels)\n\n# Confusion Matrix\ncm = torchmetrics.ConfusionMatrix(num_classes=2, task = \"binary\")(preds, labels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Accuracy : {acc}\")\nprint(f\"Precision : {precision}\")\nprint(f\"Recall : {recall}\")","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.931400Z","iopub.status.idle":"2023-05-07T14:16:27.931903Z","shell.execute_reply.started":"2023-05-07T14:16:27.931683Z","shell.execute_reply":"2023-05-07T14:16:27.931705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Class Activation Map\nLearning deep features for discriminative localization.","metadata":{}},{"cell_type":"code","source":"def load_file(path):\n    return np.load(path).astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.933018Z","iopub.status.idle":"2023-05-07T14:16:27.933459Z","shell.execute_reply.started":"2023-05-07T14:16:27.933247Z","shell.execute_reply":"2023-05-07T14:16:27.933267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_transforms = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(0.49, 0.248)\n])","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.935158Z","iopub.status.idle":"2023-05-07T14:16:27.935639Z","shell.execute_reply.started":"2023-05-07T14:16:27.935386Z","shell.execute_reply":"2023-05-07T14:16:27.935407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_dataset = torchvision.datasets.DatasteFolder(\"Processes/val\", loader = load_file, extensions = 'npy', transform = val_transform)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.937440Z","iopub.status.idle":"2023-05-07T14:16:27.937929Z","shell.execute_reply.started":"2023-05-07T14:16:27.937702Z","shell.execute_reply":"2023-05-07T14:16:27.937723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"temp_model = torchvision.models.resnet18()","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.939180Z","iopub.status.idle":"2023-05-07T14:16:27.939656Z","shell.execute_reply.started":"2023-05-07T14:16:27.939407Z","shell.execute_reply":"2023-05-07T14:16:27.939427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list(temp_model.children())","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.942066Z","iopub.status.idle":"2023-05-07T14:16:27.942576Z","shell.execute_reply.started":"2023-05-07T14:16:27.942313Z","shell.execute_reply":"2023-05-07T14:16:27.942336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list(temp_model.children())[:-2]","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.944361Z","iopub.status.idle":"2023-05-07T14:16:27.944884Z","shell.execute_reply.started":"2023-05-07T14:16:27.944653Z","shell.execute_reply":"2023-05-07T14:16:27.944675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.nn.sequential(*list(temp_model.children())[:-2])","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.945837Z","iopub.status.idle":"2023-05-07T14:16:27.946326Z","shell.execute_reply.started":"2023-05-07T14:16:27.946105Z","shell.execute_reply":"2023-05-07T14:16:27.946129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"class PneumoniaModel(pl.LightningMod\n    \n    \n        ","metadata":{}},{"cell_type":"code","source":"class PneumoniaModel(pl.LightningModule):\n    \n    def __init__(self):\n        super(PneumoniaModel, self).__init__()\n        self.model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7, 7), stride = (2, 2), padding = (3, 3), bias = False)\n        self.model.fc = torch.nn.Linear(in_)features=512, out_features=1)\n        \n        self.feature_map = torch.nn.Sequential(*list(temp_model.children())[:-2])\n        \n        \n    def forward(self, data):\n        feature_map = self.feature_map(data)\n        avg_pool_output = torch.nn.functional.adaptive_avg_pool2d(input=feature_map, output_size = (1, 1))\n        ave_output_flattened = torch.flatten(avg_pool_output)\n        pred = self.model.fc(avg_pool_flattened)\n        return pred, feature_map","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.947987Z","iopub.status.idle":"2023-05-07T14:16:27.948409Z","shell.execute_reply.started":"2023-05-07T14:16:27.948207Z","shell.execute_reply":"2023-05-07T14:16:27.948226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = PneumoniaModel.load_from_checkpoint(\"weights/weig.....0\", strict = False)\nmodel.eval():","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.950017Z","iopub.status.idle":"2023-05-07T14:16:27.950495Z","shell.execute_reply.started":"2023-05-07T14:16:27.950252Z","shell.execute_reply":"2023-05-07T14:16:27.950272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cam(model, img):\n    with torch.no_grad():\n        pred, features = model(img.unsqueeze(0))\n    features = features.reshape((512, 49))\n    weight_params = list(model.model.fc.parameters())[0]\n    weight = weight_params[0].detach()\n    \n    cam = torch.matmul(weight, features)\n    cam_img = cam.reshape(7, 7).cpu()\n    return cam_img, torch.sigmoid(pred)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.952297Z","iopub.status.idle":"2023-05-07T14:16:27.952772Z","shell.execute_reply.started":"2023-05-07T14:16:27.952548Z","shell.execute_reply":"2023-05-07T14:16:27.952569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize(img, cam, pred):\n    img = img[0]\n    cam = transforms.functional.resize(cam.unsqueeze(0), (224, 224))[0]\n    \n    fig, axis = plt.subplots(1, 2)\n    axis[0].imshow(img, cmap = 'bone')\n    axis[1].imshow(img, cmap= 'bone')\n    axis[1].imshow(cam, alpha=0.5, cmap=\"jet\")\n    plt.title(pred>0.5)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.954413Z","iopub.status.idle":"2023-05-07T14:16:27.954893Z","shell.execute_reply.started":"2023-05-07T14:16:27.954669Z","shell.execute_reply":"2023-05-07T14:16:27.954689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = val_dataset[-6][0]\nactivation_map, pred = cam(model, img)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.956649Z","iopub.status.idle":"2023-05-07T14:16:27.957144Z","shell.execute_reply.started":"2023-05-07T14:16:27.956922Z","shell.execute_reply":"2023-05-07T14:16:27.956943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize(img, activation_map, pred)","metadata":{"execution":{"iopub.status.busy":"2023-05-07T14:16:27.958400Z","iopub.status.idle":"2023-05-07T14:16:27.958846Z","shell.execute_reply.started":"2023-05-07T14:16:27.958675Z","shell.execute_reply":"2023-05-07T14:16:27.958692Z"},"trusted":true},"execution_count":null,"outputs":[]}]}