{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.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":11848,"databundleVersionId":862157,"sourceType":"competition"}],"dockerImageVersionId":30163,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"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)\nfrom skimage.io import imread\nimport torch\nimport torch.nn as nn\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset,DataLoader\nfrom torchvision.io import read_image\nimport os\nimport cv2\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import accuracy_score,roc_auc_score\nimport time\nimport copy\nfrom tqdm import tqdm_notebook as tqdm\n\nimport warnings\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\nwarnings.filterwarnings(\"ignore\", category=UserWarning)\nwarnings.filterwarnings(\"ignore\", category=FutureWarning)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-22T08:09:44.550830Z","iopub.execute_input":"2024-05-22T08:09:44.551455Z","iopub.status.idle":"2024-05-22T08:09:48.048126Z","shell.execute_reply.started":"2024-05-22T08:09:44.551352Z","shell.execute_reply":"2024-05-22T08:09:48.047297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Hyper Paramaters","metadata":{}},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nnum_epochs = 30\nbatch_size = 256\nnum_classes = 2\nlearning_rate = 0.01","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:09:57.446244Z","iopub.execute_input":"2024-05-22T08:09:57.447030Z","iopub.status.idle":"2024-05-22T08:09:57.494877Z","shell.execute_reply.started":"2024-05-22T08:09:57.446988Z","shell.execute_reply":"2024-05-22T08:09:57.493943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path='../input/histopathologic-cancer-detection/train/'\nannotation_file='../input/histopathologic-cancer-detection/train_labels.csv'\ntest_path='../input/histopathologic-cancer-detection/test/'","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:10:11.750339Z","iopub.execute_input":"2024-05-22T08:10:11.750621Z","iopub.status.idle":"2024-05-22T08:10:11.755031Z","shell.execute_reply.started":"2024-05-22T08:10:11.750590Z","shell.execute_reply":"2024-05-22T08:10:11.754107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data =pd.read_csv('../input/histopathologic-cancer-detection/train_labels.csv')\nsub = pd.read_csv('../input/histopathologic-cancer-detection/sample_submission.csv')\ntrain_data.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:10:09.293374Z","iopub.execute_input":"2024-05-22T08:10:09.294204Z","iopub.status.idle":"2024-05-22T08:10:09.771291Z","shell.execute_reply.started":"2024-05-22T08:10:09.294149Z","shell.execute_reply":"2024-05-22T08:10:09.770496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check data balanced","metadata":{}},{"cell_type":"code","source":"plt.pie(train_data.label.value_counts(), labels=['No Cancer', 'Cancer'], colors=['#90EE91', '#F47174'], autopct='%1.1f')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:10:17.208587Z","iopub.execute_input":"2024-05-22T08:10:17.208895Z","iopub.status.idle":"2024-05-22T08:10:17.305103Z","shell.execute_reply.started":"2024-05-22T08:10:17.208857Z","shell.execute_reply":"2024-05-22T08:10:17.304071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cancer = np.random.choice(train_data[train_data.label==1].id, size=50, replace=False)\nno_cancer = np.random.choice(train_data[train_data.label==0].id, size=50, replace=False)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:10:22.140928Z","iopub.execute_input":"2024-05-22T08:10:22.141615Z","iopub.status.idle":"2024-05-22T08:10:22.166565Z","shell.execute_reply.started":"2024-05-22T08:10:22.141577Z","shell.execute_reply":"2024-05-22T08:10:22.165905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize the cancer images","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(5, 10, figsize=(20,10))\n\nfor n in range(5):\n    for m in range(10):\n        img_id = cancer[m + n*10]\n        image = plt.imread(path + img_id + \".tif\")\n        ax[n,m].imshow(image)\n        ax[n,m].grid(False)\n        ax[n,m].tick_params(labelbottom=False, labelleft=False)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:10:26.086475Z","iopub.execute_input":"2024-05-22T08:10:26.086767Z","iopub.status.idle":"2024-05-22T08:10:31.728258Z","shell.execute_reply.started":"2024-05-22T08:10:26.086735Z","shell.execute_reply":"2024-05-22T08:10:31.727121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize Not cancer images","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(5, 10, figsize=(20,10))\n\nfor n in range(5):\n    for m in range(10):\n        img_id = no_cancer[m + n*10]\n        image = plt.imread(path + img_id + \".tif\")\n        ax[n,m].imshow(image)\n        ax[n,m].grid(False)\n        ax[n,m].tick_params(labelbottom=False, labelleft=False)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:10:39.140199Z","iopub.execute_input":"2024-05-22T08:10:39.140535Z","iopub.status.idle":"2024-05-22T08:10:44.553727Z","shell.execute_reply.started":"2024-05-22T08:10:39.140498Z","shell.execute_reply":"2024-05-22T08:10:44.553026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## train validation split","metadata":{}},{"cell_type":"code","source":"train, val = train_test_split(train_data, stratify=train_data['label'], test_size=0.1)\nprint(len(train), len(val))","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:11:07.607039Z","iopub.execute_input":"2024-05-22T08:11:07.607356Z","iopub.status.idle":"2024-05-22T08:11:07.720224Z","shell.execute_reply.started":"2024-05-22T08:11:07.607303Z","shell.execute_reply":"2024-05-22T08:11:07.719508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(10,4))\n\nsns.countplot(train.label, palette=\"Blues\", ax=ax[0])\nax[0].set_title(\"Train dataset\")\nfor i, rows in enumerate(train['label'].value_counts().values):\n    ax[0].annotate(int(rows), xy=(i, rows), ha='center')\nsns.countplot(val.label, palette=\"Greens\", ax=ax[1])\nax[1].set_title(\"Validation dataset\")\nfor i, rows in enumerate(val['label'].value_counts().values):\n    ax[1].annotate(int(rows), xy=(i, rows), ha='center')","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:11:11.818790Z","iopub.execute_input":"2024-05-22T08:11:11.819471Z","iopub.status.idle":"2024-05-22T08:11:12.191462Z","shell.execute_reply.started":"2024-05-22T08:11:11.819436Z","shell.execute_reply":"2024-05-22T08:11:12.190744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset Class","metadata":{}},{"cell_type":"code","source":"class Dataset(Dataset):\n    \n    def __init__(self, df_data, data_dir = './', transform=None):\n        super().__init__()\n        self.df = df_data.values\n        self.data_dir = data_dir\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        img_name,label = self.df[index]\n        img_path = os.path.join(self.data_dir, img_name + '.tif')\n        image = cv2.imread(img_path)\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:11:47.239131Z","iopub.execute_input":"2024-05-22T08:11:47.239431Z","iopub.status.idle":"2024-05-22T08:11:47.247179Z","shell.execute_reply.started":"2024-05-22T08:11:47.239395Z","shell.execute_reply":"2024-05-22T08:11:47.246179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform_train = transforms.Compose([transforms.ToPILImage(),\n                                  transforms.RandomHorizontalFlip(0.25), \n                                  transforms.RandomVerticalFlip(0.25),\n                                  transforms.RandomRotation(25), \n                                  transforms.ToTensor(),\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])\n\ntransform_val = transforms.Compose([transforms.ToPILImage(),\n                                  transforms.ToTensor(),\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])\n\ntransform_test = transforms.Compose([transforms.ToPILImage(), \n                                  transforms.ToTensor(),\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:12:07.562645Z","iopub.execute_input":"2024-05-22T08:12:07.563440Z","iopub.status.idle":"2024-05-22T08:12:07.571161Z","shell.execute_reply.started":"2024-05-22T08:12:07.563399Z","shell.execute_reply":"2024-05-22T08:12:07.570348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = Dataset(df_data=train, data_dir=path, transform=transform_train)\nval_dataset = Dataset(df_data=val, data_dir=path, transform=transform_val)\ntest_dataset = Dataset(df_data=sub, data_dir=test_path, transform=transform_test)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:12:15.874937Z","iopub.execute_input":"2024-05-22T08:12:15.875786Z","iopub.status.idle":"2024-05-22T08:12:15.905534Z","shell.execute_reply.started":"2024-05-22T08:12:15.875745Z","shell.execute_reply":"2024-05-22T08:12:15.904925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True,num_workers=4)\nval_dataloader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False, num_workers=4)\ntest_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:12:24.088148Z","iopub.execute_input":"2024-05-22T08:12:24.088933Z","iopub.status.idle":"2024-05-22T08:12:24.094070Z","shell.execute_reply.started":"2024-05-22T08:12:24.088891Z","shell.execute_reply":"2024-05-22T08:12:24.093225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self):\n        super(CNN,self).__init__()\n        \n        self.conv1 = nn.Sequential(\n                        nn.Conv2d(3, 32, 3, stride=1, padding=1),\n                        nn.BatchNorm2d(32),\n                        nn.ReLU(inplace=True),\n                        nn.MaxPool2d(2,2))\n        \n        self.conv2 = nn.Sequential(\n                        nn.Conv2d(32, 64, 3, stride=1, padding=1),\n                        nn.BatchNorm2d(64),\n                        nn.ReLU(inplace=True),\n                        nn.MaxPool2d(2,2))\n        \n        self.conv3 = nn.Sequential(\n                        nn.Conv2d(64, 128, 3, stride=1, padding=1),\n                        nn.BatchNorm2d(128),\n                        nn.ReLU(inplace=True),\n                        nn.MaxPool2d(2,2))\n        \n        self.conv4 = nn.Sequential(\n                        nn.Conv2d(128, 256, 3, stride=1, padding=1),\n                        nn.BatchNorm2d(256),\n                        nn.ReLU(inplace=True),\n                        nn.MaxPool2d(2,2))\n        \n        self.conv5 = nn.Sequential(\n                        nn.Conv2d(256, 512, 3, stride=1, padding=1),\n                        nn.BatchNorm2d(512),\n                        nn.ReLU(inplace=True),\n                        nn.MaxPool2d(2,2))\n        \n        \n        self.fc=nn.Sequential(\n                nn.Linear(512*3*3, 256),\n                nn.ReLU(inplace=True),\n                nn.BatchNorm1d(256),\n                nn.Dropout(0.4),\n                nn.Linear(256, num_classes))\n        \n    def forward(self,x):\n        x=self.conv1(x)\n        x=self.conv2(x)\n        x=self.conv3(x)\n        x=self.conv4(x)\n        x=self.conv5(x)\n#        print(x.shape)\n        x=x.view(x.shape[0],-1)\n        x=self.fc(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:12:41.521534Z","iopub.execute_input":"2024-05-22T08:12:41.522312Z","iopub.status.idle":"2024-05-22T08:12:41.792712Z","shell.execute_reply.started":"2024-05-22T08:12:41.522274Z","shell.execute_reply":"2024-05-22T08:12:41.791693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CNN().to(device)\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:12:44.185568Z","iopub.execute_input":"2024-05-22T08:12:44.186356Z","iopub.status.idle":"2024-05-22T08:12:47.359769Z","shell.execute_reply.started":"2024-05-22T08:12:44.186314Z","shell.execute_reply":"2024-05-22T08:12:47.359024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:13:00.423994Z","iopub.execute_input":"2024-05-22T08:13:00.424296Z","iopub.status.idle":"2024-05-22T08:13:00.429378Z","shell.execute_reply.started":"2024-05-22T08:13:00.424260Z","shell.execute_reply":"2024-05-22T08:13:00.428415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_losses = []\nval_losses = []\ntrain_auc = []\nval_auc = []\ntrain_auc_epoch = []\nval_auc_epoch = []\nbest_acc = 0.0\nmin_loss = np.Inf\n\nsince = time.time()\n\nfor e in range(num_epochs):\n    \n    train_loss = 0.0\n    val_loss = 0.0\n    \n    # Train the model\n    model.train()\n    for i, (images, labels) in enumerate(tqdm(train_dataloader, total=int(len(train_dataloader)))):\n        images = images.to(device)\n        labels = labels.to(device)\n        \n        # Forward pass\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        \n        # Backward and optimize\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        # Loss and accuracy\n        train_loss += loss.item()\n        y_actual = labels.data.cpu().numpy()\n        y_pred = outputs[:,-1].detach().cpu().numpy()\n        train_auc.append(roc_auc_score(y_actual, y_pred))\n    \n    # Evaluate the model\n    model.eval()\n    for i, (images, labels) in enumerate(tqdm(val_dataloader, total=int(len(val_dataloader)))):\n        images = images.to(device)\n        labels = labels.to(device)\n        \n        # Forward pass\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        \n        # Loss and accuracy\n        val_loss += loss.item()\n        y_actual = labels.data.cpu().numpy()\n        y_pred = outputs[:,-1].detach().cpu().numpy()\n        val_auc.append(roc_auc_score(y_actual, y_pred))\n    \n    # Average losses and accuracies\n    train_loss = train_loss/len(train_dataloader)\n    val_loss = val_loss/len(val_dataloader)\n    train_losses.append(train_loss)\n    val_losses.append(val_loss)\n    training_auc = np.mean(train_auc)\n    validation_auc = np.mean(val_auc)\n    train_auc_epoch.append(training_auc)\n    val_auc_epoch.append(validation_auc)\n    \n    # Updating best validation accuracy\n    if best_acc < validation_auc:\n        best_acc = validation_auc\n        \n    # Saving best model\n    if min_loss >= val_loss:\n        torch.save(model.state_dict(), 'best_model.pt')\n        min_loss = val_loss\n    \n    print('EPOCH {}/{} Train loss: {:.6f},Validation loss: {:.6f}, Train AUC: {:.4f}  Validation AUC: {:.4f}\\n  '.format(e+1, num_epochs,train_loss,val_loss, training_auc,validation_auc))\n    print('-' * 10)\ntime_elapsed = time.time() - since\nprint('Training completed in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))\nprint('Best validation accuracy: {:4f}'.format(best_acc))","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:13:12.238571Z","iopub.execute_input":"2024-05-22T08:13:12.238868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,5))\nplt.plot(train_losses, '-o', label=\"train\")\nplt.plot(val_losses, '-o', label=\"val\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Loss\")\nplt.title(\"Loss change over epoch\")\nplt.legend()","metadata":{"execution":{"iopub.status.busy":"2022-02-24T19:13:33.433684Z","iopub.execute_input":"2022-02-24T19:13:33.433954Z","iopub.status.idle":"2022-02-24T19:13:33.744484Z","shell.execute_reply.started":"2022-02-24T19:13:33.433919Z","shell.execute_reply":"2022-02-24T19:13:33.743357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,5))\nplt.plot(train_auc_epoch, '-o', label=\"train\")\nplt.plot(val_auc_epoch, '-o', label=\"val\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.title(\"Accuracy over epoch\")\nplt.legend()","metadata":{"execution":{"iopub.status.busy":"2022-02-24T19:13:33.747029Z","iopub.execute_input":"2022-02-24T19:13:33.747747Z","iopub.status.idle":"2022-02-24T19:13:34.049465Z","shell.execute_reply.started":"2022-02-24T19:13:33.747698Z","shell.execute_reply":"2022-02-24T19:13:34.048436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.load_state_dict(torch.load('best_model.pt'))\n","metadata":{"execution":{"iopub.status.busy":"2022-02-24T19:13:34.052668Z","iopub.execute_input":"2022-02-24T19:13:34.052914Z","iopub.status.idle":"2022-02-24T19:13:34.08083Z","shell.execute_reply.started":"2022-02-24T19:13:34.052884Z","shell.execute_reply":"2022-02-24T19:13:34.079675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\n\npredictions = []\n\nfor i, (images, labels) in enumerate(tqdm(test_dataloader, total=int(len(test_dataloader)))):\n    images = images.to(device)\n    labels = labels.to(device)\n    \n    outputs = model(images)\n    pred = outputs[:,1].detach().cpu().numpy()\n    \n    for j in pred:\n        predictions.append(j)","metadata":{"execution":{"iopub.status.busy":"2022-02-24T19:13:34.082738Z","iopub.execute_input":"2022-02-24T19:13:34.083111Z","iopub.status.idle":"2022-02-24T19:23:54.418636Z","shell.execute_reply.started":"2022-02-24T19:13:34.083039Z","shell.execute_reply":"2022-02-24T19:23:54.417654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub['label'] = predictions\nsub.to_csv('submission.csv', index=False)\nsub.info()","metadata":{"execution":{"iopub.status.busy":"2022-02-24T19:23:54.420564Z","iopub.execute_input":"2022-02-24T19:23:54.421137Z","iopub.status.idle":"2022-02-24T19:23:54.750762Z","shell.execute_reply.started":"2022-02-24T19:23:54.421092Z","shell.execute_reply":"2022-02-24T19:23:54.74907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images = np.random.choice(sub.id, size=50, replace=False)     \n\nfig, ax = plt.subplots(5, 10, figsize=(20,10))\n\nfor n in range(5):\n    for m in range(10):\n        img_id = test_images[m + n*10]\n        image = plt.imread(test_path + img_id + \".tif\")\n        pred = sub.loc[sub['id'] == img_id, 'label'].values[0]\n        label = \"Cancer\" if(pred >= 0.5) else \"Healthy\"  \n        ax[n,m].imshow(image)\n        ax[n,m].grid(False)\n        ax[n,m].tick_params(labelbottom=False, labelleft=False)\n        ax[n,m].set_title(\"Label: \" + label)","metadata":{"execution":{"iopub.status.busy":"2022-02-24T19:23:54.752731Z","iopub.execute_input":"2022-02-24T19:23:54.753285Z","iopub.status.idle":"2022-02-24T19:24:01.268954Z","shell.execute_reply.started":"2022-02-24T19:23:54.753237Z","shell.execute_reply":"2022-02-24T19:24:01.266531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}