{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Importing Libraries Here","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import cv2\nimport 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 time\nimport os\nfrom pandas_profiling import ProfileReport\nfrom skimage import io\nimport skimage\nfrom itertools import product\nimport random\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.models import resnet18, densenet121, mobilenet_v2\nfrom albumentations import RandomRotate90, Flip, Compose, Normalize, RandomResizedCrop\nfrom sklearn.model_selection import train_test_split\nimport torch\nimport torchvision\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler, Adam, SGD\nfrom torch.autograd import Variable\nimport torchvision\nfrom torchvision import datasets, models, transforms\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Reading All Files","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n# #         print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Path Variables","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"BASE_PATH='../input/prostate-cancer-grade-assessment/'\nTRAIN_IMAGES_PATH = BASE_PATH + 'train_images/'\nTRAIN_LABELS_PATH = BASE_PATH + 'train_label_masks/'\nTEST_IMAGES_PATH = BASE_PATH+'test_images'\nSAMPLE = BASE_PATH+'sample_submission.csv'\nTRAIN=BASE_PATH+'train.csv'\nTEST = BASE_PATH+'test.csv'\n\ntrain_df = pd.read_csv(TRAIN)\ntrain = train_df.copy()\ntest_df = pd.read_csv(TEST)\ntest = test_df.copy()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Anaysis","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train['isup_grade'].unique()\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_image = os.listdir(TRAIN_IMAGES_PATH)\ntrain_label = os.listdir(TRAIN_LABELS_PATH)\nprint(\"length of training images\", len(train_image))\nprint(\"length of training labels\", len(train_label))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trimmed_train_image=[]\nfor img in train_image:\n    trimmed_train_image.append(img.split('.tiff')[0])\n    \ntrimmed_train_label=[]\n\nfor img in train_label:\n    trimmed_train_label.append(img.split('_mask.tiff')[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Number of missing mask images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"missing_img = np.setdiff1d(trimmed_train_image, trimmed_train_label)\nprint(missing_img.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(trimmed_train_image))\nprint(len(trimmed_train_label))\n\nmasks=os.listdir(BASE_PATH+'train_label_masks/')\nimages=os.listdir(BASE_PATH+'train_images/')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_masks=pd.Series(masks).to_frame()\ndf_masks.columns=['mask_file_name']\ndf_masks['image_id']=df_masks.mask_file_name.apply(lambda x:x.split('_')[0])\n# df_masks","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train=pd.merge(train,df_masks,on='image_id',how='outer')\ndel df_masks\n# df_train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Processing gleason score column with 'negative' entries","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"gleason_replace_dict = {0:0, 1:1, 3:2, 4:3, 5:4}\n\ndef process_gleason(gleason):\n    if gleason == 'negative': gs = (1, 1)\n    else: gs = tuple(gleason.split('+'))\n    return [gleason_replace_dict[int(g)] for g in gs]\n\ndf_train.gleason_score = df_train.gleason_score.apply(process_gleason)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# df_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train['gleason_primary'] = ''\ndf_train['gleason_secondary'] = ''\n\nfor idx in range(0, len(df_train.gleason_score)):\n    df_train['gleason_primary'][idx] = df_train['gleason_score'][idx][0]\n    df_train['gleason_secondary'][idx] = df_train['gleason_score'][idx][1]\n    \ndf_train = df_train.drop(['gleason_score'], axis=1)\n# df_train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Removing All Empty Masks","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train['mask_file_name'].isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.dropna(subset=['mask_file_name'], inplace=True, axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Panda Data Report","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# profile = ProfileReport(df_train, title=\"Prostate Cancer Data\")\n# profile.to_file(\"report.html\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Tile Method to speed up computation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def tile(img, sz=128, N=16):\n    shape = img.shape\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                 constant_values=255)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    if len(img) < N:\n        img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n    idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:N]\n    img = img[idxs]\n    return img","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Neural Network Models.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# from sklearn.metrics import cohen_kappa_score\n# def quadratic_weighted_kappa(y_hat, y):\n#     return cohen_kappa_score(y_hat, y, weights='quadratic')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train-Test Split","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"X = df_train.drop(['isup_grade'], axis=1)\nY= df_train['isup_grade']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train, X_valid, y_train, y_valid = train_test_split(X ,Y, test_size=0.2, random_state=1234)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Making Dataloaders ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nclass TrainDataset(Dataset):\n    def __init__(self, df, labels, transform = None):\n        self.df = df\n        self.labels = labels\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.df['image_id'].values[idx]\n        file_path = f'../input/prostate-cancer-grade-assessment/train_images/{file_name}.tiff'\n        image = skimage.io.MultiImage(file_path)[-1]\n        image = tile(image, sz=128, N=16)\n        image = cv2.hconcat([cv2.vconcat([image[0], image[1], image[2], image[3]]), \n                                 cv2.vconcat([image[4], image[5], image[6], image[7]]), \n                                 cv2.vconcat([image[8], image[9], image[10], image[11]]), \n                                 cv2.vconcat([image[12], image[13], image[14], image[15]])])\n        image = cv2.resize(image, (299, 299))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        image = skimage.img_as_float32(image)\n        label = self.labels.values[idx]        \n        return image, label\n    \n\nclass TestDataset(Dataset):\n    def __init__(self, df, dir_name, transform=None):\n        self.df = df\n        self.dir_name = dir_name\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.df['image_id'].values[idx]\n        file_path = r'/input/prostate-cancer-grade-assessment/{self.dir_name}/{file_name}.tiff'\n        image = skimage.io.MultiImage(file_path)\n#         image = cv2.resize(image[-1], (224, 224))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n        \n        return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = TrainDataset(X_train, y_train, transform= None) \nvalid_dataset = TrainDataset(X_valid, y_valid, transform= None) \ntrain_loader = DataLoader(train_dataset, batch_size=10, num_workers = 4)\nvalid_loader = DataLoader(valid_dataset, batch_size=10, num_workers = 4)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## As we have a multi-label problem so encoding would be compulsory thing to do","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def encoder(a, num_classes):\n    labels= torch.nn.functional.one_hot(a, num_classes)\n    for i in range(labels[:,0].shape[0]):\n        if(labels[:,0][i]==1):\n            labels[:,2][i]=1\n    return labels.float()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading ResNet Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"resnet = models.resnet18(pretrained=False).to(device)\n    \nfor param in resnet.parameters():\n    param.requires_grad = True \n    \nresnet.fc = nn.Sequential(\n               nn.Linear(512, 770),\n               nn.ReLU(inplace=True),\n               nn.Linear(770, 6)).to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def focal_loss(targets,logits,eps,l):\n    ce_loss = torch.nn.functional.binary_cross_entropy_with_logits(logits, targets, reduction= 'none')\n    pt = torch.exp(-ce_loss)\n    loss = (eps * (1-pt)**l * ce_loss).mean()\n    return loss","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training Function which perform training and validation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def train(resnet, train_loader, valid_loader, epoch):\n    history = []  \n    \n    resnet.to(device)\n#     print(device)\n    \n    for e in range(epoch):\n        vcorrect = 0\n        predicted = []\n        train_acc = 0\n        valid_acc = 0\n        vtotal = 0\n        running_loss = 0.0\n        train_loss = 0\n        correct = 0\n        total = 0\n        total_train = 0\n        train_loss = 0.0\n        valid_loss = 0.0\n        running_loss = 0.0\n\n        for images, labels in iter(train_loader):\n            \n            images = images.to(device)\n            labels = labels.to(device)\n            images = images.permute(0,3,2,1)\n\n            hot_labels = encoder(labels, 6)\n            hot_labels = hot_labels.to(device)\n            optimizer.zero_grad()\n            outputs = resnet(images)\n            loss = focal_loss(hot_labels, outputs, 0.25, 2 )\n            loss.backward()                     #----> backward pass\n            optimizer.step()\n            \n            outputs[outputs >= 0.5] = 1\n            outputs[outputs < 0.5] = 0\n            correct += (outputs == hot_labels).sum().item()\n            total += labels.size(0)\n            running_loss += loss.item()\n            \n        for images, labels in iter(valid_loader):\n            \n            images = images.to(device)\n            labels = labels.to(device)\n            images = images.permute(0,3,2,1)\n\n            hot_labels = encoder(labels, 6)\n            hot_labels = hot_labels.to(device)\n            outputs = resnet(images)\n            loss = focal_loss(hot_labels, outputs, 0.2, 2 )\n            valid_loss += loss.item()\n            outputs[outputs >= 0.5] = 1\n            outputs[outputs < 0.5] = 0\n            vcorrect += (outputs == hot_labels).sum().item()\n            vtotal += hot_labels.size(0)\n\n        train_loss = running_loss / len(train_loader)\n        valid_loss = valid_loss / len(valid_loader)\n        train_acc = correct / total\n        valid_acc = vcorrect / vtotal\n        train_acc/=6\n        valid_acc/=6\n#         score = quadratic_weighted_kappa(valid_labels, preds)\n\n        history.append([train_loss, valid_loss, train_acc, valid_acc])\n        print('Epoch #', e, '\\t\\tTraining loss: ', train_loss, '\\t Validation loss: ', valid_loss)\n        print('\\t\\tTraining Accuracy: ', (100 * train_acc), '\\t Validation Accuracy: ', (100 * valid_acc))\n    history = pd.DataFrame(history, columns=['train_loss', 'valid_loss', 'train_acc', 'valid_acc'])\n#     torch.save(model.state_dict(), './gdrive/My Drive/' + name)\n    return resnet,history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# criterion = nn.BCEWithLogitsLoss()\noptimizer = optim.SGD(resnet.parameters(), lr=0.01, momentum=0.4)\nmodel, history = train(resnet, train_loader, valid_loader, 20)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## loss and Accuracy Curves","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nplt.figure(figsize=(8, 6))\nfor c in ['train_loss', 'valid_loss']:\n    plt.plot(history[c], label=c)\nplt.legend()\nplt.xlabel('Epoch')\nplt.ylabel('Average Negative Log Likelihood')\nplt.title('Training and Validation Losses')\n\nplt.figure(figsize=(8, 6))\nfor c in ['train_acc', 'valid_acc']:\n    plt.plot(100 * history[c], label=c)\nplt.legend()\nplt.xlabel('Epoch')\nplt.ylabel('Average Accuracy')\nplt.title('Training and Validation Accuracy')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Confusion Matrix","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, f1_score, precision_score, recall_score\nfrom sklearn.metrics import multilabel_confusion_matrix\nfrom mlxtend.plotting import plot_confusion_matrix\n\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel.to(device)\npr =[]\ntl =[]\n    \nwith torch.no_grad():\n    for images, labels in iter(valid_loader):\n        images = images.to(device)\n        labels = labels.to(device)\n        images = images.permute(0,3,2,1)\n        hot_labels = encoder(labels, 6)\n        hot_labels = hot_labels.to(device)\n        outputs = model(images)\n        outputs[outputs >= 0.5] = 1\n        outputs[outputs < 0.5] = 0\n        \n        for i in hot_labels.tolist():\n            tl.append(i)\n        for j in outputs.tolist():\n            pr.append(j)\n\n    pr = np.argmax(pr, axis=1)\n    tl = np.argmax(tl, axis=1)\n\ncm = multilabel_confusion_matrix(np.array(tl),np.array(pr))\nlabels=['0','1','2','3','4','5']\nfig, ax = plot_confusion_matrix(conf_mat=cm[0], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('Resnet 18 Training CF with Focal Loss (Matrix 0)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[1], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('Resnet 18 Training CF with Focal Loss (Matrix 1)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[2], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('Resnet 18 Training CF with Focal Loss (Matrix 2)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[3], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('Resnet 18 Training CF with Focal Loss (Matrix 3)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[4], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('Resnet 18 Training CF with Focal Loss (Matrix 4)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[5], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('Resnet 18 Training CF with Focal Loss (Matrix 5)')\n\nprint('F1: {}'.format(f1_score(hot_labels.data.cpu().numpy(), outputs.data.cpu().numpy(), average='macro')))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading VGG16 Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"vgg16 = models.vgg16(pretrained=False).to(device)\nvgg16.classifier = nn.Sequential(\n               nn.Linear(25088, 770),\n               nn.ReLU(inplace=True),\n               nn.Linear(770, 770),\n               nn.ReLU(inplace=True),\n               nn.Linear(770, 6)).to(device)\n\nfor param in vgg16.parameters():\n    param.requires_grad = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = optim.SGD(vgg16.parameters(), lr=0.001, momentum=0.8)\nmodel, history = train(vgg16, train_loader, valid_loader, 50)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## loss and Accuracy Curve","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\nplt.figure(figsize=(8, 6))\nfor c in ['train_loss', 'valid_loss']:\n    plt.plot(history[c], label=c)\nplt.legend()\nplt.xlabel('Epoch')\nplt.ylabel('Average Negative Log Likelihood')\nplt.title('Training and Validation Losses')\n\nplt.figure(figsize=(8, 6))\nfor c in ['train_acc', 'valid_acc']:\n    plt.plot(100 * history[c], label=c)\nplt.legend()\nplt.xlabel('Epoch')\nplt.ylabel('Average Accuracy')\nplt.title('Training and Validation Accuracy')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Confusion Matrix\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, f1_score, precision_score, recall_score\nfrom sklearn.metrics import multilabel_confusion_matrix\nfrom mlxtend.plotting import plot_confusion_matrix\n\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel.to(device)\npr =[]\ntl =[]\n    \nwith torch.no_grad():\n    for images, labels in iter(valid_loader):\n        images = images.to(device)\n        labels = labels.to(device)\n        images = images.permute(0,3,2,1)\n        hot_labels = encoder(labels, 6)\n        hot_labels = hot_labels.to(device)\n        outputs = model(images)\n        outputs[outputs >= 0.5] = 1\n        outputs[outputs < 0.5] = 0\n        \n        for i in hot_labels.tolist():\n            tl.append(i)\n        for j in outputs.tolist():\n            pr.append(j)\n\n    pr = np.argmax(pr, axis=1)\n    tl = np.argmax(tl, axis=1)\n        \ncm = multilabel_confusion_matrix(np.array(tl),np.array(pr))\nlabels=['0','1','2','3','4','5']\nfig, ax = plot_confusion_matrix(conf_mat=cm[0], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('vgg16 Training CF with Focal Loss (Matrix 0)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[1], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('vgg16 Training CF with Focal Loss (Matrix 1)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[2], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('vgg16 Training CF with Focal Loss (Matrix 2)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[3], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('vgg16 Training CF with Focal Loss (Matrix 3)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[4], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('vgg16 Training CF with Focal Loss (Matrix 4)')\n\nfig, ax = plot_confusion_matrix(conf_mat=cm[5], show_absolute=True, show_normed=True, colorbar=True)\nplt.title('vgg16 Training CF with Focal Loss (Matrix 5)')\n\nprint('F1: {}'.format(f1_score(hot_labels.data.cpu().numpy(), outputs.data.cpu().numpy(), average='macro')))","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}