{"cells":[{"metadata":{"_uuid":"336bac52-581f-4fd7-b15d-e1ea65fc47a7","_cell_guid":"31a1d56e-0199-46c1-b31b-e47bcbb7d518","trusted":true},"cell_type":"code","source":"import torch.nn as nn\nimport numpy as np\nnp.random.seed(0)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3f0276ed-71b0-4f72-95d0-925e7d26f24a","_cell_guid":"4830cc58-a651-4f0d-bf91-aecdd5698105","trusted":true},"cell_type":"code","source":"# !pip install pandas==1.0.3","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"aec38451-ac86-424b-90f0-d45710a8647a","_cell_guid":"fef8a86a-b0fc-47e6-9557-2a555b722199","trusted":true},"cell_type":"code","source":" cd /kaggle/input/histopathologic-cancer-detection/","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2df421fc-279e-4f22-a511-455113b2e66a","_cell_guid":"869a62db-6993-4cad-baa5-147ecc80791c","trusted":true},"cell_type":"code","source":"import torch.nn as nn\nimport torch.nn.functional as F\n\n\ndef findConv2dOutShape(H_in,W_in,conv,pool=2):\n    # get conv arguments\n    kernel_size=conv.kernel_size\n    stride=conv.stride\n    padding=conv.padding\n    dilation=conv.dilation\n\n    # Ref: https://pytorch.org/docs/stable/nn.html\n    H_out=np.floor((H_in+2*padding[0]-dilation[0]*(kernel_size[0]-1)-1)/stride[0]+1)\n    W_out=np.floor((W_in+2*padding[1]-dilation[1]*(kernel_size[1]-1)-1)/stride[1]+1)\n\n    if pool:\n        H_out/=pool\n        W_out/=pool\n    return int(H_out),int(W_out)\n\nclass Net(nn.Module):\n    def __init__(self, params):\n        super(Net, self).__init__()\n    \n        C_in,H_in,W_in=params[\"input_shape\"]\n        init_f=params[\"initial_filters\"] \n        num_fc1=params[\"num_fc1\"]  \n        num_classes=params[\"num_classes\"] \n        self.dropout_rate=params[\"dropout_rate\"] \n        \n        self.conv1 = nn.Conv2d(C_in, init_f, kernel_size=3)\n        h,w=findConv2dOutShape(H_in,W_in,self.conv1)\n        \n        self.conv2 = nn.Conv2d(init_f, 2*init_f, kernel_size=3)\n        h,w=findConv2dOutShape(h,w,self.conv2)\n        \n        self.conv3 = nn.Conv2d(2*init_f, 4*init_f, kernel_size=3)\n        h,w=findConv2dOutShape(h,w,self.conv3)\n\n        self.conv4 = nn.Conv2d(4*init_f, 8*init_f, kernel_size=3)\n        h,w=findConv2dOutShape(h,w,self.conv4)\n        \n        # compute the flatten size\n        self.num_flatten=h*w*8*init_f\n        \n        self.fc1 = nn.Linear(self.num_flatten, num_fc1)\n        self.fc2 = nn.Linear(num_fc1, num_classes)\n\n    def forward(self, x):\n        x = F.relu(self.conv1(x))\n        x = F.max_pool2d(x, 2, 2)\n        \n        x = F.relu(self.conv2(x))\n        x = F.max_pool2d(x, 2, 2)\n\n        x = F.relu(self.conv3(x))\n        x = F.max_pool2d(x, 2, 2)\n\n        x = F.relu(self.conv4(x))\n        x = F.max_pool2d(x, 2, 2)\n        \n        x = x.view(-1, self.num_flatten)\n        \n        x = F.relu(self.fc1(x))\n        x=F.dropout(x, self.dropout_rate)\n        x = self.fc2(x)\n        return F.log_softmax(x, dim=1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ef4743e1-c787-4643-a6f4-71b9a58ae55c","_cell_guid":"be47b4c1-97b1-4caf-ad65-fda3067a1432","trusted":true},"cell_type":"code","source":"# model parameters\nparams_model={\n \"input_shape\": (3,96,96),\n \"initial_filters\": 8, \n \"num_fc1\": 100,\n \"dropout_rate\": 0.25,\n \"num_classes\": 2,\n }\n\n# initialize model\ncnn_model = Net(params_model)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f982c44f-fd9d-4403-b1f9-bb1e81e9e862","_cell_guid":"bc343da2-77d7-4319-9248-ce2ef6bca85f","trusted":true},"cell_type":"code","source":"import torch\n\n# path2weights=\"./models/weights.pt\"\n# # load state_dict into model\n# cnn_model.load_state_dict(torch.load(path2weights))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"99ecf3f2-dfd0-44d2-92a4-cc45ad2e4480","_cell_guid":"9dd37f3e-cd85-4dec-b804-855576f92136","trusted":true},"cell_type":"code","source":"# # set model in evaluation mode\n# cnn_model.eval()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e40e7309-a079-44d6-bf7f-3395098a4408","_cell_guid":"4286d60f-0438-4752-9ac0-f0605126617c","trusted":true},"cell_type":"code","source":"# move model to cuda/gpu device\n# if torch.cuda.is_available():\n#     device = torch.device(\"cuda\")\n#     cnn_model=cnn_model.to(device)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"754639e6-1ec1-4001-a826-a8c89836cddd","_cell_guid":"17a64163-6662-44a3-9ff5-a385c7dc371d","trusted":true},"cell_type":"code","source":"import time \ndef deploy_model(model,dataset,device, num_classes=2,sanity_check=False):\n\n    len_data=len(dataset)\n    \n    # initialize output tensor on CPU: due to GPU memory limits\n    y_out=torch.zeros(len_data,num_classes)\n    \n    # initialize ground truth on CPU: due to GPU memory limits\n    y_gt=np.zeros((len_data),dtype=\"uint8\")\n    \n    # move model to device\n#     model=model.to(device)\n    \n    elapsed_times=[]\n    with torch.no_grad():\n        for i in range(len_data):\n            x,y=dataset[i]\n            y_gt[i]=y\n            start=time.time()    \n            y_out[i]=model(x.unsqueeze(0))\n#             y_out[i]=model(x.unsqueeze(0).to(device))\n            elapsed=time.time()-start\n            elapsed_times.append(elapsed)\n\n            if sanity_check is True:\n                break\n\n    inference_time=np.mean(elapsed_times)*1000\n    print(\"average inference time per image on %s: %.2f ms \" %(device,inference_time))\n    return y_out.numpy(),y_gt","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"396f95fe-9b51-4e4b-addb-e1e2725e3ebe","_cell_guid":"5940b79c-b656-4940-912b-ed0af58f21fe","trusted":true},"cell_type":"code","source":"import torch\nfrom PIL import Image\nfrom torch.utils.data import Dataset\nimport pandas as pd\nimport torchvision.transforms as transforms\nimport os\n\n# fix torch random seed\ntorch.manual_seed(0)\n\nclass histoCancerDataset(Dataset):\n    def __init__(self, data_dir, transform,data_type=\"train\"):      \n    \n        # path to images\n        path2data=os.path.join(data_dir,data_type)\n\n        # get a list of images\n        self.filenames = os.listdir(path2data)\n\n        # get the full path to images\n        self.full_filenames = [os.path.join(path2data, f) for f in self.filenames]\n\n        # labels are in a csv file named train_labels.csv\n        csv_filename=data_type+\"_labels.csv\"\n        path2csvLabels=os.path.join(data_dir,csv_filename)\n        labels_df=pd.read_csv(path2csvLabels)\n\n        # set data frame index to id\n        labels_df.set_index(\"id\", inplace=True)\n\n        # obtain labels from data frame\n        self.labels = [labels_df.loc[filename[:-4]].values[0] for filename in self.filenames]\n\n        self.transform = transform\n      \n    def __len__(self):\n        # return size of dataset\n        return len(self.full_filenames)\n      \n    def __getitem__(self, idx):\n        # open image, apply transforms and return with label\n        image = Image.open(self.full_filenames[idx])  # PIL image\n        image = self.transform(image)\n        return image, self.labels[idx]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"bcf0e3e1-1e82-4e4b-8a89-050b324bde0f","_cell_guid":"656b6d20-9eaf-47df-9a0a-794f35a3412c","trusted":true},"cell_type":"code","source":"import torchvision.transforms as transforms\ndata_transformer = transforms.Compose([transforms.ToTensor()])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b5a28b13-d968-4ee4-9897-a07bce5f4588","_cell_guid":"d0e06ed1-a2a3-4cc7-9b81-ea253975865f","trusted":true},"cell_type":"code","source":"import pixiedust\n%%pixie_debugger\n\ndata_dir = \"/kaggle/input/histopathologic-cancer-detection/\"\nhisto_dataset = histoCancerDataset(data_dir, data_transformer, \"train\")\nprint(len(histo_dataset))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !pip install pixiedust","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1bc3d258-b3fc-4f87-9a3a-a71a29524c41","_cell_guid":"afae9941-7717-4464-b017-fd0e85e9481c","trusted":true},"cell_type":"code","source":"from torch.utils.data import random_split\n\nlen_histo=len(histo_dataset)\nlen_train=int(0.8*len_histo)\nlen_val=len_histo-len_train\n\ntrain_ds,val_ds=random_split(histo_dataset,[len_train,len_val])\n\nprint(\"train dataset length:\", len(train_ds))\nprint(\"validation dataset length:\", len(val_ds))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9db88979-e287-47ed-85c0-2dc36e092dcf","_cell_guid":"f38f6137-106b-4946-82b4-67094dd3166e","trusted":true},"cell_type":"code","source":"# torch.save(tensor, 'file.pt') and torch.load('file.pt')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"84c29e8d-2c5a-4e87-80b9-cb201f37b20c","_cell_guid":"9724ccda-0431-4646-9a50-d940fda0948a","trusted":true},"cell_type":"code","source":"pwd","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"16de2c80-0723-456b-b1a4-a3c66237486a","_cell_guid":"0d87dbf6-3c09-4b17-867d-22581c630ea6","trusted":true},"cell_type":"code","source":"torch.save(histo_dataset, 'cancer.pt')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a5e29e13-31c1-43ac-95f8-ff92e6647f05","_cell_guid":"c3f21827-9cd0-4495-bf37-5d56c0f67563","trusted":true},"cell_type":"code","source":"# deploy model \ny_out,y_gt=deploy_model(cnn_model,val_ds,device=device,sanity_check=False)\nprint(y_out.shape,y_gt.shape)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"de0678be-19de-4274-88a7-dfafb09b1d61","_cell_guid":"215d5ae4-9bda-47e2-9c56-2b4a45115642","trusted":true},"cell_type":"markdown","source":"### Accuracy"},{"metadata":{"_uuid":"ff7f4d65-ed56-42c3-a9a7-a823c6721d5a","_cell_guid":"f4631c15-8208-4893-b497-40de63ad300c","trusted":true},"cell_type":"code","source":"# from sklearn.metrics import accuracy_score\n\n# # get predictions\n# y_pred = np.argmax(y_out,axis=1)\n# print(y_pred.shape,y_gt.shape)\n\n# # compute accuracy \n# acc=accuracy_score(y_pred,y_gt)\n# print(\"accuracy: %.2f\" %acc)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ef3b9005-2a22-4cc6-bfa4-94363d5738a4","_cell_guid":"d770cc4a-2859-4d23-86c7-9f36862bb397","trusted":true},"cell_type":"markdown","source":"### Deploy on CPU"},{"metadata":{"_uuid":"0a554550-f79d-4048-be1d-a2c26c40f606","_cell_guid":"feb7e47e-5155-4a92-a4f8-b491ea51c520","trusted":true},"cell_type":"code","source":"pwd","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9aef825d-170b-471e-9396-06c9266dd788","_cell_guid":"8357028a-4c4e-4465-a968-c8c5cf545175","trusted":true},"cell_type":"code","source":"# deploy model on cpu\ndevice_cpu = torch.device(\"cpu\")\ny_out,y_gt=deploy_model(cnn_model,val_ds,device=device_cpu,sanity_check=False)\nprint(y_out.shape,y_gt.shape)\n\n# from torch.utils.tensorboard import SummaryWriter\n\n#graph\nwriter = SummaryWriter()\nwriter.add_graph(cnn_model, val_ds)\n%load_ext tensorboard\n%tensorboard --logdir /kaggle/working/runs/","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1eea7e35-39f8-4d00-ab65-930e65f6f07f","_cell_guid":"b7a01f5a-3b5e-4445-a7f5-4988ac6fce69","trusted":true},"cell_type":"code","source":"pwd","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"987ec24c-b0c9-4804-8021-4c9be9ad4900","_cell_guid":"3794602f-6b6b-419f-985b-bbc7787e6688","trusted":true},"cell_type":"code","source":"import torch\ntorch.save(cnn_model, '/kaggle/working/mod')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1267cbcc-2e5e-4f71-bd6f-0f4a396c1e15","_cell_guid":"dca67438-9904-4d7f-bfc4-b1828b96c64d","trusted":true},"cell_type":"code","source":"from sklearn.metrics import accuracy_score\n\n# get predictions\ny_pred = np.argmax(y_out,axis=1)\nprint(y_pred.shape,y_gt.shape)\n\n# compute accuracy \nacc=accuracy_score(y_pred,y_gt)\nprint(\"accuracy: %.2f\" %acc)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e02117ce-8128-4961-aec4-9be0597258ed","_cell_guid":"21697617-1de9-482a-82ff-4d455a040a27","trusted":true},"cell_type":"markdown","source":"# Model Inference on Test Data"},{"metadata":{"_uuid":"176ef394-6e03-4b5e-82d1-0bf21cd53668","_cell_guid":"eba07f05-7444-4e93-b2e4-2df2d0b1027e","trusted":true},"cell_type":"code","source":"path2csv=\"/kaggle/input/histopathologic-cancer-detection/train_labels.csv\"\nlabels_df=pd.read_csv(path2csv)\nlabels_df.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f0be90b5-239e-48f7-b6cd-0a7f850266b4","_cell_guid":"bfb006f3-984f-40a3-bf32-f42ea8ad1262","trusted":true},"cell_type":"code","source":"data_dir = \"/kaggle/input/histopathologic-cancer-detection/\"\nhisto_test = histoCancerDataset(data_dir, data_transformer,data_type=\"train\")\nprint(len(histo_test))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0107c6de-cc15-4771-9dd8-025cee9fc9d4","_cell_guid":"a91807e8-7479-4b93-bcf8-4ef51fede550","trusted":true},"cell_type":"code","source":"\ny_test_out,_=deploy_model(cnn_model,histo_test, device_cpu, sanity_check=False)\n\n\ny_test_pred=np.argmax(y_test_out,axis=1)\nprint(y_test_pred.shape)\n\nfrom torch.utils.tensorboard import SummaryWriter\n\n#graph\nwriter = SummaryWriter()\nwriter.add_graph(cnn_model, torch.tensor(histo_test))\n%load_ext tensorboard\n%tensorboard --logdir runs/","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"65a6add3-6587-4814-b241-755165292461","_cell_guid":"4923a6d3-dfca-489b-a8fe-70c2b36f3073","trusted":true},"cell_type":"code","source":"from torchvision import utils\n\nimport numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline\nnp.random.seed(0)\n\n\ndef show(img,y,color=False):\n    # convert tensor to numpy array\n    npimg = img.numpy()\n   \n    # Convert to H*W*C shape\n    npimg_tr=np.transpose(npimg, (1,2,0))\n    \n    if color==False:\n        npimg_tr=npimg_tr[:,:,0]\n        plt.imshow(npimg_tr,interpolation='nearest',cmap=\"gray\")\n    else:\n        # display images\n        plt.imshow(npimg_tr,interpolation='nearest')\n    plt.title(\"label: \"+str(y))\n    \ngrid_size=4\nrnd_inds=np.random.randint(0,len(histo_test),grid_size)\nprint(\"image indices:\",rnd_inds)\n\nx_grid_test=[histo_test[i][0] for i in range(grid_size)]\ny_grid_test=[y_test_pred[i] for i in range(grid_size)]\n\nx_grid_test=utils.make_grid(x_grid_test, nrow=4, padding=2)\nprint(x_grid_test.shape)\n\nplt.rcParams['figure.figsize'] = (10.0, 5)\nshow(x_grid_test,y_grid_test)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"30b41d96-14bf-4047-a2e1-186f4457565b","_cell_guid":"0dfb59f7-3257-4d03-a442-d37cf2ba7599","trusted":true},"cell_type":"markdown","source":"### Create Submission"},{"metadata":{"_uuid":"eba4ea2e-da2a-49c8-a4d6-6237ed8bafd2","_cell_guid":"ee925fe1-6185-47c2-a709-ea46ffd70116","trusted":true},"cell_type":"code","source":"print(y_test_out.shape)\ncancer_preds = np.exp(y_test_out[:, 1])\nprint(cancer_preds.shape)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9b731921-03d6-42c1-b558-703017420f15","_cell_guid":"01c85107-a9e0-41d7-9c67-5c4b53323a6e","trusted":true},"cell_type":"code","source":"# # get test id's from the sample_submission.csv \n# path2sampleSub = \"./data/\"+ \"sample_submission.csv\"\n\n# # read sample submission\n# sample_df = pd.read_csv(path2sampleSub)\n\n# # get id column\n# ids_list = list(sample_df.id)\n\n# # convert predictions to to list\n# pred_list = [p for p in cancer_preds]\n\n# # create a dict of id and prediction\n# pred_dic = dict((key[:-4], value) for (key, value) in zip(histo_test.filenames, pred_list))    \n\n\n# # re-order predictions to match sample submission csv \n# pred_list_sub = [pred_dic[id_] for id_ in ids_list]\n\n# # create convert to data frame\n# submission_df = pd.DataFrame({'id':ids_list,'label':pred_list_sub})\n\n# # Export to csv\n# if not os.path.exists(\"./submissions/\"):\n#     os.makedirs(\"submissions/\")\n#     print(\"submission folder created!\")\n    \n# path2submission=\"./submissions/submission.csv\"\n# submission_df.to_csv(path2submission, header=True, index=False)\n# submission_df.head()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.8"}},"nbformat":4,"nbformat_minor":4}