{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nos.listdir('../input/histopathologic-cancer-detection')\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n #   for filename in filenames:\n  #      print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"path2csv='../input/histopathologic-cancer-detection/train_labels.csv'\nlabels_df=pd.read_csv(path2csv)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels_df.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(labels_df['label'].value_counts())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\nlabels_df['label'].hist();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pylab as plt\nfrom PIL import Image, ImageDraw\nimport numpy as np\nimport os\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# get ids for malignant images\nmalignantIds = labels_df.loc[labels_df['label']==1]['id'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path2train=\"../input/histopathologic-cancer-detection/train\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"color=False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.rcParams['figure.figsize'] = (10.0, 10.0)\nplt.subplots_adjust(wspace=0, hspace=0)\nnrows,ncols=3,3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i,id_ in enumerate(malignantIds[:nrows*ncols]):\n    full_filenames = os.path.join(path2train , id_ +'.tif')\n    # load image\n    img = Image.open(full_filenames)\n    # draw a 32*32 rectangle\n    draw = ImageDraw.Draw(img)\n    draw.rectangle(((32, 32), (64, 64)),outline=\"green\")\n    plt.subplot(nrows, ncols, i+1)\n    if color is True:\n        plt.imshow(np.array(img))\n    else:\n        plt.imshow(np.array(img)[:,:,0],cmap=\"gray\")\n    plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"image shape:\", np.array(img).shape)\nprint(\"pixel values range from %s to %s\" %(np.min(img),\nnp.max(img)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We will define a class for the custom dataset, define the transformation function, and then load an image from the dataset using the Dataset class. "},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\nimport torch\nfrom torch.utils.data import Dataset\nimport pandas as pd\nimport torchvision.transforms as transforms\nimport os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# fix torch random seed\ntorch.manual_seed(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class histoCancerDataset(Dataset):\n    def __init__(self, data_dir, transform,data_type=\"train\"):\n        # path to images\n        path2data = os.path.join(data_dir,data_type)\n        # get a list of images\n        filenames = os.listdir(path2data)\n        # get the full path to images\n        self.full_filenames = [os.path.join(path2data, f) for f in filenames]\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        # set data frame index to id\n        labels_df.set_index(\"id\", inplace=True)\n        # obtain labels from data frame\n        self.labels = [labels_df.loc[filename[:-4]].values[0] for filename in filenames]\n        self.transform = transform\n        \n        \n    def __len__(self):\n        # return size of dataset\n        return len(self.full_filenames)\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":{"trusted":true},"cell_type":"code","source":"import torchvision.transforms as transforms\ndata_transformer = transforms.Compose([transforms.ToTensor()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_dir = \"../input/histopathologic-cancer-detection\"\nhisto_dataset = histoCancerDataset(data_dir, data_transformer,\"train\")\nprint(len(histo_dataset))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Next, we will load an image using the custom dataset:"},{"metadata":{"trusted":true},"cell_type":"code","source":"# load an image\nimg,label=histo_dataset[256]\nprint(img.shape,torch.min(img),torch.max(img))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We need to provide a validation dataset to track the model's performance during training. We use 20% of histo_dataset as the validation dataset and use the rest as the training dataset."},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.utils.data import random_split\nlen_histo=len(histo_dataset)\nlen_train=int(0.8*len_histo)\nlen_val=len_histo-len_train\ntrain_ds,val_ds=random_split(histo_dataset,[len_train,len_val])\nprint(\"train dataset length:\", len(train_ds))\nprint(\"validation dataset length:\", len(val_ds))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for x,y in train_ds:\n    print(x.shape,y)\n    break\nfor x,y in val_ds:\n    print(x.shape,y)\n    break\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's display a few samples from train_ds."},{"metadata":{"trusted":true},"cell_type":"code","source":"#Import the required packages:\nfrom torchvision import utils\nimport numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline\nnp.random.seed(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#helper function\ndef show(img,y,color=True):\n    # convert tensor to numpy array\n    npimg = img.numpy()\n    # Convert to H*W*C shape\n    npimg_tr=np.transpose(npimg, (1,2,0))\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))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#making grid \ngrid_size=4\nrnd_inds=np.random.randint(0,len(train_ds),grid_size)\nprint(\"image indices:\",rnd_inds)\nx_grid_train=[train_ds[i][0] for i in rnd_inds]\ny_grid_train=[train_ds[i][1] for i in rnd_inds]\nx_grid_train=utils.make_grid(x_grid_train, nrow=4, padding=2)\nprint(x_grid_train.shape)\nplt.rcParams['figure.figsize'] = (10.0, 5)\nshow(x_grid_train,y_grid_train)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Augmentation of data to trainset and other transformation "},{"metadata":{"trusted":true},"cell_type":"code","source":"train_transformer = transforms.Compose([\n    transforms.RandomHorizontalFlip(p=0.5),\n    transforms.RandomVerticalFlip(p=0.5),\n    transforms.RandomRotation(45),\n    transforms.RandomResizedCrop(96,scale=(0.8,1.0),ratio=(1.0,1.0)),\n    transforms.ToTensor()])\n#we do not distort validation dataset except for convetring it to tensor\nval_transformer = transforms.Compose([transforms.ToTensor()])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#overwrite the transform functions\ntrain_ds.transform=train_transformer\nval_ds.transform=val_transformer","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":" creating dataloaders"},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.utils.data import DataLoader\ntrain_dl = DataLoader(train_ds, batch_size=32, shuffle=True)\nval_dl = DataLoader(val_ds, batch_size=64, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# extract a batch from training data\nfor x, y in train_dl:\n    print(x.shape)\n    print(y.shape)\n    break\nfor x, y in val_dl:\n    print(x.shape)\n    print(y.shape)\n    break","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Building the CLASSIFICATION MODEL"},{"metadata":{},"cell_type":"markdown","source":"First, let's create dumb baselines for the validation dataset."},{"metadata":{"trusted":true},"cell_type":"code","source":"# get labels for validation dataset\ny_val=[y for _,y in val_ds]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def accuracy(labels, out):\n    return np.sum(out==labels)/float(len(labels))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# accuracy all zero predictions\nacc_all_zeros=accuracy(y_val,np.zeros_like(y_val))\nprint(\"accuracy all zero prediction: %.2f\" %acc_all_zeros)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# accuracy all ones predictions\nacc_all_ones=accuracy(y_val,np.ones_like(y_val))\nprint(\"accuracy all one prediction: %.2f\" %acc_all_ones)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# accuracy random predictions\nacc_random=accuracy(y_val,np.random.randint(2,size=len(y_val)))\nprint(\"accuracy random prediction: %.2f\" %acc_random)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#now the full cnn model\nimport torch.nn as nn\nimport numpy as np\nimport torch.nn.functional as F\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#helper function to give output size\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    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    if pool:\n        H_out/=pool\n        W_out/=pool\n    return int(H_out),int(W_out)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Net(nn.Module):\n    def __init__(self, params):\n        super(Net, self).__init__()\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        self.conv1 = nn.Conv2d(C_in, init_f, kernel_size=3)\n        h,w=findConv2dOutShape(H_in,W_in,self.conv1)\n        self.conv2 = nn.Conv2d(init_f, 2*init_f, kernel_size=3)\n        h,w=findConv2dOutShape(h,w,self.conv2)\n        self.conv3 = nn.Conv2d(2*init_f, 4*init_f, kernel_size=3)\n        h,w=findConv2dOutShape(h,w,self.conv3)\n        self.conv4 = nn.Conv2d(4*init_f, 8*init_f, kernel_size=3)\n        h,w=findConv2dOutShape(h,w,self.conv4)\n        # compute the flatten size\n        self.num_flatten=h*w*8*init_f\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        x = F.relu(self.conv2(x))\n        x = F.max_pool2d(x, 2, 2)\n        x = F.relu(self.conv3(x))\n        x = F.max_pool2d(x, 2, 2)\n        x = F.relu(self.conv4(x))\n        x = F.max_pool2d(x, 2, 2)\n        x = x.view(-1, self.num_flatten)\n        x = F.relu(self.fc1(x))\n        x=F.dropout(x, self.dropout_rate, training= self.training)\n        x = self.fc2(x)\n        return F.log_softmax(x, dim=1)\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dict to define 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    }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create model\ncnn_model = Net(params_model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if torch.cuda.is_available():\n    device=torch.device(\"cuda\")\n    cnn_mdel = cnn_model.to(device) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(cnn_model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pip install torchsummary","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torchsummary import summary\nsummary(cnn_model, input_size=(3, 96, 96),device=device.type)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"loss_func = nn.NLLLoss(reduction=\"sum\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch import optim\nopt = optim.Adam(cnn_model.parameters(), lr=3e-4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# get learning rate\ndef get_lr(opt):\n    for param_group in opt.param_groups:\n        return param_group['lr']\ncurrent_lr=get_lr(opt)\nprint('current lr={}'.format(current_lr))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.optim.lr_scheduler import ReduceLROnPlateau\n# define learning rate scheduler\nlr_scheduler = ReduceLROnPlateau(opt, mode='min',factor=0.5,\npatience=20,verbose=1)\nfor i in range(100):\n    lr_scheduler.step(1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Training and evaluation of the model**"},{"metadata":{"trusted":true},"cell_type":"code","source":"def metrics_batch(output, target):\n    # get output class\n    pred = output.argmax(dim=1, keepdim=True)\n    # compare output class with target class\n    corrects=pred.eq(target.view_as(pred)).sum().item()\n    return corrects","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#loss value per batch\ndef loss_batch(loss_func, output, target, opt=None):\n    loss = loss_func(output, target)\n    with torch.no_grad():\n        metric_b = metrics_batch(output,target)\n    if opt is not None:\n        opt.zero_grad()\n        loss.backward()\n        opt.step()\n    return loss.item(), metric_b","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#loss per epoch\ndef loss_epoch(model,loss_func,dataset_dl,sanity_check=False,opt=None):\n    running_loss=0.0\n    running_metric=0.0\n    len_data=len(dataset_dl.dataset)\n    \n    for xb, yb in dataset_dl:\n        # move batch to device\n        xb=xb.to(device)\n        yb=yb.to(device)\n        # get model output\n        output=model(xb)\n        # get loss per batch\n        loss_b,metric_b=loss_batch(loss_func, output, yb, opt)\n        \n        # update running loss\n        running_loss+=loss_b\n        # update running metric\n        if metric_b is not None:\n            running_metric+=metric_b\n        # break the loop in case of sanity check\n        if sanity_check is True:\n            break\n            \n    # average loss value\n    loss=running_loss/float(len_data)\n    # average metric value\n    metric=running_metric/float(len_data)\n    return loss, metric","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_val(model, params):\n    # extract model parameters\n    num_epochs=params[\"num_epochs\"]\n    loss_func=params[\"loss_func\"]\n    opt=params[\"optimizer\"]\n    train_dl=params[\"train_dl\"]\n    val_dl=params[\"val_dl\"]\n    sanity_check=params[\"sanity_check\"]\n    lr_scheduler=params[\"lr_scheduler\"]\n    path2weights=params[\"path2weights\"]\n    \n    \n    # history of loss values in each epoch\n    loss_history={\n    \"train\": [],\n    \"val\": [],\n        }\n    # history of metric values in each epoch\n    metric_history={\n    \"train\": [],\n    \"val\": [],\n        }\n    # a deep copy of weights for the best performing model\n    best_model_wts = copy.deepcopy(model.state_dict())\n    \n    # initialize best loss to a large value\n    best_loss=float('inf')\n    \n    #we will define a loop that will calculate the training loss over an epoch:\n    # main loop\n    for epoch in range(num_epochs):\n        # get current learning rate\n        current_lr=get_lr(opt)\n        print('Epoch {}/{}, current lr={}'.format(epoch, num_epochs- 1, current_lr))\n        # train model on training dataset\n        model.train()\n        train_loss,train_metric=loss_epoch(model,loss_func,train_dl,sanity_check,opt)\n        # collect loss and metric for training dataset\n        loss_history[\"train\"].append(train_loss)\n        metric_history[\"train\"].append(train_metric)\n        \n        # evaluate model on validation dataset\n        model.eval()\n        with torch.no_grad():\n            val_loss,val_metric=loss_epoch(model,loss_func,val_dl,sanity_check)\n    \n        # collect loss and metric for validation dataset\n        loss_history[\"val\"].append(val_loss)\n        metric_history[\"val\"].append(val_metric)\n    \n    \n        # store best model\n        if val_loss < best_loss:\n            best_loss = val_loss\n            best_model_wts = copy.deepcopy(model.state_dict())\n            # store weights into a local file\n            torch.save(model.state_dict(), path2weights)\n            print(\"Copied best model weights!\")\n        # learning rate schedule\n        lr_scheduler.step(val_loss)\n        if current_lr != get_lr(opt):\n            print(\"Loading best model weights!\")\n            model.load_state_dict(best_model_wts)\n        \n            \n        print(\"train loss: %.6f, dev loss: %.6f, accuracy: %.2f\"%(train_loss,val_loss,100*val_metric))\n        print(\"-\"*10)\n    # load best model weights\n    model.load_state_dict(best_model_wts)\n    return model, loss_history, metric_history\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import copy\nloss_func = nn.NLLLoss(reduction=\"sum\")\nopt = optim.Adam(cnn_model.parameters(), lr=3e-4)\nlr_scheduler = ReduceLROnPlateau(opt, mode='min',factor=0.5,\npatience=20,verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"params_train = {\n    \"num_epochs\": 100,\n    \"optimizer\": opt,\n    \"loss_func\": loss_func,\n    \"train_dl\": train_dl,\n    \"val_dl\": val_dl,\n    \"sanity_check\": True,\n    \"lr_scheduler\": lr_scheduler,\n    \"path2weights\": \"weights.pt\",\n    \n} ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"# train and validate the model\ncnn_model,loss_hist,metric_hist=train_val(cnn_model,params_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train-Validation Progress\nnum_epochs=params_train[\"num_epochs\"]\n# plot loss progress\nplt.title(\"Train-Val Loss\")\nplt.plot(range(1,num_epochs+1),loss_hist[\"train\"],label=\"train\")\nplt.plot(range(1,num_epochs+1),loss_hist[\"val\"],label=\"val\")\nplt.ylabel(\"Loss\")\nplt.xlabel(\"Training Epochs\")\nplt.legend()\nplt.show()\n# plot accuracy progress\nplt.title(\"Train-Val Accuracy\")\nplt.plot(range(1,num_epochs+1),metric_hist[\"train\"],label=\"train\")\nplt.plot(range(1,num_epochs+1),metric_hist[\"val\"],label=\"val\")\nplt.ylabel(\"Accuracy\")\nplt.xlabel(\"Training Epochs\")\nplt.legend()\nplt.grid()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Deploying the model**"},{"metadata":{"trusted":true},"cell_type":"code","source":"#First, we'll create an object of the Net class and load the stored weights into the model\n# 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}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize model\ncnn_model = Net(params_model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# load state_dict into model\n# load state_dict into model\npath2weights=\"weights.pt\"\ncnn_model.load_state_dict(torch.load(path2weights))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cnn_model.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# move model to cuda/gpu device\nif torch.cuda.is_available():\n    device = torch.device(\"cuda\")\n    cnn_model=cnn_model.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import time\ndef deploy_model(model,dataset,device,num_classes=2,sanity_check=False):\n    len_data=len(dataset)\n    # initialize output tensor on CPU: due to GPU memory limits\n    y_out=torch.zeros(len_data,num_classes)\n    # initialize ground truth on CPU: due to GPU memory limits\n    y_gt=np.zeros((len_data),dtype=\"uint8\")\n    # move model to device\n    model=model.to(device)\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).to(device))\n            elapsed=time.time()-start\n            elapsed_times.append(elapsed)\n            if sanity_check is True:\n                break\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\n            ","execution_count":null,"outputs":[]},{"metadata":{"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":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import accuracy_score\n# get predictions\ny_pred = np.argmax(y_out,axis=1)\nprint(y_pred.shape,y_gt.shape)\n# compute accuracy\nacc=accuracy_score(y_pred,y_gt)\nprint(\"accuracy: %.2f\" %acc)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Applying on ths test set**"},{"metadata":{"trusted":true},"cell_type":"code","source":"path2csv=\"./../input/histopathologic-cancer-detection/sample_submission.csv\"\nlabels_df=pd.read_csv(path2csv)\nlabels_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class histoCancerDataset_test(Dataset):\n    def __init__(self, data_dir, transform,data_type=\"train\"):\n        # path to images\n        path2data = os.path.join(data_dir,data_type)\n        # get a list of images\n        filenames = os.listdir(path2data)\n        # get the full path to images\n        self.full_filenames = [os.path.join(path2data, f) for f in filenames]\n        # labels are in a csv file named train_labels.csv\n        csv_filename=\"sample_submission.csv\"\n        path2csvLabels=os.path.join(data_dir,csv_filename)\n        labels_df=pd.read_csv(path2csvLabels)\n        # set data frame index to id\n        labels_df.set_index(\"id\", inplace=True)\n        # obtain labels from data frame\n        self.labels = [labels_df.loc[filename[:-4]].values[0] for filename in filenames]\n        self.transform = transform\n        \n        \n    def __len__(self):\n        # return size of dataset\n        return len(self.full_filenames)\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":{"trusted":true},"cell_type":"code","source":"histo_test = histoCancerDataset_test(data_dir,val_transformer,data_type=\"test\")\nprint(len(histo_test))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test_out,_=deploy_model(cnn_model,histo_test, device,sanity_check=False)\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test_pred=np.argmax(y_test_out,axis=1)\nprint(y_test_pred.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"grid_size=4\nrnd_inds=np.random.randint(0,len(histo_test),grid_size)\nprint(\"image indices:\",rnd_inds)\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)]\nx_grid_test=utils.make_grid(x_grid_test, nrow=4, padding=2)\nprint(x_grid_test.shape)\nplt.rcParams['figure.figsize'] = (10.0, 5)\nshow(x_grid_test,y_grid_test)\n","execution_count":null,"outputs":[]},{"metadata":{"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":{"trusted":true},"cell_type":"code","source":"","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}