{"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":"# %%capture\n# ! pip install timm\n# ! pip install einops\n# ! pip install --upgrade wandb\n# ! pip install --upgrade torchmetrics\n# ! pip install --upgrade pytorch-lightning","metadata":{"execution":{"iopub.status.busy":"2023-02-04T14:09:51.005899Z","iopub.execute_input":"2023-02-04T14:09:51.006372Z","iopub.status.idle":"2023-02-04T14:10:59.22427Z","shell.execute_reply.started":"2023-02-04T14:09:51.006336Z","shell.execute_reply":"2023-02-04T14:10:59.222755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport pydicom\nimport glob\nfrom pathlib import Path\n\nimport os, sys\nimport cv2\nimport seaborn as sns\nfrom sklearn.model_selection import train_test_split\n\nfrom tqdm.auto import tqdm\n\nimport wandb\n\nimport torch\nfrom torch import nn\nimport torchvision\nfrom torch.utils.data import Dataset,DataLoader\nimport cv2\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nimport torchvision.transforms as transforms\n","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:47:57.879319Z","iopub.execute_input":"2023-02-04T16:47:57.879692Z","iopub.status.idle":"2023-02-04T16:48:01.548341Z","shell.execute_reply.started":"2023-02-04T16:47:57.879663Z","shell.execute_reply":"2023-02-04T16:48:01.547298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Section 1: Data","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/rsna-breast-cancer-detection/train.csv\")\n\nimage_path  = Path('/kaggle/input/rsna-breast-cancer-256-pngs')\n\npath = []\nfor i in tqdm(range(len(df))):\n    row = df.iloc[i, :]\n    filename = str(row.patient_id) + \"_\" + str(row.image_id) + \".png\"\n    path.append(image_path /  filename )\ndf[\"path\"] = path\n","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:04.494072Z","iopub.execute_input":"2023-02-04T16:48:04.494949Z","iopub.status.idle":"2023-02-04T16:48:16.778019Z","shell.execute_reply.started":"2023-02-04T16:48:04.494904Z","shell.execute_reply":"2023-02-04T16:48:16.776849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:21.714225Z","iopub.execute_input":"2023-02-04T16:48:21.715269Z","iopub.status.idle":"2023-02-04T16:48:21.737164Z","shell.execute_reply.started":"2023-02-04T16:48:21.71523Z","shell.execute_reply":"2023-02-04T16:48:21.736188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# let's view the first two training instances\nfor i in range(5):\n    img_read = cv2.imread(str(df[\"path\"][i]), cv2.IMREAD_UNCHANGED)\n    plt.imshow(img_read)\n    plt.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:30.102036Z","iopub.execute_input":"2023-02-04T16:48:30.102794Z","iopub.status.idle":"2023-02-04T16:48:31.28491Z","shell.execute_reply.started":"2023-02-04T16:48:30.10276Z","shell.execute_reply":"2023-02-04T16:48:31.2838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_read.shape","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:33.613499Z","iopub.execute_input":"2023-02-04T16:48:33.613869Z","iopub.status.idle":"2023-02-04T16:48:33.620571Z","shell.execute_reply.started":"2023-02-04T16:48:33.613837Z","shell.execute_reply":"2023-02-04T16:48:33.61942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.catplot(data = df, x = \"cancer\", y = \"age\", order = [0,1])\n\nsns.catplot(data = df, y = \"cancer\", kind = \"count\", \n           palette = \"pastel\")\n\nprint(df.cancer.value_counts())","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:34.292421Z","iopub.execute_input":"2023-02-04T16:48:34.292781Z","iopub.status.idle":"2023-02-04T16:48:35.477114Z","shell.execute_reply.started":"2023-02-04T16:48:34.292751Z","shell.execute_reply":"2023-02-04T16:48:35.476267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Logging using WandB","metadata":{}},{"cell_type":"code","source":"# Config = {}","metadata":{"execution":{"iopub.status.busy":"2023-01-13T18:18:43.871187Z","iopub.execute_input":"2023-01-13T18:18:43.871627Z","iopub.status.idle":"2023-01-13T18:18:43.87718Z","shell.execute_reply.started":"2023-01-13T18:18:43.871585Z","shell.execute_reply":"2023-01-13T18:18:43.8759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from kaggle_secrets import UserSecretsClient\n# user_secrets = UserSecretsClient()\n# wb_key = user_secrets.get_secret(\"wandb\")\n\n# wandb.login(key=wb_key)\n\n# run = wandb.init(\n#     project='pytorch_lightning',\n#     config=Config,\n#     group='GIKI',\n#     job_type='train',\n# )","metadata":{"execution":{"iopub.status.busy":"2023-01-13T18:18:43.878504Z","iopub.execute_input":"2023-01-13T18:18:43.878948Z","iopub.status.idle":"2023-01-13T18:18:43.892799Z","shell.execute_reply.started":"2023-01-13T18:18:43.878913Z","shell.execute_reply":"2023-01-13T18:18:43.891602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"# Section 2: Modelling ","metadata":{}},{"cell_type":"markdown","source":"## Loss Function","metadata":{}},{"cell_type":"code","source":"def probabilistic_f1(labels, preds, beta=1):\n    \"\"\"\n    Function taken from Awsaf's notebook:\n    https://www.kaggle.com/code/awsaf49/rsna-bcd-efficientnet-tf-tpu-1vm-train\n    \"\"\"\n    eps = 1e-5\n    preds = preds.clip(0, 1)\n    y_true_count = labels.sum()\n    ctp = preds[labels==1].sum()\n    cfp = preds[labels==0].sum()\n    beta_squared = beta * beta\n    c_precision = ctp / (ctp + cfp + eps)\n    c_recall = ctp / (y_true_count + eps)\n    if (c_precision > 0 and c_recall > 0):\n        result = (1 + beta_squared) * (c_precision * c_recall) / (beta_squared * c_precision + c_recall + eps)\n        return result\n    else:\n        return 0.0","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:44.601686Z","iopub.execute_input":"2023-02-04T16:48:44.602032Z","iopub.status.idle":"2023-02-04T16:48:44.609784Z","shell.execute_reply.started":"2023-02-04T16:48:44.602001Z","shell.execute_reply":"2023-02-04T16:48:44.608417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Splitting up Data","metadata":{}},{"cell_type":"code","source":"X = df[\"path\"].astype(str)\ny = df[\"cancer\"]\n\ndef split(X,y,stage):\n\n    x_train, x_test, y_train, y_test = train_test_split(X,y, \n                                                        test_size = 0.25,\n                                                       random_state = 42, \n                                                       stratify = y)\n\n    x_val, x_test, y_val, y_test = train_test_split(x_test, y_test, \n                                                    test_size = 0.25, random_state = 42,\n                                                   stratify = y_test)\n\n    if stage in \"train\":\n        return(x_train.reset_index(drop = True), y_train.reset_index(drop = True))\n    if stage in \"test\":\n        return(x_test.reset_index(drop = True), y_test.reset_index(drop = True))\n    if stage in \"val\":\n        return(x_val.reset_index(drop = True), y_val.reset_index(drop = True))\n    if stage in \"predict\":\n        return(x_test.reset_index(drop = True))\n\n\n","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:48:46.360059Z","iopub.execute_input":"2023-02-04T16:48:46.3608Z","iopub.status.idle":"2023-02-04T16:48:46.498137Z","shell.execute_reply.started":"2023-02-04T16:48:46.360756Z","shell.execute_reply":"2023-02-04T16:48:46.496979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Creating pytorch dataset","metadata":{}},{"cell_type":"code","source":"class CancerDataset(torch.utils.data.Dataset):\n    def __init__(self, image, targets, stage):\n        \n        if stage == \"train\":\n            image, targets = split(image, targets, \"train\")\n            self.image  = image\n            self.targets = targets\n        elif stage == \"test\":\n            image, targets = split(image, targets, \"test\")\n            self.image  = image\n            self.targets = targets\n        elif stage == \"val\":\n            image, targets = split(image, targets, \"val\")\n            self.image  = image\n            self.targets = targets\n        elif stage == \"predict\":\n            image = split(image, targets, \"predict\")\n            self.image  = image\n            self.targets = None\n        else:\n            raise ValueError(f\"stage :{stage} not in [train, test, val, predict]\" )\n    def __len__(self):\n        return len(self.image)\n    def __getitem__(self, index):\n        path = self.image[index]\n        image = cv2.imread(path)\n        #image = cv2.resize(image, (256,256))\n        #image = transformations(image)\n        if self.targets is None:\n            return torch.tensor(image).float().reshape(3,256,256)\n        return torch.tensor(image).float().reshape(3,256,256), torch.tensor(self.targets[index])","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:53:52.366134Z","iopub.execute_input":"2023-02-04T16:53:52.366955Z","iopub.status.idle":"2023-02-04T16:53:52.377412Z","shell.execute_reply.started":"2023-02-04T16:53:52.366915Z","shell.execute_reply":"2023-02-04T16:53:52.376187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Pytorch lightning data module ","metadata":{}},{"cell_type":"code","source":"class CancerDataModule(pl.LightningDataModule):\n    def __init__(self, X,y, batch_size, num_workers):\n        super().__init__()\n        self.X = X\n        self.y = y\n        self.batch_size = batch_size\n        self.num_workers = num_workers\n        \n    def setup(self,stage:str):\n        self.train_dataset = CancerDataset(self.X,self.y,stage = \"train\")\n        self.test_dataset = CancerDataset(self.X,self.y, stage = \"test\")\n        self.val_dataset = CancerDataset(self.X,self.y, stage = \"val\")\n        self.predict_dataset = CancerDataset(self.X,self.y,stage = \"predict\")\n    \n    def train_dataloader(self):\n        return DataLoader(self.train_dataset, shuffle = True, \n                          batch_size=self.batch_size, num_workers = self.num_workers)\n\n    def val_dataloader(self):\n        return DataLoader(self.val_dataset, \n                          batch_size=self.batch_size, num_workers = self.num_workers)\n\n    def test_dataloader(self):\n        return DataLoader(self.test_dataset, \n                          batch_size=self.batch_size, num_workers = self.num_workers)\n\n    def predict_dataloader(self):\n        return DataLoader(self.predict_dataset, \n                          batch_size=self.batch_size, num_workers = self.num_workers)","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:53:54.127745Z","iopub.execute_input":"2023-02-04T16:53:54.128191Z","iopub.status.idle":"2023-02-04T16:53:54.138213Z","shell.execute_reply.started":"2023-02-04T16:53:54.128153Z","shell.execute_reply":"2023-02-04T16:53:54.137048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Resnet50 Model ","metadata":{}},{"cell_type":"code","source":"nn = torchvision.models.resnet50(pretrained=True)\nnn.fc = torch.nn.Linear(2048,2) # changing num output features","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:49:03.394858Z","iopub.execute_input":"2023-02-04T16:49:03.395307Z","iopub.status.idle":"2023-02-04T16:49:09.57548Z","shell.execute_reply.started":"2023-02-04T16:49:03.395272Z","shell.execute_reply":"2023-02-04T16:49:09.574442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = torch.nn.CrossEntropyLoss()\n\nclass CancerModel(pl.LightningModule):\n    def __init__(self):\n        super().__init__()\n        self.nn = nn\n    def forward(self,x):\n        return self.nn(x)\n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(),\n                                    lr = 1e-4)\n        scheduler = torch.optim.lr_scheduler.StepLR(optimizer,\n                                                   step_size = 20,\n                                                   gamma = 0.75,\n                                                   last_epoch = -1, \n                                                   verbose = True)\n        return {\"optimizer\": optimizer,\n               \"lr_scheduler\": {\n                   \"scheduler\": scheduler,\n                   \"monitor\" : \"val_loss\"\n                   },\n               }\n    \n    def training_step(self, batch, batch_idx):\n        x,y = batch\n        y_pred = self(x)\n        loss = criterion(y_pred, y)\n        return loss\n    def validation_step(self,batch,batch_idx):\n        x,y = batch\n        y_pred = self(x)\n        loss = criterion(y_pred, y)\n        self.log(\"val_loss\", loss)\n        return loss\n    def test_step(self, batch, batch_idx):\n        x,y = batch\n        y_pred = self(x)\n        loss = criterion(y_pred, y)\n        self.log(\"test_loss: \", loss)\n        return loss\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:53:57.427283Z","iopub.execute_input":"2023-02-04T16:53:57.427638Z","iopub.status.idle":"2023-02-04T16:53:57.438543Z","shell.execute_reply.started":"2023-02-04T16:53:57.427608Z","shell.execute_reply":"2023-02-04T16:53:57.437431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Trainer","metadata":{}},{"cell_type":"code","source":"checkpoint_callback = ModelCheckpoint(monitor = \"val_loss\",\n                                     mode = \"min\")\n\nmodel = CancerModel()\ndata = CancerDataModule(X,y, batch_size = 32, num_workers = 1)\ntrainer = pl.Trainer(max_epochs = 10, \n                    accelerator = \"gpu\", \n                     devices = 1, \n                    callbacks = [checkpoint_callback],\n                    )\ntrainer.fit(model, data)\n","metadata":{"execution":{"iopub.status.busy":"2023-02-04T16:53:59.284465Z","iopub.execute_input":"2023-02-04T16:53:59.28482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}