{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport cv2\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport random\nfrom sklearn.utils import shuffle\nfrom tqdm import tqdm_notebook\ndata = pd.read_csv('/kaggle/input/train_labels.csv')\ntrain_path = '/kaggle/input/train/'\ntest_path = '/kaggle/input/test/'\ndata['label'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"def readImage(path):\n    bgr_img = cv2.imread(path)\n    b,g,r = cv2.split(bgr_img)\n    rgb_img = cv2.merge([r,g,b])\n    return rgb_img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nshuffled_data = shuffle(data)\nfig, ax = plt.subplots(2,5, figsize=(20,8))\nfig.suptitle('Histopathologic scans of lymph node sections',fontsize=20)\nfor i, idx in enumerate(shuffled_data[shuffled_data['label'] == 0]['id'][:5]):\n    path = os.path.join(train_path, idx)\n    ax[0,i].imshow(readImage(path + '.tif'))\n    box = patches.Rectangle((32,32),32,32,linewidth=4,edgecolor='b',facecolor='none', linestyle=':', capstyle='round')\n    ax[0,i].add_patch(box)\nax[0,0].set_ylabel('Negative samples', size='large')\nfor i, idx in enumerate(shuffled_data[shuffled_data['label'] == 1]['id'][:5]):\n    path = os.path.join(train_path, idx)\n    ax[1,i].imshow(readImage(path + '.tif'))\n    box = patches.Rectangle((32,32),32,32,linewidth=4,edgecolor='r',facecolor='none', linestyle=':', capstyle='round')\n    ax[1,i].add_patch(box)\nax[1,0].set_ylabel('Tumor tissue samples', size='large')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\nimport imgaug as ia\nfrom imgaug import augmenters as iaa\nimport numpy as np\nORIGINAL_SIZE = 96 \nCROP_SIZE = 90          \nRANDOM_ROTATION = 3    \nRANDOM_SHIFT = 2         \nRANDOM_BRIGHTNESS = 7  \nRANDOM_CONTRAST = 5   \nRANDOM_90_DEG_TURN = 1\ndef readCroppedImage(path, augmentations = True):\n    bgr_img = cv2.imread(path)\n    b,g,r = cv2.split(bgr_img)\n    rgb_img = cv2.merge([r,g,b])\n    if(not augmentations):\n        return rgb_img / 255\n    rotation = random.randint(-RANDOM_ROTATION,RANDOM_ROTATION)\n    if(RANDOM_90_DEG_TURN == 1):\n        rotation += random.randint(-1,1) * 90\n    M = cv2.getRotationMatrix2D((48,48),rotation,1) \n    rgb_img = cv2.warpAffine(rgb_img,M,(96,96))\n    x = random.randint(-RANDOM_SHIFT, RANDOM_SHIFT)\n    y = random.randint(-RANDOM_SHIFT, RANDOM_SHIFT)\n    start_crop = (ORIGINAL_SIZE - CROP_SIZE) // 2\n    end_crop = start_crop + CROP_SIZE\n    rgb_img = rgb_img[(start_crop + x):(end_crop + x), (start_crop + y):(end_crop + y)] / 255\n    flip_hor = bool(random.getrandbits(1))\n    flip_ver = bool(random.getrandbits(1))\n    if(flip_hor):\n        rgb_img = rgb_img[:, ::-1]\n    if(flip_ver):\n        rgb_img = rgb_img[::-1, :]\n    br = random.randint(-RANDOM_BRIGHTNESS, RANDOM_BRIGHTNESS) / 100.\n    rgb_img = rgb_img + br\n    cr = 1.0 + random.randint(-RANDOM_CONTRAST, RANDOM_CONTRAST) / 100.\n    rgb_img = rgb_img * cr\n    rgb_img = np.clip(rgb_img, 0, 1.0)\n    return rgb_img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(2,5, figsize=(20,8))\nfig.suptitle('Cropped histopathologic scans of lymph node sections',fontsize=20)\nfor i, idx in enumerate(shuffled_data[shuffled_data['label'] == 0]['id'][:5]):\n    path = os.path.join(train_path, idx)\n    ax[0,i].imshow(readCroppedImage(path + '.tif'))\nax[0,0].set_ylabel('Negative samples', size='large')\nfor i, idx in enumerate(shuffled_data[shuffled_data['label'] == 1]['id'][:5]):\n    path = os.path.join(train_path, idx)\n    ax[1,i].imshow(readCroppedImage(path + '.tif'))\nax[1,0].set_ylabel('Tumor tissue samples', size='large')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndark_th = 10 / 255      \nbright_th = 245 / 255   \ntoo_dark_idx = []\ntoo_bright_idx = []\nx_tot = np.zeros(3)\nx2_tot = np.zeros(3)\ncounted_ones = 0\nfor i, idx in tqdm_notebook(enumerate(shuffled_data['id']), 'computing statistics...(220025 it total)'):\n    path = os.path.join(train_path, idx)\n    imagearray = readCroppedImage(path + '.tif', augmentations = False).reshape(-1,3)\n    if(imagearray.max() < dark_th):\n        too_dark_idx.append(idx)\n        continue \n    if(imagearray.min() > bright_th):\n        too_bright_idx.append(idx)\n        continue \n    x_tot += imagearray.mean(axis=0)\n    x2_tot += (imagearray**2).mean(axis=0)\n    counted_ones += 1\nchannel_avr = x_tot/counted_ones\nchannel_std = np.sqrt(x2_tot/counted_ones - channel_avr**2)\nchannel_avr,channel_std\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('There was {0} extremely dark image'.format(len(too_dark_idx)))\nprint('and {0} extremely bright images'.format(len(too_bright_idx)))\nprint('Dark one:')\nprint(too_dark_idx)\nprint('Bright ones:')\nprint(too_bright_idx)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(2,6, figsize=(25,9))\nfig.suptitle('Almost completely black or white images',fontsize=20)\ni = 0\nfor idx in np.asarray(too_dark_idx)[:min(6, len(too_dark_idx))]:\n    lbl = shuffled_data[shuffled_data['id'] == idx]['label'].values[0]\n    path = os.path.join(train_path, idx)\n    ax[0,i].imshow(readCroppedImage(path + '.tif', augmentations = False))\n    ax[0,i].set_title(idx + '\\n label=' + str(lbl), fontsize = 8)\n    i += 1\nax[0,0].set_ylabel('Extremely dark images', size='large')\nfor j in range(min(6, len(too_dark_idx)), 6):\n    ax[0,j].axis('off') \ni = 0\nfor idx in np.asarray(too_bright_idx)[:min(6, len(too_bright_idx))]:\n    lbl = shuffled_data[shuffled_data['id'] == idx]['label'].values[0]\n    path = os.path.join(train_path, idx)\n    ax[1,i].imshow(readCroppedImage(path + '.tif', augmentations = False))\n    ax[1,i].set_title(idx + '\\n label=' + str(lbl), fontsize = 8)\n    i += 1\nax[1,0].set_ylabel('Extremely bright images', size='large')\nfor j in range(min(6, len(too_bright_idx)), 6):\n    ax[1,j].axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_df = data.set_index('id')\ntrain_names = train_df.index.values\ntrain_labels = np.asarray(train_df['label'].values)\ntr_n, tr_idx, val_n, val_idx = train_test_split(train_names, range(len(train_names)), test_size=0.2, stratify=train_labels, random_state=123)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai import *\nfrom fastai.vision import *\nfrom torchvision.models import *  \narch = squeezenet1_1                 \nBATCH_SIZE = 128                    \nsz = CROP_SIZE                     \nMODEL_PATH = str(arch).split()[1]   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ntrain_dict = {'name': train_path + train_names, 'label': train_labels}\ndf = pd.DataFrame(data=train_dict)\ntest_names = []\nfor f in os.listdir(test_path):\n    test_names.append(test_path + f)\ndf_test = pd.DataFrame(np.asarray(test_names), columns=['name'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nclass MyImageItemList(ImageList):\n    def open(self, fn:PathOrStr)->Image:\n        img = readCroppedImage(fn.replace('/./','').replace('//','/'))\n        return vision.Image(px=pil2tensor(img, np.float32))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nimgDataBunch = (MyImageItemList.from_df(path='/', df=df, suffix='.tif')\n        .split_by_idx(val_idx)\n        .label_from_df(cols='label')\n        .add_test(MyImageItemList.from_df(path='/', df=df_test))\n        .transform(tfms=[[],[]], size=sz)\n        .databunch(bs=BATCH_SIZE)\n        .normalize([tensor([0.702447, 0.546243, 0.696453]), tensor([0.238893, 0.282094, 0.216251])])\n       )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"imgDataBunch.show_batch(rows=2, figsize=(4,4))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef getLearner():\n    return create_cnn(imgDataBunch, arch, pretrained=True, path='.', metrics=accuracy, ps=0.5, callback_fns=ShowGraph)\nlearner = getLearner()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lrs = []\nlosses = []\nwds = []\niter_count = 600\n\n# WEIGHT DECAY = 1e-6\nlearner.lr_find(wd=1e-6, num_it=iter_count)\nlrs.append(learner.recorder.lrs)\nlosses.append(learner.recorder.losses)\nwds.append('1e-6')\nlearner = getLearner() #reset learner - this gets more consistent starting conditions\n\n# WEIGHT DECAY = 1e-4\nlearner.lr_find(wd=1e-4, num_it=iter_count)\nlrs.append(learner.recorder.lrs)\nlosses.append(learner.recorder.losses)\nwds.append('1e-4')\nlearner = getLearner() #reset learner - this gets more consistent starting conditions\n\n# WEIGHT DECAY = 1e-2\nlearner.lr_find(wd=1e-2, num_it=iter_count)\nlrs.append(learner.recorder.lrs)\nlosses.append(learner.recorder.losses)\nwds.append('1e-2')\nlearner = getLearner() #reset learner","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plot weight decays\n_, ax = plt.subplots(1,1)\nmin_y = 0.5\nmax_y = 0.55\nfor i in range(len(losses)):\n    ax.plot(lrs[i], losses[i])\n    min_y = min(np.asarray(losses[i]).min(), min_y)\nax.set_ylabel(\"Loss\")\nax.set_xlabel(\"Learning Rate\")\nax.set_xscale('log')\n#ax ranges may need some tuning with different model architectures \nax.set_xlim((1e-3,3e-1))\nax.set_ylim((min_y - 0.02,max_y))\nax.legend(wds)\nax.xaxis.set_major_formatter(plt.FormatStrFormatter('%.0e'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_lr = 2e-2\nwd = 1e-4\n# 1cycle policy\nlearner.fit_one_cycle(cyc_len=8, max_lr=max_lr, wd=wd)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learner.recorder.plot_lr()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learner.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp = ClassificationInterpretation.from_learner(learner)\ninterp.plot_confusion_matrix(title='Confusion matrix')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learner.save(MODEL_PATH + '_stage1')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# load the baseline model\nlearner.load(MODEL_PATH + '_stage1')\n\n# unfreeze and run learning rate finder again\nlearner.unfreeze()\nlearner.lr_find(wd=wd)\n\n# plot learning rate finder results\nlearner.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learner.fit_one_cycle(cyc_len=12, max_lr=slice(4e-5,4e-4))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learner.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interp = ClassificationInterpretation.from_learner(learner)\ninterp.plot_confusion_matrix(title='Confusion matrix')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learner.save(MODEL_PATH + '_stage2')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds,y, loss = learner.get_preds(with_loss=True)\n# get accuracy\nacc = accuracy(preds, y)\nprint('The accuracy is {0} %.'.format(acc))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from random import randint\n\ndef plot_overview(interp:ClassificationInterpretation, classes=['Negative','Tumor']):\n    # top losses will return all validation losses and indexes sorted by the largest first\n    tl_val,tl_idx = interp.top_losses()\n    #classes = interp.data.classes\n    fig, ax = plt.subplots(3,4, figsize=(16,12))\n    fig.suptitle('Predicted / Actual / Loss / Probability',fontsize=20)\n    # Random\n    for i in range(4):\n        random_index = randint(0,len(tl_idx))\n        idx = tl_idx[random_index]\n        im,cl = interp.data.dl(DatasetType.Valid).dataset[idx]\n        im = image2np(im.data)\n        cl = int(cl)\n        ax[0,i].imshow(im)\n        ax[0,i].set_xticks([])\n        ax[0,i].set_yticks([])\n        ax[0,i].set_title(f'{classes[interp.pred_class[idx]]} / {classes[cl]} / {interp.losses[idx]:.2f} / {interp.probs[idx][cl]:.2f}')\n    ax[0,0].set_ylabel('Random samples', fontsize=16, rotation=0, labelpad=80)\n    # Most incorrect or top losses\n    for i in range(4):\n        idx = tl_idx[i]\n        im,cl = interp.data.dl(DatasetType.Valid).dataset[idx]\n        cl = int(cl)\n        im = image2np(im.data)\n        ax[1,i].imshow(im)\n        ax[1,i].set_xticks([])\n        ax[1,i].set_yticks([])\n        ax[1,i].set_title(f'{classes[interp.pred_class[idx]]} / {classes[cl]} / {interp.losses[idx]:.2f} / {interp.probs[idx][cl]:.2f}')\n    ax[1,0].set_ylabel('Most incorrect\\nsamples', fontsize=16, rotation=0, labelpad=80)\n    # Most correct or least losses\n    for i in range(4):\n        idx = tl_idx[len(tl_idx) - i - 1]\n        im,cl = interp.data.dl(DatasetType.Valid).dataset[idx]\n        cl = int(cl)\n        im = image2np(im.data)\n        ax[2,i].imshow(im)\n        ax[2,i].set_xticks([])\n        ax[2,i].set_yticks([])\n        ax[2,i].set_title(f'{classes[interp.pred_class[idx]]} / {classes[cl]} / {interp.losses[idx]:.2f} / {interp.probs[idx][cl]:.2f}')\n    ax[2,0].set_ylabel('Most correct\\nsamples', fontsize=16, rotation=0, labelpad=80)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_overview(interp, ['Negative','Tumor'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai.callbacks.hooks import *\n\n# hook into forward pass\ndef hooked_backward(m, oneBatch, cat):\n    # we hook into the convolutional part = m[0] of the model\n    with hook_output(m[0]) as hook_a: \n        with hook_output(m[0], grad=True) as hook_g:\n            preds = m(oneBatch)\n            preds[0,int(cat)].backward()\n    return hook_a,hook_g","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# We can create a utility function for getting a validation image with an activation map\ndef getHeatmap(val_index):\n    \"\"\"Returns the validation set image and the activation map\"\"\"\n    # this gets the model\n    m = learner.model.eval()\n    tensorImg,cl = imgDataBunch.valid_ds[val_index]\n    # create a batch from the one image\n    oneBatch,_ = imgDataBunch.one_item(tensorImg)\n    oneBatch_im = vision.Image(imgDataBunch.denorm(oneBatch)[0])\n    # convert batch tensor image to grayscale image with opencv\n    cvIm = cv2.cvtColor(image2np(oneBatch_im.data), cv2.COLOR_RGB2GRAY)\n    # attach hooks\n    hook_a,hook_g = hooked_backward(m, oneBatch, cl)\n    # get convolutional activations and average from channels\n    acts = hook_a.stored[0].cpu()\n    #avg_acts = acts.mean(0)\n\n    # Grad-CAM\n    grad = hook_g.stored[0][0].cpu()\n    grad_chan = grad.mean(1).mean(1)\n    grad.shape,grad_chan.shape\n    mult = (acts*grad_chan[...,None,None]).mean(0)\n    return mult, cvIm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Then, modify our plotting func a bit\ndef plot_heatmap_overview(interp:ClassificationInterpretation, classes=['Negative','Tumor']):\n    # top losses will return all validation losses and indexes sorted by the largest first\n    tl_val,tl_idx = interp.top_losses()\n    #classes = interp.data.classes\n    fig, ax = plt.subplots(3,4, figsize=(16,12))\n    fig.suptitle('Grad-CAM\\nPredicted / Actual / Loss / Probability',fontsize=20)\n    # Random\n    for i in range(4):\n        random_index = randint(0,len(tl_idx))\n        idx = tl_idx[random_index]\n        act, im = getHeatmap(idx)\n        H,W = im.shape\n        _,cl = interp.data.dl(DatasetType.Valid).dataset[idx]\n        cl = int(cl)\n        ax[0,i].imshow(im)\n        ax[0,i].imshow(im, cmap=plt.cm.gray)\n        ax[0,i].imshow(act, alpha=0.5, extent=(0,H,W,0),\n              interpolation='bilinear', cmap='inferno')\n        ax[0,i].set_xticks([])\n        ax[0,i].set_yticks([])\n        ax[0,i].set_title(f'{classes[interp.pred_class[idx]]} / {classes[cl]} / {interp.losses[idx]:.2f} / {interp.probs[idx][cl]:.2f}')\n    ax[0,0].set_ylabel('Random samples', fontsize=16, rotation=0, labelpad=80)\n    # Most incorrect or top losses\n    for i in range(4):\n        idx = tl_idx[i]\n        act, im = getHeatmap(idx)\n        H,W = im.shape\n        _,cl = interp.data.dl(DatasetType.Valid).dataset[idx]\n        cl = int(cl)\n        ax[1,i].imshow(im)\n        ax[1,i].imshow(im, cmap=plt.cm.gray)\n        ax[1,i].imshow(act, alpha=0.5, extent=(0,H,W,0),\n              interpolation='bilinear', cmap='inferno')\n        ax[1,i].set_xticks([])\n        ax[1,i].set_yticks([])\n        ax[1,i].set_title(f'{classes[interp.pred_class[idx]]} / {classes[cl]} / {interp.losses[idx]:.2f} / {interp.probs[idx][cl]:.2f}')\n    ax[1,0].set_ylabel('Most incorrect\\nsamples', fontsize=16, rotation=0, labelpad=80)\n    # Most correct or least losses\n    for i in range(4):\n        idx = tl_idx[len(tl_idx) - i - 1]\n        act, im = getHeatmap(idx)\n        H,W = im.shape\n        _,cl = interp.data.dl(DatasetType.Valid).dataset[idx]\n        cl = int(cl)\n        ax[2,i].imshow(im)\n        ax[2,i].imshow(im, cmap=plt.cm.gray)\n        ax[2,i].imshow(act, alpha=0.5, extent=(0,H,W,0),\n              interpolation='bilinear', cmap='inferno')\n        ax[2,i].set_xticks([])\n        ax[2,i].set_yticks([])\n        ax[2,i].set_title(f'{classes[interp.pred_class[idx]]} / {classes[cl]} / {interp.losses[idx]:.2f} / {interp.probs[idx][cl]:.2f}')\n    ax[2,0].set_ylabel('Most correct\\nsamples', fontsize=16, rotation=0, labelpad=80)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_heatmap_overview(interp, ['Negative','Tumor'])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import roc_curve, auc\n# probs from log preds\nprobs = np.exp(preds[:,1])\n# Compute ROC curve\nfpr, tpr, thresholds = roc_curve(y, probs, pos_label=1)\n\n# Compute ROC area\nroc_auc = auc(fpr, tpr)\nprint('ROC area is {0}'.format(roc_auc))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure()\nplt.plot(fpr, tpr, color='darkorange', label='ROC curve (area = %0.2f)' % roc_auc)\nplt.plot([0, 1], [0, 1], color='navy', linestyle='--')\nplt.xlim([-0.01, 1.0])\nplt.ylim([0.0, 1.01])\nplt.xlabel('False Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.title('Receiver operating characteristic')\nplt.legend(loc=\"lower right\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# make sure we have the best performing model stage loaded\nlearner.load(MODEL_PATH + '_stage2')\n\n# Fastai has a function for this but we don't want the additional augmentations it does (our image loader has augmentations) so we just use the get_preds\n#preds_test,y_test=learner.TTA(ds_type=DatasetType.Test)\n\n# We do a fair number of iterations to cover different combinations of flips and rotations.\n# The predictions are then averaged.\nn_aug = 12\npreds_n_avg = np.zeros((len(learner.data.test_ds.items),2))\nfor n in tqdm_notebook(range(n_aug), 'Running TTA...'):\n    preds,y = learner.get_preds(ds_type=DatasetType.Test, with_loss=False)\n    preds_n_avg = np.sum([preds_n_avg, preds.numpy()], axis=0)\npreds_n_avg = preds_n_avg / n_aug","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Negative and Tumor Probabilities: ' + str(preds_n_avg[0]))\ntumor_preds = preds_n_avg[:, 1]\nprint('Tumor probability: ' + str(tumor_preds[0]))\n# If we wanted to get the predicted class, argmax would get the index of the max\nclass_preds = np.argmax(preds_n_avg, axis=1)\nclasses = ['Negative','Tumor']\nprint('Class prediction: ' + classes[class_preds[0]])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# get test id's from the sample_submission.csv and keep their original order\nSAMPLE_SUB = '/kaggle/input/sample_submission.csv'\nsample_df = pd.read_csv(SAMPLE_SUB)\nsample_list = list(sample_df.id)\n\n# List of tumor preds. \n# These are in the order of our test dataset and not necessarily in the same order as in sample_submission\npred_list = [p for p in tumor_preds]\n\n# To know the id's, we create a dict of id:pred\npred_dic = dict((key, value) for (key, value) in zip(learner.data.test_ds.items, pred_list))\n\n# Now, we can create a new list with the same order as in sample_submission\npred_list_cor = [pred_dic['///kaggle/input/test/' + id + '.tif'] for id in sample_list]\n\n# Next, a Pandas dataframe with id and label columns.\ndf_sub = pd.DataFrame({'id':sample_list,'label':pred_list_cor})\n\n# Export to csv\ndf_sub.to_csv('{0}_submission.csv'.format(MODEL_PATH), header=True, index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_sub.head(10)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}