{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Prostate cANcer graDe Assessment (PANDA) Challenge\n### Prostate cancer diagnosis using the Gleason grading system","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:01.058913Z","iopub.status.busy":"2020-08-21T17:34:01.058051Z","iopub.status.idle":"2020-08-21T17:34:01.060973Z","shell.execute_reply":"2020-08-21T17:34:01.060371Z"},"papermill":{"duration":0.022572,"end_time":"2020-08-21T17:34:01.061077","exception":false,"start_time":"2020-08-21T17:34:01.038505","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import sys\nsys.path = [\n    '../input/efficientnet-pytorch/EfficientNet-PyTorch/EfficientNet-PyTorch-master',\n] + sys.path","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !pip install torchsummary","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2020-08-21T17:34:01.096215Z","iopub.status.busy":"2020-08-21T17:34:01.095524Z","iopub.status.idle":"2020-08-21T17:34:05.309748Z","shell.execute_reply":"2020-08-21T17:34:05.310544Z"},"papermill":{"duration":4.236212,"end_time":"2020-08-21T17:34:05.310778","exception":false,"start_time":"2020-08-21T17:34:01.074566","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from fastai import *\nfrom fastai.vision import *\nfrom fastai.callbacks.hooks import *\nfrom fastai.callbacks import *\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import cohen_kappa_score,confusion_matrix\nimport matplotlib.image as image\nfrom tqdm.notebook import tqdm\nimport os\nimport gc\nimport zipfile\nimport openslide\nimport cv2\nimport skimage.io as sk\nimport warnings\nimport albumentations as A\nfrom torchvision import transforms\n# from torchsummary import summary\nfrom sys import getsizeof\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.365955Z","iopub.status.busy":"2020-08-21T17:34:05.364112Z","iopub.status.idle":"2020-08-21T17:34:05.366698Z","shell.execute_reply":"2020-08-21T17:34:05.367196Z"},"papermill":{"duration":0.036473,"end_time":"2020-08-21T17:34:05.367325","exception":false,"start_time":"2020-08-21T17:34:05.330852","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"device = torch.device('cuda')","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.39986Z","iopub.status.busy":"2020-08-21T17:34:05.399219Z","iopub.status.idle":"2020-08-21T17:34:05.403326Z","shell.execute_reply":"2020-08-21T17:34:05.402861Z"},"papermill":{"duration":0.021456,"end_time":"2020-08-21T17:34:05.403422","exception":false,"start_time":"2020-08-21T17:34:05.381966","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"tile_size = 256\nsz = image_size = 256\nN = n_tiles = 36\nbatch_size = 8\nnum_workers = 4\nTRAIN = '/kaggle/input/prostate-cancer-grade-assessment/train_images/'","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.433758Z","iopub.status.busy":"2020-08-21T17:34:05.433171Z","iopub.status.idle":"2020-08-21T17:34:05.437418Z","shell.execute_reply":"2020-08-21T17:34:05.436914Z"},"papermill":{"duration":0.020607,"end_time":"2020-08-21T17:34:05.437508","exception":false,"start_time":"2020-08-21T17:34:05.416901","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"path1 = Path('/kaggle/input/panda-36-tiles')","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.469375Z","iopub.status.busy":"2020-08-21T17:34:05.468615Z","iopub.status.idle":"2020-08-21T17:34:05.554366Z","shell.execute_reply":"2020-08-21T17:34:05.553834Z"},"papermill":{"duration":0.103169,"end_time":"2020-08-21T17:34:05.554506","exception":false,"start_time":"2020-08-21T17:34:05.451337","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"sld = os.listdir(TRAIN)\nsld = [x[:-5] for x in sld]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_duplicates = pd.read_csv('../input/duplicates-panda/duplicates.csv')\n# df_duplicates.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"duplicate_files = df_duplicates['file2'].tolist()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.589759Z","iopub.status.busy":"2020-08-21T17:34:05.58913Z","iopub.status.idle":"2020-08-21T17:34:05.625919Z","shell.execute_reply":"2020-08-21T17:34:05.625419Z"},"papermill":{"duration":0.057221,"end_time":"2020-08-21T17:34:05.626021","exception":false,"start_time":"2020-08-21T17:34:05.5688","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/prostate-cancer-grade-assessment/train.csv')\ndf = df[df['image_id'].isin(sld)]\ndf = df[~df['image_id'].isin(duplicate_files)]\ndf.columns = ['fn', 'data_provider', 'isup_grade', 'gleason_score']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wsi_aug = A.Compose([\n    A.RandomCrop(height=10, width=10, p=0.2),\n    A.Rotate(limit=5, p=0.2)\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tile_aug = A.Compose([A.OneOf([\n                            A.RGBShift(p=1),\n                            A.RandomGamma(p=1),\n                        ], p=0.5),\n                        A.RandomBrightnessContrast(p=0.7),\n                        A.OneOf([\n                            A.RandomRotate90(p=1),\n                            A.Flip(p=1),\n                            A.Rotate(limit=10, border_mode=0, value=(255, 255, 255), p=1),\n                            A.ShiftScaleRotate(shift_limit=0.15, scale_limit=0.1, rotate_limit=10, border_mode=0, value=(255, 255, 255), p=1),\n                        ], p=0.25),\n                        A.OneOf([\n                            A.Cutout(num_holes=50, max_h_size=10, max_w_size=10, fill_value=0, p=1),\n                            A.Cutout(num_holes=70, max_h_size=7, max_w_size=7, fill_value=0, p=1),\n                            A.Cutout(num_holes=100, max_h_size=5, max_w_size=5, fill_value=0, p=1),\n                        ], p=0.2)])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Stratified Kfold","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.662016Z","iopub.status.busy":"2020-08-21T17:34:05.6614Z","iopub.status.idle":"2020-08-21T17:34:05.677578Z","shell.execute_reply":"2020-08-21T17:34:05.676814Z"},"papermill":{"duration":0.037881,"end_time":"2020-08-21T17:34:05.677691","exception":false,"start_time":"2020-08-21T17:34:05.63981","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"df['kfold'] = -1\ndf = df.sample(frac=1.,random_state=2020).reset_index(drop=True)\nkf = StratifiedKFold(n_splits=5)\ny = df.isup_grade.values\nfor f,(t_,v_) in enumerate(kf.split(X=df,y=y)):\n    df.loc[v_,'kfold'] = f","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.714828Z","iopub.status.busy":"2020-08-21T17:34:05.71424Z","iopub.status.idle":"2020-08-21T17:34:05.725201Z","shell.execute_reply":"2020-08-21T17:34:05.725782Z"},"papermill":{"duration":0.034157,"end_time":"2020-08-21T17:34:05.725892","exception":false,"start_time":"2020-08-21T17:34:05.691735","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"# df.head()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:05.76034Z","iopub.status.busy":"2020-08-21T17:34:05.759652Z","iopub.status.idle":"2020-08-21T17:34:06.068086Z","shell.execute_reply":"2020-08-21T17:34:06.067461Z"},"papermill":{"duration":0.327432,"end_time":"2020-08-21T17:34:06.068223","exception":false,"start_time":"2020-08-21T17:34:05.740791","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.countplot(x=df[df.kfold==1].isup_grade);\nplt.title('Fold - 1: Images count');","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.015963,"end_time":"2020-08-21T17:34:06.100213","exception":false,"start_time":"2020-08-21T17:34:06.08425","status":"completed"},"tags":[]},"cell_type":"markdown","source":"# Data Processing for fastai \n* We have 2 options either we write a custom Imagelist function or\n* We first convert all images first then use then As we like.\n\nLater will take time at first but will Speed up process later. As Fastai datablock will not have to process large **.tiff** files every time","execution_count":null},{"metadata":{"papermill":{"duration":0.015483,"end_time":"2020-08-21T17:34:06.131748","exception":false,"start_time":"2020-08-21T17:34:06.116265","status":"completed"},"tags":[]},"cell_type":"markdown","source":"* I have converted the tiff files they can be found [**here**](https://www.kaggle.com/ianmoone0617/panda-36-tiles-resize)\n* Lets start with Custum ImageItem List first","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:06.179204Z","iopub.status.busy":"2020-08-21T17:34:06.172179Z","iopub.status.idle":"2020-08-21T17:34:06.181833Z","shell.execute_reply":"2020-08-21T17:34:06.181336Z"},"papermill":{"duration":0.033041,"end_time":"2020-08-21T17:34:06.181935","exception":false,"start_time":"2020-08-21T17:34:06.148894","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"def get_tiles(img, mode=0):\n        result = []\n        h, w, c = img.shape\n        pad_h = (tile_size - h % tile_size) % tile_size + ((tile_size * mode) // 2)\n        pad_w = (tile_size - w % tile_size) % tile_size + ((tile_size * mode) // 2)\n        img2 = np.pad(img,[[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2,pad_w - pad_w//2], [0,0]], constant_values=1)\n        img3 = img2.reshape(\n            img2.shape[0] // tile_size,\n            tile_size,\n            img2.shape[1] // tile_size,\n            tile_size,\n            3\n        )\n\n        img3 = img3.transpose(0,2,1,3,4).reshape(-1, tile_size, tile_size,3)\n        if len(img) < n_tiles:\n            img3 = np.pad(img3,[[0,n_tiles-len(img3)],[0,0],[0,0],[0,0]], constant_values=1)\n        idxs = np.argsort(img3.reshape(img3.shape[0],-1).sum(-1))[:n_tiles]\n        img3 = img3[idxs]\n        for i in range(len(img3)):\n            result.append({'img':1 - img3[i], 'idx':i})\n        return result","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Custom Fastai TiffImageList to Directly Process Slides","execution_count":null},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.execute_input":"2020-08-21T17:34:06.223535Z","iopub.status.busy":"2020-08-21T17:34:06.222656Z","iopub.status.idle":"2020-08-21T17:34:06.225532Z","shell.execute_reply":"2020-08-21T17:34:06.225066Z"},"papermill":{"duration":0.028375,"end_time":"2020-08-21T17:34:06.225629","exception":false,"start_time":"2020-08-21T17:34:06.197254","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"class TiffImageItemList(ImageList):\n    def open(self,fn):\n        path = '/kaggle/input/prostate-cancer-grade-assessment/train_images/'\n        fl = path + str(fn)+'.tiff'\n        img = sk.MultiImage(fl)[1]\n        img = wsi_aug(**{'image':img})['image']\n        res = get_tiles(img)\n        imgs = []\n        for i in range(36):\n            im = res[i%len(res)]['img']\n            im = tile_aug(**{'image':im})['image']\n            imgs.append(im)\n        #imgs = np.array(imgs)\n        imgs = [torch.tensor(x) for x in imgs]\n        imgs = torch.div(imgs, 255.0)\n#         final_image = np.concatenate(np.array([np.concatenate(imgs[j:j+6],axis=1).astype(np.uint8) for j in range(0,36,6)]),axis=0)\n#         final_image = cv2.resize(final_image, dsize=(512, 512), interpolation=cv2.INTER_CUBIC)\n        \n#         return vision.Image(pil2tensor(final_image,np.float32).div_(255))\n        return imgs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mean, std = imagenet_stats\nmean = 1.0 - torch.tensor(mean)\nstd = 1.0 - torch.tensor(std)\ndef open_image(fn:PathOrStr, div:bool=True, convert_mode:str='RGB', cls:type=Image,\n        after_open:Callable=None)->Image:\n    with warnings.catch_warnings():\n        warnings.simplefilter(\"ignore\", UserWarning) # EXIF warning from TiffPlugin\n        x = sk.MultiImage(fn)[1]\n        trans = transforms.ToPILImage()\n        x = trans(x).convert(convert_mode)\n#         x = PIL.Image.open(fn).convert(convert_mode)\n    if after_open: x = after_open(x)\n    x = pil2tensor(x,np.float32)\n    if div: x.div_(255)\n    return x #invert image for zero padding\n\nclass MImage(ItemBase):\n    def __init__(self, imgs):\n        self.obj, self.data = \\\n          (imgs), [(imgs[i].data - mean[...,None,None])/std[...,None,None] for i in range(len(imgs))]\n    \n    def apply_tfms(self, tfms,*args, **kwargs):\n        for i in range(len(self.obj)):\n            self.obj[i] = self.obj[i].apply_tfms(tfms, *args, **kwargs)\n            self.data[i] = (self.obj[i].data - mean[...,None,None])/std[...,None,None]\n        return self\n    \n    def __repr__(self): return f'{self.__class__.__name__} {img.shape for img in self.obj}'\n    def to_one(self):\n        img = torch.stack(self.data,1)\n        img = img.view(3,-1,N,sz,sz).permute(0,1,3,2,4).contiguous().view(3,-1,sz*N)\n        return Image(1.0 - (mean[...,None,None]+img*std[...,None,None]))\n\nclass MImageItemList(ImageList):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n    \n    def __len__(self)->int: return len(self.items) or 1 \n    \n    def get(self, i):\n        fn = Path(self.items[i])\n#         fnames = [Path(str(fn)+'_'+str(i)+'.png')for i in range(N)]\n        fname = TRAIN + str(fn)+ '.tiff'\n        imgs = open_image(fname, convert_mode=self.convert_mode, after_open=self.after_open)\n        imgs = imgs.permute(1, 2, 0).numpy()\n        res = get_tiles(imgs)\n        imgs = [Image(torch.tensor(x['img']).permute(2, 0, 1)) for x in res]\n#         print(imgs)\n        return MImage(imgs)\n\n    def reconstruct(self, t):\n        return MImage([mean[...,None,None]+_t*std[...,None,None] for _t in t])\n    \n    def show_xys(self, xs, ys, figsize:Tuple[int,int]=(300,50), **kwargs):\n        rows = min(len(xs),8)\n        fig, axs = plt.subplots(rows,1,figsize=figsize)\n        for i, ax in enumerate(axs.flatten() if rows > 1 else [axs]):\n            xs[i].to_one().show(ax=ax, y=ys[i], **kwargs)\n        plt.tight_layout()\n        \n\n#collate function to combine multiple images into one tensor\ndef MImage_collate(batch:ItemsList)->Tensor:\n    result = torch.utils.data.dataloader.default_collate(to_data(batch))\n    if isinstance(result[0],list):\n        result = [torch.stack(result[0],1),result[1]]\n    return result","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# x = sk.MultiImage('../input/prostate-cancer-grade-assessment/train_images/0005f7aaab2800f6170c399693a96917.tiff')[1]\n# trans = transforms.ToPILImage()\n# x = trans(x).convert('RGB')\n# x = pil2tensor(x,np.float32)\n# x.div_(255)\n# z = x #invert image for zero padding\n# img = z.permute(1, 2, 0).numpy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# mode=0\n# result = []\n# h, w, c = img.shape\n# pad_h = (tile_size - h % tile_size) % tile_size + ((tile_size * mode) // 2)\n# pad_w = (tile_size - w % tile_size) % tile_size + ((tile_size * mode) // 2)\n# img2 = np.pad(img,[[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2,pad_w - pad_w//2], [0,0]], constant_values=1)\n# img3 = img2.reshape(\n#     img2.shape[0] // tile_size,\n#     tile_size,\n#     img2.shape[1] // tile_size,\n#     tile_size,\n#     3\n# )\n\n# img3 = img3.transpose(0,2,1,3,4).reshape(-1, tile_size, tile_size,3)\n# if len(img) < n_tiles:\n#     img3 = np.pad(img3,[[0,n_tiles-len(img3)],[0,0],[0,0],[0,0]], constant_values=1)\n# idxs = np.argsort(img3.reshape(img3.shape[0],-1).sum(-1))[:n_tiles]\n# img3 = img3[idxs]\n# for i in range(len(img3)):\n#     result.append({'img':1 - img3[i], 'idx':i})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(6, 6, figsize = (22, 22))\nfor i,j in enumerate(ax.flatten()):\n    j.imshow(result[i]['img'])","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.016246,"end_time":"2020-08-21T17:34:06.258382","exception":false,"start_time":"2020-08-21T17:34:06.242136","status":"completed"},"tags":[]},"cell_type":"markdown","source":"* Train and validation split","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:06.295638Z","iopub.status.busy":"2020-08-21T17:34:06.294845Z","iopub.status.idle":"2020-08-21T17:34:06.314335Z","shell.execute_reply":"2020-08-21T17:34:06.313866Z"},"papermill":{"duration":0.040421,"end_time":"2020-08-21T17:34:06.314429","exception":false,"start_time":"2020-08-21T17:34:06.274008","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"trn_idx,val_idx = list(df[df.kfold!=4].index),list(df[df.kfold==4].index)\nrandom.shuffle(trn_idx)\nrandom.shuffle(val_idx)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.01557,"end_time":"2020-08-21T17:34:06.34548","exception":false,"start_time":"2020-08-21T17:34:06.32991","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## DataBunch of Custom TiffImageItemList ","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:06.386871Z","iopub.status.busy":"2020-08-21T17:34:06.38593Z","iopub.status.idle":"2020-08-21T17:34:24.931517Z","shell.execute_reply":"2020-08-21T17:34:24.930955Z"},"papermill":{"duration":18.570109,"end_time":"2020-08-21T17:34:24.931655","exception":false,"start_time":"2020-08-21T17:34:06.361546","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"data = (MImageItemList.from_df(df,path='',cols='fn')\n                          .split_by_idxs(trn_idx,val_idx)\n                          .label_from_df(cols='isup_grade')\n                          .transform(get_transforms(flip_vert=True,max_rotate=15),size=sz,padding_mode='zeros')\n                          .databunch(num_workers=4,bs=batch_size)\n#                           .normalize(imagenet_stats)\n       )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.show_batch()","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.020047,"end_time":"2020-08-21T17:34:50.565161","exception":false,"start_time":"2020-08-21T17:34:50.545114","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## Databunch of Processed Images: Using fastai's own ImageList","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:50.616659Z","iopub.status.busy":"2020-08-21T17:34:50.616079Z","iopub.status.idle":"2020-08-21T17:34:51.473828Z","shell.execute_reply":"2020-08-21T17:34:51.472846Z"},"papermill":{"duration":0.888422,"end_time":"2020-08-21T17:34:51.473957","exception":false,"start_time":"2020-08-21T17:34:50.585535","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"# stats = ([0.785946], [0.45007266])\n# data_img = (ImageList.from_df(df,path1,folder='.',suffix='.png',cols='fn')\n#                 .split_by_idxs(trn_idx,val_idx)\n#                 .label_from_df(cols='isup_grade',)\n#                 .transform(get_transforms(do_flip=True), size=300)\n#                 .databunch(bs=batch_size).normalize(imagenet_stats))","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:51.520115Z","iopub.status.busy":"2020-08-21T17:34:51.519502Z","iopub.status.idle":"2020-08-21T17:34:52.935755Z","shell.execute_reply":"2020-08-21T17:34:52.936219Z"},"papermill":{"duration":1.441746,"end_time":"2020-08-21T17:34:52.936391","exception":false,"start_time":"2020-08-21T17:34:51.494645","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"# data_img.show_batch(rows=3,figsize=(20,8),seed=2020)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.000772Z","iopub.status.busy":"2020-08-21T17:34:52.999954Z","iopub.status.idle":"2020-08-21T17:34:53.021902Z","shell.execute_reply":"2020-08-21T17:34:53.02138Z"},"papermill":{"duration":0.057612,"end_time":"2020-08-21T17:34:53.022002","exception":false,"start_time":"2020-08-21T17:34:52.96439","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"len(data_img.train_ds), len(data_img.valid_ds), data_img.classes, data_img.train_ds[0][0].data[0].shape,data_img.c","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.025196,"end_time":"2020-08-21T17:34:53.071423","exception":false,"start_time":"2020-08-21T17:34:53.046227","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## Model Efficient-B3","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.124816Z","iopub.status.busy":"2020-08-21T17:34:53.124187Z","iopub.status.idle":"2020-08-21T17:34:53.139659Z","shell.execute_reply":"2020-08-21T17:34:53.138198Z"},"papermill":{"duration":0.044013,"end_time":"2020-08-21T17:34:53.139856","exception":false,"start_time":"2020-08-21T17:34:53.095843","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from efficientnet_pytorch import model as enet","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.196553Z","iopub.status.busy":"2020-08-21T17:34:53.195923Z","iopub.status.idle":"2020-08-21T17:34:53.199476Z","shell.execute_reply":"2020-08-21T17:34:53.200041Z"},"papermill":{"duration":0.034347,"end_time":"2020-08-21T17:34:53.200169","exception":false,"start_time":"2020-08-21T17:34:53.165822","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"pretrained_model = {\n    'efficientnet-b3': '../input/efficientnet-pytorch/efficientnet-b3-c8376fa2.pth'\n}\n\nenet_type = 'efficientnet-b3'\nout_dim = 6","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"enet.EfficientNet.from_name('efficientnet-b3')","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.259627Z","iopub.status.busy":"2020-08-21T17:34:53.258444Z","iopub.status.idle":"2020-08-21T17:34:53.268118Z","shell.execute_reply":"2020-08-21T17:34:53.267624Z"},"papermill":{"duration":0.043447,"end_time":"2020-08-21T17:34:53.268216","exception":false,"start_time":"2020-08-21T17:34:53.224769","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"class enetv2(nn.Module):\n    def __init__(self, backbone, out_dim):\n        super(enetv2, self).__init__()\n        self.enet = enet.EfficientNet.from_name(backbone)\n        self.enet.load_state_dict(torch.load(pretrained_model[backbone]))\n        nc = self.enet._fc.in_features\n        self.head = nn.Sequential(AdaptiveConcatPool2d(),Flatten(),nn.Linear(2*nc,512),\n                            nn.ReLU(),nn.BatchNorm1d(512), nn.Dropout(0.5),nn.Linear(512,out_dim))\n        self.myfc = nn.Linear(self.enet._fc.in_features, out_dim)\n        self.enet._fc = nn.Identity()\n\n    def extract(self, x):\n        return self.enet(x)\n\n    def forward(self, x):\n        shape = x[0].shape\n        x = torch.stack(x,1).view(-1,shape[1],shape[2],shape[3])\n        #x: bs*N x 3 x 128 x 128\n        x = self.extract(x)\n        #x: bs*N x C x 4 x 4\n        shape = x.shape\n        #concatenate the output for tiles into a single map\n        x = x.view(-1,n,shape[1],shape[2],shape[3]).permute(0,2,1,3,4).contiguous()\\\n          .view(-1,shape[1],shape[2]*n,shape[3])\n        #x: bs x C x N*4 x 4\n        x = self.head(x)\n        #x: bs x n\n        return x\n#         x = self.extract(x)\n#         x = self.myfc(x)\n#         return x","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.329584Z","iopub.status.busy":"2020-08-21T17:34:53.32875Z","iopub.status.idle":"2020-08-21T17:34:53.584728Z","shell.execute_reply":"2020-08-21T17:34:53.584126Z"},"papermill":{"duration":0.290834,"end_time":"2020-08-21T17:34:53.584841","exception":false,"start_time":"2020-08-21T17:34:53.294007","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"arch = enetv2(enet_type, out_dim=out_dim)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.024639,"end_time":"2020-08-21T17:34:53.634797","exception":false,"start_time":"2020-08-21T17:34:53.610158","status":"completed"},"tags":[]},"cell_type":"markdown","source":"### Metrics Kappa Score","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.690185Z","iopub.status.busy":"2020-08-21T17:34:53.689443Z","iopub.status.idle":"2020-08-21T17:34:53.693407Z","shell.execute_reply":"2020-08-21T17:34:53.692909Z"},"papermill":{"duration":0.033533,"end_time":"2020-08-21T17:34:53.693502","exception":false,"start_time":"2020-08-21T17:34:53.659969","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"kp = KappaScore()\nkp.weights = 'quadratic'","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.801537Z","iopub.status.busy":"2020-08-21T17:34:53.798991Z","iopub.status.idle":"2020-08-21T17:34:53.861207Z","shell.execute_reply":"2020-08-21T17:34:53.861646Z"},"papermill":{"duration":0.093809,"end_time":"2020-08-21T17:34:53.861791","exception":false,"start_time":"2020-08-21T17:34:53.767982","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"learn = Learner(data_img, arch , metrics = [kp] , model_dir = '/kaggle/working/')","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:34:53.923909Z","iopub.status.busy":"2020-08-21T17:34:53.922939Z","iopub.status.idle":"2020-08-21T17:35:54.50754Z","shell.execute_reply":"2020-08-21T17:35:54.508107Z"},"papermill":{"duration":60.621768,"end_time":"2020-08-21T17:35:54.508293","exception":false,"start_time":"2020-08-21T17:34:53.886525","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"learn.lr_find()\nlearn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:35:54.651034Z","iopub.status.busy":"2020-08-21T17:35:54.650378Z","iopub.status.idle":"2020-08-21T17:35:54.656796Z","shell.execute_reply":"2020-08-21T17:35:54.657469Z"},"papermill":{"duration":0.123371,"end_time":"2020-08-21T17:35:54.657607","exception":false,"start_time":"2020-08-21T17:35:54.534236","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:35:54.716899Z","iopub.status.busy":"2020-08-21T17:35:54.715102Z","iopub.status.idle":"2020-08-21T17:35:54.717657Z","shell.execute_reply":"2020-08-21T17:35:54.718149Z"},"papermill":{"duration":0.034452,"end_time":"2020-08-21T17:35:54.718272","exception":false,"start_time":"2020-08-21T17:35:54.68382","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"cb2 = SaveModelCallback(learn, monitor = 'kappa_score', every = 'improvement', mode='max', name = 'best_model_ft' )\ncb3 = ReduceLROnPlateauCallback(learn,  monitor = 'kappa_score', mode = 'max',factor = 0.2,patience = 4, min_delta = 0.01)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#learn.split([arch.myfc])","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T17:35:54.781509Z","iopub.status.busy":"2020-08-21T17:35:54.78061Z","iopub.status.idle":"2020-08-21T18:22:50.122194Z","shell.execute_reply":"2020-08-21T18:22:50.121382Z"},"papermill":{"duration":2815.378744,"end_time":"2020-08-21T18:22:50.122383","exception":false,"start_time":"2020-08-21T17:35:54.743639","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"# epochs = 4\n# learn.fit_one_cycle(epochs ,max_lr = 1e-3, callbacks = [cb2,cb3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.fit_one_cycle(6 ,max_lr = 1e-3, callbacks = [cb2,cb3])","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T18:22:50.184046Z","iopub.status.busy":"2020-08-21T18:22:50.182667Z","iopub.status.idle":"2020-08-21T18:22:50.369651Z","shell.execute_reply":"2020-08-21T18:22:50.370256Z"},"papermill":{"duration":0.221155,"end_time":"2020-08-21T18:22:50.370394","exception":false,"start_time":"2020-08-21T18:22:50.149239","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T18:22:50.428568Z","iopub.status.busy":"2020-08-21T18:22:50.427329Z","iopub.status.idle":"2020-08-21T18:22:50.736377Z","shell.execute_reply":"2020-08-21T18:22:50.735806Z"},"papermill":{"duration":0.339721,"end_time":"2020-08-21T18:22:50.736484","exception":false,"start_time":"2020-08-21T18:22:50.396763","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"learn.load('best_model_ft');","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T18:22:50.795902Z","iopub.status.busy":"2020-08-21T18:22:50.794975Z","iopub.status.idle":"2020-08-21T18:22:51.195953Z","shell.execute_reply":"2020-08-21T18:22:51.196469Z"},"papermill":{"duration":0.43267,"end_time":"2020-08-21T18:22:51.196622","exception":false,"start_time":"2020-08-21T18:22:50.763952","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"learn.export('/kaggle/working/panda.pkl')","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.040717,"end_time":"2020-08-21T18:22:51.278976","exception":false,"start_time":"2020-08-21T18:22:51.238259","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## Inference Kernel can be found [**here**](https://www.kaggle.com/ianmoone0617/panda-effnet-b3-inference-fastai-custom-imagelist)","execution_count":null},{"metadata":{"execution":{"iopub.execute_input":"2020-08-21T18:22:51.376078Z","iopub.status.busy":"2020-08-21T18:22:51.37516Z","iopub.status.idle":"2020-08-21T18:23:12.097651Z","shell.execute_reply":"2020-08-21T18:23:12.097138Z"},"papermill":{"duration":20.778917,"end_time":"2020-08-21T18:23:12.097803","exception":false,"start_time":"2020-08-21T18:22:51.318886","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"interp = ClassificationInterpretation.from_learner(learn)\ninterp.plot_confusion_matrix()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# learn = learn.to_fp32()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test_df = pd.read_csv('/kaggle/input/prostate-cancer-grade-assessment/test.csv')\n# df.drop('kfold', axis=1, inplace=True)\n# df.columns = ['image_id', 'data_provider', 'isup_grade', 'gleason_score']\n# data_dir = '../input/prostate-cancer-grade-assessment'\n# image_folder = os.path.join(data_dir, 'test_images')\n# is_test = os.path.exists(image_folder)  # IF test_images is not exists, we will use some train images.\n# image_folder = image_folder if is_test else os.path.join(data_dir, 'train_images')\n\n# test = test_df if is_test else df.sample(n=100)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def image_test(fn,image_folder):     \n#     path2 = image_folder +'/'\n#     fl = path2 + str(fn)+'.tiff'\n#     img = sk.MultiImage(fl)[1]\n#     res = get_tiles(img)\n#     imgs = []\n#     for i in range(36):\n#         im = res[i%len(res)]['img']\n#         imgs.append(im)\n#     imgs = np.array(imgs)\n#     final_image = np.concatenate(np.array([np.concatenate(imgs[j:j+6],axis=1).astype(np.uint8) for j in range(0,36,6)]),axis=0)\n#     final_image = cv2.resize(final_image, dsize=(300, 300), interpolation=cv2.INTER_CUBIC)\n#     return vision.Image(pil2tensor(final_image,np.float32).div_(255))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ts_name = test.image_id.values\n# pred = np.zeros(len(ts_name))\n    \n# for j in tqdm(range(len(ts_name))):\n#     ans = int(learn.predict(image_test(ts_name[j],image_folder))[0])\n#     pred[j] = ans\n        \n# out = pd.DataFrame({'image_id':ts_name,'isup_grade':pred.astype(int)})\n# out.to_csv('submission.csv',index=False)","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}