{"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":"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":"2022-08-01T02:21:47.574492Z","iopub.execute_input":"2022-08-01T02:21:47.575712Z","iopub.status.idle":"2022-08-01T02:21:47.582387Z","shell.execute_reply.started":"2022-08-01T02:21:47.575666Z","shell.execute_reply":"2022-08-01T02:21:47.581163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = pd.read_csv(\"../input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:21:47.583800Z","iopub.execute_input":"2022-08-01T02:21:47.584520Z","iopub.status.idle":"2022-08-01T02:21:47.638661Z","shell.execute_reply.started":"2022-08-01T02:21:47.584483Z","shell.execute_reply":"2022-08-01T02:21:47.637378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels.head(6)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:21:47.642541Z","iopub.execute_input":"2022-08-01T02:21:47.643059Z","iopub.status.idle":"2022-08-01T02:21:47.673259Z","shell.execute_reply.started":"2022-08-01T02:21:47.643012Z","shell.execute_reply":"2022-08-01T02:21:47.672029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = labels.drop_duplicates(\"patientId\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:21:47.674977Z","iopub.execute_input":"2022-08-01T02:21:47.675822Z","iopub.status.idle":"2022-08-01T02:21:47.703773Z","shell.execute_reply.started":"2022-08-01T02:21:47.675776Z","shell.execute_reply":"2022-08-01T02:21:47.702675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROOT_PATH = Path(\"../input/rsna-pneumonia-detection-challenge/stage_2_train_images/\")\nSAVE_PATH = Path(\"Processed\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:21:47.704866Z","iopub.execute_input":"2022-08-01T02:21:47.705240Z","iopub.status.idle":"2022-08-01T02:21:47.711154Z","shell.execute_reply.started":"2022-08-01T02:21:47.705210Z","shell.execute_reply":"2022-08-01T02:21:47.709805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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        patient_id = labels.patientId.iloc[c]\n        dcm_path = ROOT_PATH/patient_id\n        dcm_path = dcm_path.with_suffix(\".dcm\")\n        dcm = pydicom.read_file(dcm_path).pixel_array\n        \n        label = labels[\"Target\"].iloc[c]\n        \n        axis[i][j].imshow(dcm, cmap=\"bone\")\n        axis[i][j].set_title(label)\n        c+=1","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:21:47.713625Z","iopub.execute_input":"2022-08-01T02:21:47.714362Z","iopub.status.idle":"2022-08-01T02:21:49.883774Z","shell.execute_reply.started":"2022-08-01T02:21:47.714314Z","shell.execute_reply":"2022-08-01T02:21:49.882792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sums = 0\nsums_squared = 0\n\nfor c, patient_id in enumerate(tqdm(labels.patientId)):\n    dcm_path = ROOT_PATH/patient_id  \n    dcm_path = dcm_path.with_suffix(\".dcm\")  \n    \n  \n    dcm = pydicom.read_file(dcm_path).pixel_array / 255  \n        \n \n    dcm_array = cv2.resize(dcm, (224, 224)).astype(np.float16)\n    \n    \n    label = labels.Target.iloc[c]\n    \n    \n    train_or_val = \"train\" if c < 24000 else \"val\" \n        \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    normalizer = dcm_array.shape[0] * dcm_array.shape[1]  \n    if train_or_val == \"train\": \n        sums += np.sum(dcm_array) / normalizer\n        sums_squared += (np.power(dcm_array, 2).sum()) / normalizer\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:21:49.884872Z","iopub.execute_input":"2022-08-01T02:21:49.885672Z","iopub.status.idle":"2022-08-01T02:32:29.146987Z","shell.execute_reply.started":"2022-08-01T02:21:49.885633Z","shell.execute_reply":"2022-08-01T02:32:29.145363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mean = sums / 24000\nstd = np.sqrt(sums_squared / 24000 - (mean**2))","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:29.149357Z","iopub.execute_input":"2022-08-01T02:32:29.153005Z","iopub.status.idle":"2022-08-01T02:32:29.159333Z","shell.execute_reply.started":"2022-08-01T02:32:29.152960Z","shell.execute_reply":"2022-08-01T02:32:29.158230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Mean of Dataset: {mean}, STD: {std}\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:29.163860Z","iopub.execute_input":"2022-08-01T02:32:29.164288Z","iopub.status.idle":"2022-08-01T02:32:29.173154Z","shell.execute_reply.started":"2022-08-01T02:32:29.164248Z","shell.execute_reply":"2022-08-01T02:32:29.171973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torchvision\nfrom torchvision import transforms\nimport torchmetrics\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom pytorch_lightning.loggers import TensorBoardLogger\nfrom tqdm.notebook import tqdm\nimport numpy as np\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:29.174786Z","iopub.execute_input":"2022-08-01T02:32:29.175096Z","iopub.status.idle":"2022-08-01T02:32:34.316476Z","shell.execute_reply.started":"2022-08-01T02:32:29.175069Z","shell.execute_reply":"2022-08-01T02:32:34.315051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_file(path):\n    return np.load(path).astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:34.318246Z","iopub.execute_input":"2022-08-01T02:32:34.319179Z","iopub.status.idle":"2022-08-01T02:32:34.325007Z","shell.execute_reply.started":"2022-08-01T02:32:34.319141Z","shell.execute_reply":"2022-08-01T02:32:34.323858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n                                    transforms.ToTensor(),  \n                                    transforms.Normalize(0.49, 0.248),  \n                                    transforms.RandomAffine( \n                                        degrees=(-5, 5), translate=(0, 0.05), scale=(0.9, 1.1)),\n                                        transforms.RandomResizedCrop((224, 224), scale=(0.35, 1))\n\n])\n\nval_transforms = transforms.Compose([\n                                    transforms.ToTensor(), \n                                    transforms.Normalize([0.49], [0.248]),  \n])\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:34.326243Z","iopub.execute_input":"2022-08-01T02:32:34.327336Z","iopub.status.idle":"2022-08-01T02:32:34.346635Z","shell.execute_reply.started":"2022-08-01T02:32:34.327292Z","shell.execute_reply":"2022-08-01T02:32:34.345432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = torchvision.datasets.DatasetFolder(\n    \"Processed/train/\",\n    loader=load_file, extensions=\"npy\", transform=train_transforms)\n\nval_dataset = torchvision.datasets.DatasetFolder(\n    \"Processed/val/\",\n    loader=load_file, extensions=\"npy\", transform=val_transforms)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:34.348518Z","iopub.execute_input":"2022-08-01T02:32:34.349408Z","iopub.status.idle":"2022-08-01T02:32:34.505819Z","shell.execute_reply.started":"2022-08-01T02:32:34.349359Z","shell.execute_reply":"2022-08-01T02:32:34.504769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axis = plt.subplots(2, 2, figsize=(9, 9))\nfor i in range(2):\n    for j in range(2):\n        random_index = np.random.randint(0, 20000)\n        x_ray, label = train_dataset[random_index]\n        axis[i][j].imshow(x_ray[0], cmap=\"bone\")\n        axis[i][j].set_title(f\"Label:{label}\")\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:34.507458Z","iopub.execute_input":"2022-08-01T02:32:34.507872Z","iopub.status.idle":"2022-08-01T02:32:35.503394Z","shell.execute_reply.started":"2022-08-01T02:32:34.507840Z","shell.execute_reply":"2022-08-01T02:32:35.502578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 64#TODO\nnum_workers = 4# TODO\n\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=True)\nval_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=False)\n\nprint(f\"There are {len(train_dataset)} train images and {len(val_dataset)} val images\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.504863Z","iopub.execute_input":"2022-08-01T02:32:35.505231Z","iopub.status.idle":"2022-08-01T02:32:35.512345Z","shell.execute_reply.started":"2022-08-01T02:32:35.505179Z","shell.execute_reply":"2022-08-01T02:32:35.511464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.unique(train_dataset.targets, return_counts=True), np.unique(val_dataset.targets, return_counts=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.513801Z","iopub.execute_input":"2022-08-01T02:32:35.514648Z","iopub.status.idle":"2022-08-01T02:32:35.535560Z","shell.execute_reply.started":"2022-08-01T02:32:35.514616Z","shell.execute_reply":"2022-08-01T02:32:35.533918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PneumoniaModel(pl.LightningModule):\n    def __init__(self, weight=1):\n        super().__init__()\n        \n        self.model = torchvision.models.resnet18()\n        # change conv1 from 3 to 1 input channels\n        self.model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n        # change out_feature of the last fully connected layer (called fc in resnet18) from 1000 to 1\n        self.model.fc = torch.nn.Linear(in_features=512, out_features=1)\n        \n        self.optimizer = torch.optim.Adam(self.model.parameters(), lr=1e-4)\n        self.loss_fn = torch.nn.BCEWithLogitsLoss(pos_weight=torch.tensor([weight]))\n        \n        # simple accuracy computation\n        self.train_acc = torchmetrics.Accuracy()\n        self.val_acc = torchmetrics.Accuracy()\n\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()  # Convert label to float (just needed for loss computation)\n        pred = self(x_ray)[:,0]  # Prediction: Make sure prediction and label have same shape\n        loss = self.loss_fn(pred, label)  # Compute the loss\n        \n        # Log loss and batch accuracy\n        self.log(\"Train Loss\", loss)\n        self.log(\"Step Train Acc\", self.train_acc(torch.sigmoid(pred), label.int()))\n        return loss\n    \n    \n    def training_epoch_end(self, outs):\n        # After one epoch compute the whole train_data accuracy\n        self.log(\"Train Acc\", self.train_acc.compute())\n        \n        \n    def validation_step(self, batch, batch_idx):\n        # Same steps as in the training_step\n        x_ray, label = batch\n        label = label.float()\n        pred = self(x_ray)[:,0]  # make sure prediction and label have same shape\n\n        loss = self.loss_fn(pred, label)\n        \n        # Log validation metrics\n        self.log(\"Val Loss\", loss)\n        self.log(\"Step Val Acc\", self.val_acc(torch.sigmoid(pred), label.int()))\n        return loss\n    \n    def validation_epoch_end(self, outs):\n        self.log(\"Val Acc\", self.val_acc.compute())\n    \n    def configure_optimizers(self):\n        #Caution! You always need to return a list here (just pack your optimizer into one :))\n        return [self.optimizer]\n\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.537728Z","iopub.execute_input":"2022-08-01T02:32:35.538617Z","iopub.status.idle":"2022-08-01T02:32:35.560230Z","shell.execute_reply.started":"2022-08-01T02:32:35.538570Z","shell.execute_reply":"2022-08-01T02:32:35.558591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = PneumoniaModel()  # Instanciate the model","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.561797Z","iopub.execute_input":"2022-08-01T02:32:35.562307Z","iopub.status.idle":"2022-08-01T02:32:35.852300Z","shell.execute_reply.started":"2022-08-01T02:32:35.562265Z","shell.execute_reply":"2022-08-01T02:32:35.851173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the checkpoint callback\ncheckpoint_callback = ModelCheckpoint(\n    monitor='Val Acc',\n    save_top_k=10,\n    mode='max')","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.853668Z","iopub.execute_input":"2022-08-01T02:32:35.853984Z","iopub.status.idle":"2022-08-01T02:32:35.859653Z","shell.execute_reply.started":"2022-08-01T02:32:35.853955Z","shell.execute_reply":"2022-08-01T02:32:35.858779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\ngpus = 0\ntrainer = pl.Trainer(gpus=gpus, logger=TensorBoardLogger(save_dir=\"./logs\"), log_every_n_steps=1,\n                     callbacks=checkpoint_callback,\n                     max_epochs=1)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.860842Z","iopub.execute_input":"2022-08-01T02:32:35.861834Z","iopub.status.idle":"2022-08-01T02:32:35.872923Z","shell.execute_reply.started":"2022-08-01T02:32:35.861801Z","shell.execute_reply":"2022-08-01T02:32:35.871708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(model, train_loader, val_loader)\n\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T02:32:35.874073Z","iopub.execute_input":"2022-08-01T02:32:35.874409Z","iopub.status.idle":"2022-08-01T03:33:58.826169Z","shell.execute_reply.started":"2022-08-01T02:32:35.874380Z","shell.execute_reply":"2022-08-01T03:33:58.824588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfor dirname, _, filenames in os.walk('/kaggle/working'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2022-08-01T03:55:46.116546Z","iopub.execute_input":"2022-08-01T03:55:46.117003Z","iopub.status.idle":"2022-08-01T03:55:46.463132Z","shell.execute_reply.started":"2022-08-01T03:55:46.116972Z","shell.execute_reply":"2022-08-01T03:55:46.461707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n\nmodel = PneumoniaModel.load_from_checkpoint(\"/kaggle/working/logs/lightning_logs/version_0/checkpoints/epoch=0-step=375.ckpt\")\nmodel.eval()\nmodel.to(device);","metadata":{"execution":{"iopub.status.busy":"2022-08-01T03:57:19.654360Z","iopub.execute_input":"2022-08-01T03:57:19.654891Z","iopub.status.idle":"2022-08-01T03:57:19.965376Z","shell.execute_reply.started":"2022-08-01T03:57:19.654853Z","shell.execute_reply":"2022-08-01T03:57:19.964041Z"},"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        pred = torch.sigmoid(model(data)[0].cpu())\n        preds.append(pred)\n        labels.append(label)\npreds = torch.tensor(preds)\nlabels = torch.tensor(labels).int()\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T03:57:30.544392Z","iopub.execute_input":"2022-08-01T03:57:30.545897Z","iopub.status.idle":"2022-08-01T03:59:41.117613Z","shell.execute_reply.started":"2022-08-01T03:57:30.545824Z","shell.execute_reply":"2022-08-01T03:59:41.116515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = torchmetrics.Accuracy()(preds, labels)\nprecision = torchmetrics.Precision()(preds, labels)\nrecall = torchmetrics.Recall()(preds, labels)\ncm = torchmetrics.ConfusionMatrix(num_classes=2)(preds, labels)\ncm_threshed = torchmetrics.ConfusionMatrix(num_classes=2, threshold=0.25)(preds, labels)\n\nprint(f\"Val Accuracy: {acc}\")\nprint(f\"Val Precision: {precision}\")\nprint(f\"Val Recall: {recall}\")\nprint(f\"Confusion Matrix:\\n {cm}\")\nprint(f\"Confusion Matrix 2:\\n {cm_threshed}\")","metadata":{"execution":{"iopub.status.busy":"2022-08-01T04:00:30.052351Z","iopub.execute_input":"2022-08-01T04:00:30.053075Z","iopub.status.idle":"2022-08-01T04:00:30.087931Z","shell.execute_reply.started":"2022-08-01T04:00:30.053014Z","shell.execute_reply":"2022-08-01T04:00:30.086495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axis = plt.subplots(3, 3, figsize=(9, 9))\n\nfor i in range(3):\n    for j in range(3):\n        rnd_idx = np.random.randint(0, len(preds))\n        axis[i][j].imshow(val_dataset[rnd_idx][0][0], cmap=\"bone\")\n        axis[i][j].set_title(f\"Pred:{int(preds[rnd_idx] > 0.5)}, Label:{labels[rnd_idx]}\")\n        axis[i][j].axis(\"off\")\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T04:00:42.148532Z","iopub.execute_input":"2022-08-01T04:00:42.149014Z","iopub.status.idle":"2022-08-01T04:00:42.788283Z","shell.execute_reply.started":"2022-08-01T04:00:42.148977Z","shell.execute_reply":"2022-08-01T04:00:42.786996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%matplotlib notebook\nimport torch\nimport torchvision\nfrom torchvision import transforms\nimport pytorch_lightning as pl\nimport numpy as np\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-08-01T04:05:42.960206Z","iopub.execute_input":"2022-08-01T04:05:42.961861Z","iopub.status.idle":"2022-08-01T04:05:42.987928Z","shell.execute_reply.started":"2022-08-01T04:05:42.961810Z","shell.execute_reply":"2022-08-01T04:05:42.986481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_file(path):\n    return np.load(path).astype(np.float32)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-01T04:05:44.229537Z","iopub.execute_input":"2022-08-01T04:05:44.231010Z","iopub.status.idle":"2022-08-01T04:05:44.236947Z","shell.execute_reply.started":"2022-08-01T04:05:44.230947Z","shell.execute_reply":"2022-08-01T04:05:44.235502Z"},"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\n])\n\nval_dataset = torchvision.datasets.DatasetFolder(\"Processed/val/\", loader=load_file, extensions=\"npy\", transform=val_transforms)","metadata":{"execution":{"iopub.status.busy":"2022-08-01T04:05:48.809264Z","iopub.execute_input":"2022-08-01T04:05:48.809722Z","iopub.status.idle":"2022-08-01T04:05:48.831452Z","shell.execute_reply.started":"2022-08-01T04:05:48.809686Z","shell.execute_reply":"2022-08-01T04:05:48.830492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"temp_model = torchvision.models.resnet18()\ntemp_model","metadata":{"execution":{"iopub.status.busy":"2022-08-01T04:05:52.412769Z","iopub.execute_input":"2022-08-01T04:05:52.413211Z","iopub.status.idle":"2022-08-01T04:05:52.607049Z","shell.execute_reply.started":"2022-08-01T04:05:52.413160Z","shell.execute_reply":"2022-08-01T04:05:52.605503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}