{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install /kaggle/input/timmwhl/timm-0.1.18-py3-none-any.whl\n\nimport cv2\nfrom tqdm import tqdm_notebook as tqdm\nimport fastai\nfrom fastai.vision import *\nimport os\nfrom mish_activation import *\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport skimage.io\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nfrom tqdm import tqdm\nfrom skimage.transform import resize, rescale\nfrom PIL import Image, ImageSequence\nimport openslide\n\nimport sys\npackage_path = '/kaggle/input/efficientnet-pytorch/EfficientNet-PyTorch/EfficientNet-PyTorch-master'\nsys.path.append(package_path)\nsys.path.insert(0, '../input/semisupervised-imagenet-models/semi-supervised-ImageNet1K-models-master/')\nfrom hubconf import *\n\nfrom efficientnet_pytorch import EfficientNet\nimport torch.nn as nn\nimport torch\nimport torchvision.models as models\nfrom torch.nn import TransformerEncoder, TransformerEncoderLayer\nimport torch.nn.functional as F\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(\"device:\",device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\npackage_path = '/kaggle/input/efficientnet-pytorch/EfficientNet-PyTorch/EfficientNet-PyTorch-master'\nsys.path.append(package_path)\nfrom efficientnet_pytorch import EfficientNet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"##first ensemble CM\n# path: /home/rvslight/pycharm/prostate/Input//LB91_224tile_best_resnext50_X20_30e_0.pth\n# Predicted    0    1    2    3    4    5\n# Actual                                 \n# 0          658   34    0    4    2    0\n# 1           28  536   23    5    3    1\n# 2            1   92  176   23   14    1\n# 3            8    9   46  126   52   25\n# 4            3   10   16   36  176   29\n# 5            7    3    6   22   36  168\n#               precision    recall  f1-score   support\n\n#            0       0.93      0.94      0.94       698\n#            1       0.78      0.90      0.84       596\n#            2       0.66      0.57      0.61       307\n#            3       0.58      0.47      0.52       266\n#            4       0.62      0.65      0.64       270\n#            5       0.75      0.69      0.72       242\n\n#     accuracy                           0.77      2379\n#    macro avg       0.72      0.71      0.71      2379\n# weighted avg       0.77      0.77      0.77      2379\n\n# kappa_score 0.8984666622351744\n\n\n## second ensemble CM\n# path: /home/rvslight/pycharm/prostate/Input//cv8899_expand_288_tiles_resnext50_X20_30e_0.pth\n# Predicted    0    1    2    3    4    5\n# Actual                                 \n# 0          662   30    0    3    3    0\n# 1           34  528   25    6    3    0\n# 2            3  121  124   38   19    2\n# 3            8   17   30  117   75   19\n# 4            3   18   11   43  163   32\n# 5            8    1    3   16   63  151\n#               precision    recall  f1-score   support\n\n#            0       0.92      0.95      0.94       698\n#            1       0.74      0.89      0.81       596\n#            2       0.64      0.40      0.50       307\n#            3       0.52      0.44      0.48       266\n#            4       0.50      0.60      0.55       270\n#            5       0.74      0.62      0.68       242\n\n#     accuracy                           0.73      2379\n#    macro avg       0.68      0.65      0.66      2379\n# weighted avg       0.73      0.73      0.72      2379\n\n# kappa_score 0.889748198293697\n\n### third efficientnet-b2 ### cv 8822","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"############ ensemble_list ###################\n\n####first######\n#224 tile mean / std\nmean_224 = torch.tensor([1.0-0.82097102, 1.0-0.63302738, 1.0-0.75392824])\nstd_224 = torch.tensor([0.37723779, 0.49839178, 0.4015415])\nfirst_resnext_pth_path_224 = \"../input/lb91-224tile/LB91_224tile_best_resnext50_X20_30e_0.pth\"\n\nensemble_1 ={\"mean\":mean_224,\"std\":std_224,\"tileSize\":224,\"isExpandTile\":False,\"arch\":\"resnext50_32x4d\",\"path\":first_resnext_pth_path_224,\"NN\":64}\n\n######second#####\n#288 tile mean / std\nmean_288 = torch.tensor([1.0-0.82809473, 1.0-0.65345352, 1.0-0.76934528])\nstd_288 = torch.tensor([0.40728608, 0.52557509, 0.42674383])\nsecond_resnext_pth_path_288 = \"../input/cv8899-expand-288/cv8899_expand_288_tiles_resnext50_X20_30e_0.pth\"\nexpand_sz = 288\n\nensemble_2 ={\"mean\":mean_288,\"std\":std_288,\"tileSize\":288,\"isExpandTile\":True,\"arch\":\"resnext50_32x4d\",\"path\":second_resnext_pth_path_288,\"NN\":64}\n\n\n#################################################\n\nensemble_list = []\nensemble_list.append(ensemble_1)\nensemble_list.append(ensemble_2)\n\n\nMODELS = []\nfor model_path_index in range(len(ensemble_list)):\n    MODELS.append(ensemble_list[model_path_index]['path'])\n\nDATA = '../input/prostate-cancer-grade-assessment/test_images'\nTEST = '../input/prostate-cancer-grade-assessment/test.csv'\n\nDATA2 = '../input/prostate-cancer-grade-assessment/train_images'\nTEST2 = '../input/prostate-cancer-grade-assessment/train.csv'\n\nSAMPLE = '../input/prostate-cancer-grade-assessment/sample_submission.csv'\n\nmixnet_pth=\"../input/segmmixnetv2/checkpoint_segm_mixnet_hardaug_14elr0005_acc88.59.pth\"\n\nbs = 2\nsz2=224\nNUM=20 #16\nNN=64 #64 #50 #60 # jjshadow.. 60-> 0.89, 50-> ??\n\n# X20: 64-> 0.91, 68->0.89   X16: 72->0.88   #   64->0.89 (max)   #   56->0.89   #48->0.88\nnworkers = 2\n\ndebug = False\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if os.path.exists(DATA):\n    print('test set exist')\n    debug = False # always off debug\n    chk=False\nelse:\n    print('test set not exist')\n    chk=True\n    TEST=TEST2\n    DATA=DATA2\n    nchk=10 #30 #100 #50 #3000 #101#3000 #3000 #1000 #100# 50\n    if debug:\n        nchk = 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.utils.data import Dataset\nfrom torchvision.transforms import Normalize\nfrom torchvision import datasets, transforms#, models\n\ndef _resnext(url, block, layers, pretrained, progress, **kwargs):\n    model = ResNet(block, layers, **kwargs)\n    return model\n    \nclass Model(nn.Module):\n    def __init__(self, arch, n=6, pre=True):\n        super().__init__()\n        self.arch = arch\n        if arch == 'resnet18':\n            m = models.resnet18(pretrained=False)\n        elif arch == 'resnet34':\n            m = models.resnet34(pretrained=False)\n        elif arch == 'resnet50':\n            m = models.resnet50(pretrained=False)\n        elif arch.startswith('efficient'):\n            m = EfficientNet.from_name(arch)\n            self.m = m\n        else: ## resnext50_32x4d\n            \n            m = _resnext(semi_supervised_model_urls[arch], Bottleneck, [3, 4, 6, 3], False, \n                progress=False,groups=32,width_per_group=4)\n        print(\"arch\",arch)\n        \n        if arch.startswith('efficient'):\n            nc = self.m._fc.in_features\n            self.m._fc = nn.Identity()\n            #\n            avgpool = 'avgpool' if hasattr(self.m, 'avgpool') else '_avg_pooling'\n            setattr(self.m, avgpool, AdaptiveConcatPool2d())\n\n            final = nn.Linear(nc * 2, n)\n            self.head = nn.Sequential(*list(self.m.children())[-4:], Flatten(), final)\n        else:\n            self.enc = nn.Sequential(*list(m.children())[:-2])       \n            nc = list(m.children())[-1].in_features\n            self.head = nn.Sequential(AdaptiveConcatPool2d(),Flatten(),nn.Linear(2*nc,512),\n                    Mish(),nn.BatchNorm1d(512),nn.Dropout(0.5),nn.Linear(512,n))\n        \n    def forward(self, x):\n        shape = x.shape\n        n = shape[1]\n        x = x.view(-1,shape[2],shape[3],shape[4])\n        if self.arch.startswith('efficient'):\n            x = self.m.extract_features(x)\n        else:\n            x = self.enc(x)\n        shape = x.shape\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 = self.head(x)\n        return x\n\n\nclass Unnormalize:\n    \"\"\"Converts an image tensor that was previously Normalize'd\n    back to an image with pixels in the range [0, 1].\"\"\"\n    def __init__(self, mean, std):\n        self.mean = mean\n        self.std = std\n\n    def __call__(self, tensor):\n        mean = torch.as_tensor(self.mean, dtype=tensor.dtype, device=tensor.device).view(3, 1, 1)\n        std = torch.as_tensor(self.std, dtype=tensor.dtype, device=tensor.device).view(3, 1, 1)\n        return torch.clamp(tensor*std + mean, 0., 1.)\n\nnormalize_transform = Normalize(mean_224, std_224)\nunnormalize_transform = Unnormalize(mean_224, std_224)\n\ndef tileSegm(img,N=NN,sz=56): #N=36\n    shape = img.shape\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                 constant_values=255)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    if len(img) < N:\n        img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n     \n       \n    idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:N]\n    img = img[idxs]\n    return img, idxs\n\nclass PandaSegmDataset(Dataset):\n     \n    def __init__(self, tiles):\n        self.tiles = tiles\n        print(\"tiles.shape=\",self.tiles.shape)\n         \n        \n \n    def __getitem__(self, index): \n        \n        tile=self.tiles[index]\n        tile=torch.tensor(tile).permute((2, 0, 1)).float().div(255)\n        tile= normalize_transform(tile)   \n        return tile \n       \n         \n    def __len__(self):\n        return len(self.tiles)\n\ndef predict(loader,model):\n    pred =[]\n    with tqdm(total=len(loader), leave=False) as pbar:\n        for batch_idx, data in enumerate(loader):\n             with torch.no_grad():\n                x = data.to(device)\n                y_pred = model(x)\n                y_pred=torch.sigmoid(y_pred.squeeze())\n                pred.append(y_pred.cpu().numpy() )\n             pbar.update()\n    pred=np.hstack(pred)            \n    return pred \n\ndef tile(img,idxs,sz=224,N=NN):\n    if debug:\n        print('tile_aksell')\n        print(\"tile_sz\",sz)\n        print(\"NN\",N)\n    shape = img.shape\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                 constant_values=255)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    if len(img) < N:\n        img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)   \n    img = img[idxs]\n    return img\n\ndef expand_tile(img,idxs,sz=224,N=NN, expand_sz = expand_sz):  # expand tile as 288 with 224 base size\n    if debug:\n        print('tile_expand_tile')\n        print(\"tile_sz\",expand_sz)\n        print(\"NN\",N)\n    \n    gap =(expand_sz - sz)\n    \n    shape = img.shape\n    \n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    padgap0,padgap1 = pad0 + gap, pad1 + gap\n    \n    img_org = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                 constant_values=255)\n    img_org_pad = np.pad(img,[[padgap0//2,padgap0-padgap0//2],[padgap1//2,padgap1-padgap1//2],[0,0]],\n                 constant_values=255)\n    \n    img_w_h = img_org.reshape(img_org.shape[0]//sz,sz,img_org.shape[1]//sz,sz,3)\n    img_w_h = img_w_h.transpose(0,2,1,3,4)\n    img = img_w_h.reshape(-1,sz,sz,3)\n    \n    expand_img_list = []\n    \n    for vertical_row in range(0,img_w_h.shape[0]):\n        for horizontal_row in range(0,img_w_h.shape[1]):\n            expand_tile_img = img_org_pad[ (sz*vertical_row):(sz*(vertical_row+1))+gap , (sz*horizontal_row):(sz*(horizontal_row+1))+gap]\n            expand_img_list.append(expand_tile_img) \n    \n    expand_img = np.asarray(expand_img_list)\n    \n    if debug: #debug\n        print(\"gap\",gap)\n        print('img_w_h',img_w_h.shape)\n        print(\"img.shape\",img.shape)\n        print('expand_img_shape',expand_img.shape)\n    \n    if len(expand_img) < N:\n        expand_img = np.pad(expand_img,[[0,N-len(expand_img)],[0,0],[0,0],[0,0]],constant_values=255)  \n    expand_img = expand_img[idxs]\n    return expand_img\n\ndef loadANDtile(image_id,tile_idx, N=NN, phase=0):\n    level=1\n    img = skimage.io.MultiImage(os.path.join(DATA,image_id+'.tiff'))[level] # mid res\n\n    isExpandTile = ensemble_list[phase]['isExpandTile']\n    if debug:\n        print(\"isExpandTile\",isExpandTile)\n        print(\"NN\",NN)\n    if isExpandTile:\n        tiles=expand_tile(img,tile_idx, N=N, expand_sz = ensemble_list[phase]['tileSize'])\n    else:\n        tiles=tile(img,tile_idx, N=N)\n    return tiles    \n\nclass ResnetDataset(Dataset):\n    def __init__(self, df, N=NN, phase=0):\n       # self.path = path\n        self.df = df\n        self.N = N\n        self.phase = phase\n        print(\"length=\",len(self.df))\n         \n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        image_id = row[\"image_id\"] \n        tile_idx = row[\"tile_idx\"] \n        tile_idx=[int(i) for i in tile_idx]\n        tiles=loadANDtile(image_id,tile_idx, N=self.N, phase=self.phase)\n        tiles = torch.Tensor(1.0 - tiles/255.0)\n        \n        mean = ensemble_list[self.phase]['mean']\n        std = ensemble_list[self.phase]['std']\n        if debug:\n            print(\"mean\",mean)\n            print(\"std\",std)\n        tiles = (tiles - mean)/std\n        return tiles.permute(0,3,1,2), image_id","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import timm\nsegmmodel = timm.create_model('mixnet_xl', pretrained=False)\nfor param in segmmodel.parameters():\n    param.requires_grad = False\n    # Replace the last fully-connected layer\n    # Parameters of newly constructed modules have requires_grad=True by default\nsegmmodel.classifier=nn.Linear(1536, 1)\nsegmmodel.fc = nn.Linear(1536, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = torch.load(mixnet_pth, map_location=device)\nsegmmodel.load_state_dict(checkpoint)\nsegmmodel.eval()\nsegmmodel.cuda() \ndel checkpoint","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"aknell_models = []\nfor model_index, path in enumerate(MODELS):\n    #\n    print(\"path\",path)\n    state_dict = torch.load(path,map_location=torch.device(device))   \n    model = Model(arch=ensemble_list[model_index]['arch'])\n    model.load_state_dict(state_dict)\n    model.float()\n    model.eval()\n    model.cuda()   \n    aknell_models.append(model)\n\ndel state_dict","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test=pd.read_csv(TEST)\nif chk:\n    pass\n    test=test[:][:nchk]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"names=[]\nAksell_PRED_LIST=[]\nfor pred_list_index in range(len(ensemble_list)):\n    Aksell_PRED_LIST.append([])\n\nfor index, ensemble_parameter in enumerate(ensemble_list):\n    NN = ensemble_parameter['NN']\n    print(\"Current_MODEL_PATH\",str(index),ensemble_parameter['path'])\n    print(\"Current_NN\",str(index),NN)\n    \n    imid=[]\n    idxs=[]\n    tiles=[]\n    level=2 #low res\n    for i in tqdm(range(len(test))):\n        img = skimage.io.MultiImage(os.path.join(DATA,test.iloc[i].image_id+'.tiff'))[level]\n        ti,idx=tileSegm(img, N=NN)\n        imid.append(test.iloc[i].image_id)\n        idxs.append(idx)\n        tiles.append(ti)\n\n    tiles= np.array(tiles)\n    tiles=tiles.reshape(tiles.shape[0]*tiles.shape[1],tiles.shape[2],tiles.shape[3],3  )\n    idxs=np.array(idxs).flatten()\n    imid =np.repeat(imid, NN) \n\n    dataset = PandaSegmDataset(tiles)\n    loader = DataLoader(dataset, batch_size=128, shuffle=False, num_workers=2, pin_memory=True)\n    \n    with torch.no_grad():\n        y=predict(loader,segmmodel)\n\n    df=pd.DataFrame({ 'image_id':imid ,  'idxs':idxs,'pred':y}) \n    df=df.sort_values([\"image_id\",\"pred\"],ascending=False)\n    df['oq'] = df.groupby('image_id').cumcount() + 1\n    df=df.loc[df.oq<=NUM]\n\n    test=test.set_index('image_id')\n    test[\"tile_idx\"]=np.nan\n    test=test.astype(object)\n\n    iuniq=df.image_id.unique()\n    for i in tqdm(iuniq):\n        idxs=df.loc[df.image_id==i].idxs.values\n        test.at[i,\"tile_idx\"]=idxs\n    test = test.reset_index()\n    del dataset\n    del loader\n    del df\n    import gc\n    gc.collect()\n\n    ds = ResnetDataset(test, N=NN, phase=index)\n\n    bs = 2\n    dl = DataLoader(ds, batch_size=bs, num_workers=nworkers, shuffle=False)\n\n    \n    with torch.no_grad():\n        \n        sz2 = ensemble_parameter['tileSize']\n        print(\"tilsSize:\",sz2)\n        print(f\"{index} prediction with NN:{NN}\")\n        for x,y in dl:#loader1:    \n\n            x = x.to(device)\n            #dihedral TTA\n\n            x = torch.stack([x,x.flip(-1),x.flip(-2),x.flip(-1,-2),\n              x.transpose(-1,-2),x.transpose(-1,-2).flip(-1),\n              x.transpose(-1,-2).flip(-2),x.transpose(-1,-2).flip(-1,-2)],1)\n            x = x.view(-1,NUM,3,sz2,sz2)\n            p = aknell_models[index](x) \n            pred_mean=p.view(bs,8,-1).mean(1) \n            Aksell_PRED_LIST[index].extend(pred_mean.argmax(-1).detach().cpu().numpy())\n            \n            del x,p\n            torch.cuda.empty_cache()\n            if index == 0: ## just first case add y\n                names.append(y)\nif debug:             \n    for check_p_index in range(len(Aksell_PRED_LIST)):\n        print(len(Aksell_PRED_LIST[check_p_index]))\nprint(\"at last concat phase\")\nnames = np.concatenate(names)\n# for pred_value_index, unit_pred in enumerate(Aksell_PRED_LIST):\n#     if pred_value_index == 0:\n#         total = (torch.cat(PRED_LIST[pred_value_index]).sigmoid().cpu())\n#     else:\n#         total += (torch.cat(PRED_LIST[pred_value_index]).sigmoid().cpu())\n\n# LOGITS = total / len(PRED_LIST)\n# preds=LOGITS.argmax(-1).numpy()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ce_preds = [float(x) for x in preds] # to float for ensemble with regression","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"####### shujun code merge ##########\n\ntest_image_dir='/kaggle/input/prostate-cancer-grade-assessment/test_images'\nif os.path.exists(test_image_dir):\n    print('test set exist')\n    chk=False\n    mode='test'\n    test_image_dir='/kaggle/input/prostate-cancer-grade-assessment/{}_images'.format(mode)\n    csv_path='/kaggle/input/prostate-cancer-grade-assessment/{}.csv'.format(mode)\nelse: #before test debug with 100 train image\n    print('test set not exist')\n    chk=True    \n    mode='train'\n    test_image_dir='/kaggle/input/prostate-cancer-grade-assessment/{}_images'.format(mode)\n    csv_path='/kaggle/input/prostate-cancer-grade-assessment/{}.csv'.format(mode)\n    \nsubmission_path='/kaggle/input/prostate-cancer-grade-assessment/sample_submission.csv'\n    \ndf=pd.read_csv(csv_path)\nif chk:\n    pass\n    df=df[:][:nchk]\n\n##################### shujun ensemble recipe ###########################\n\n#### ensemlbe #1 36x256x256 resnext50_32x4d arch lb: 0.911 best one ######\n    \nmean_256 = [0.85841531, 0.78983734, 0.89534979] # original shujun 256 cut\nstd_256 = [0.16897951, 0.25758676, 0.13730845] # original shujun 256 cut\nfirst_effb3_path_256 = '/kaggle/input/pandalayertest4wunertaintyacc/pandalayertest4wunertaintyacc/fold{}top{}.ckpt'\n\nensemble_shujun_1 ={\"mean\":mean_256,\"std\":std_256,\"tileImageSize\":256,\"isCutThreshold\":False,\"arch\":\"resnext50_32x4d\",\"path\":first_effb3_path_256,\"TILE_SIZE\":36,\"TILE_ALL\":False,\"CVT_COLOR\":True}\n\n#### ensemble #2 29x224x224 resnext50_32x4d arch qwk: 0.8996019660786133 ######\n\nmean_224= [0.81702482, 0.6299724, 0.75427603] # 224 cut\nstd_224=[0.40702703, 0.52099041, 0.42290275] # 224 cut\nsecond_resnext50_path_224 = '/kaggle/input/pandaakselltest3/fold{}top{}.ckpt'\n\nensemble_shujun_2 ={\"mean\":mean_224,\"std\":std_224,\"tileImageSize\":224,\"isCutThreshold\":True,\"arch\":\"resnext50_32x4d\",\"path\":second_resnext50_path_224,\"TILE_SIZE\":20,\"TILE_ALL\":False,\"CVT_COLOR\":True}\n\n#### ensemble #3 30x224x224 resnext50_32x4d  ######\nmean_224_30tile= [0.82514849, 0.64166622, 0.76170417] # 224 cut\nstd_224_30tile=[0.40444484, 0.52074353, 0.42308628] # 224 cut\nthird_resnext50_path_224 = '/kaggle/input/pandaakselltest4/fold{}top{}.ckpt'\nensemble_shujun_3 ={\"mean\":mean_224_30tile,\"std\":std_224_30tile,\"tileImageSize\":224,\"isCutThreshold\":True,\"arch\":\"resnext50_32x4d\",\"path\":third_resnext50_path_224,\"TILE_SIZE\":30,\"TILE_ALL\":False,\"CVT_COLOR\":False}\n\n# #### ensemble #4 20x288x288 resnext50_32x4d  ######\n# mean_288= [0.82809473, 0.65345352, 0.76934528] # 288 cut\n# std_288=[0.40728608, 0.52557509, 0.42674383] # 288 cut\nmean_288 = mean_224\nstd_288 = std_224\nfourth_resnext50_path_288 = '/kaggle/input/pandaakselltest5/fold{}top{}.ckpt'\nensemble_shujun_4 ={\"mean\":mean_288,\"std\":std_288,\"tileImageSize\":288,\"isCutThreshold\":True,\"arch\":\"resnext50_32x4d\",\"path\":fourth_resnext50_path_288,\"TILE_SIZE\":20,\"TILE_ALL\":False,\"CVT_COLOR\":False}\n## no cvtColor\n\n##### snsemble #5 32x224x224 ####\nmean_224_32= [0.82514849, 0.64166622, 0.76170417] # 224 32\nstd_224_32=[0.40444484, 0.52074353, 0.42308628] # 224 32\nfifth_resnext50_path_224 = '/kaggle/input/pandaakselltest7/fold{}top{}.ckpt'\nensemble_shujun_5 ={\"mean\":mean_224_32,\"std\":std_224_32,\"tileImageSize\":224,\"isCutThreshold\":True,\"arch\":\"resnext50_32x4d\",\"path\":fifth_resnext50_path_224,\"TILE_SIZE\":32,\"TILE_ALL\":True,\"CVT_COLOR\":True}\n## no cvtColor\n\n##### janey's model ensemble #6 64x224x224 ####\nmean_256_64= [0.8021112084388733, 0.7040286064147949, 0.8552106022834778] # 224 32\nstd_256_64=[0.18155023455619812, 0.27437373995780945, 0.15957728028297424] # 224 32\nsixth_resnext50_path_256 = '/kaggle/input/resnext50-new/fold{}top{}.ckpt'\nensemble_shujun_6 ={\"mean\":mean_256_64,\"std\":std_256_64,\"tileImageSize\":256,\"isCutThreshold\":False,\"arch\":\"resnext50_32x4d\",\"path\":sixth_resnext50_path_256,\"TILE_SIZE\":64,\"TILE_ALL\":False,\"CVT_COLOR\":True}\n\n\n###########################################################################\n## remove 30x224x224\n\nensemble_shujun_list = []\nensemble_shujun_list.append(ensemble_shujun_1)\nensemble_shujun_list.append(ensemble_shujun_2)\nensemble_shujun_list.append(ensemble_shujun_4)\nensemble_shujun_list.append(ensemble_shujun_5)\nensemble_shujun_list.append(ensemble_shujun_6)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"### shujun common structure ###\n# mish activation\nclass Mish(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n    def forward(self, x):\n        #inlining this saves 1 second per epoch (V100 GPU) vs having a temp x and then returning x(!)\n        return x *( torch.tanh(F.softplus(x)))\n\n\nfrom torch.nn.parameter import Parameter\ndef gem(x, p=3, eps=1e-6):\n    return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)\n\nclass GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM,self).__init__()\n        self.p = Parameter(torch.ones(1)*p)\n        self.eps = eps\n    def forward(self, x):\n        return gem(x, p=self.p, eps=self.eps)\n    def __repr__(self):\n        return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(self.eps) + ')'\n\nclass MultiheadAttentionClassifier(nn.Module):\n    def __init__(self,num_classes,out_features,ninp,nhead,dropout,attention_dropout=0.1):\n        super(MultiheadAttentionClassifier, self).__init__()\n        self.attention=nn.MultiheadAttention(ninp, nhead, dropout=attention_dropout)\n        self.classifier=nn.Linear(ninp*2,num_classes)\n        self.dropout=nn.Dropout(dropout)\n        self.mish=Mish()\n\n    def forward(self,x):\n        x=x.permute(1,0,2)\n        x,_=self.attention(x,x,x)\n        x=self.mish(x)\n        x=x.permute(1,0,2)\n        max_x,_=torch.max(x,dim=1)\n        x=torch.cat([torch.mean(x,dim=1),max_x],dim=-1)\n        x=self.dropout(x)\n        x=self.classifier(x)\n        return x\n\ndef _resnext(url, block, layers, pretrained, progress, **kwargs):\n    model = ResNet(block, layers, **kwargs)\n    return model\n\nclass Network(nn.Module):\n    def __init__(self,num_classes,arch='efficientnet-b0',dropout_p=0.5,nhead=8,ninp=512, nhid=512,attention_dropout=0.1):\n        super(Network, self).__init__()\n        if debug:\n            print('arch',arch)\n        if arch.startswith('efficient'):\n            self.backbone=EfficientNet.from_name(arch)\n        elif arch == 'resnet34':\n            self.backbone=models.resnet34(pretrained=False,)\n        elif arch == 'resnext50_32x4d':\n            self.backbone=models.resnext50_32x4d(pretrained=False)\n        self.backbone.avgpool=GeM()\n        self.num_classes=num_classes\n        self.out_features = self.backbone.fc.in_features\n        self.ninp=ninp\n        self.backbone.fc=nn.Linear(self.out_features,ninp)\n        self.regression_head=MultiheadAttentionClassifier(1,self.out_features,ninp,nhead,dropout_p)\n        self.classifier_head=MultiheadAttentionClassifier(num_classes[0],self.out_features,ninp,nhead,dropout_p)\n        self.regression_head2=MultiheadAttentionClassifier(1,self.out_features,ninp,nhead,dropout_p)\n        self.regression_head3=MultiheadAttentionClassifier(1,self.out_features,ninp,nhead,dropout_p)\n\n    def forward(self,x):\n        shape = x[0].shape\n        bs=x.shape[0]\n        n = len(x)\n        x = x.reshape((-1,shape[1],shape[2],shape[3]))\n        features=self.backbone(x)\n        features=features.reshape(bs,shape[0],self.ninp)\n        outputs=[self.regression_head(features).squeeze(),F.log_softmax(self.classifier_head(features),dim=1),\n                 self.regression_head2(features).squeeze(),self.regression_head3(features).squeeze()]\n        \n        return outputs\ndef tile_shujun(img, sz=224,N=20):\n    if debug:\n        print('tile_shujun')\n    result = []\n    shape = img.shape\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                constant_values=255)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    if len(img) < N:\n        img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n    idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))[:N]\n    img = img[idxs]\n    return img\n\ndef tile_all(img, N, sz=256):\n    if debug:\n        print('tile_all_shujun')\n        print('N',N)\n    result = []\n    shape = img.shape\n    pad0,pad1 = (sz - shape[0]%sz)%sz, (sz - shape[1]%sz)%sz\n    img = np.pad(img,[[pad0//2,pad0-pad0//2],[pad1//2,pad1-pad1//2],[0,0]],\n                constant_values=255)\n    img = img.reshape(img.shape[0]//sz,sz,img.shape[1]//sz,sz,3)\n    img = img.transpose(0,2,1,3,4).reshape(-1,sz,sz,3)\n    if len(img) < N:\n         img = np.pad(img,[[0,N-len(img)],[0,0],[0,0],[0,0]],constant_values=255)\n    idxs = np.argsort(img.reshape(img.shape[0],-1).sum(-1))\n    \n    return img, idxs\n\ndef standardize_batch(batch,mean,std,isCutThresholdTile):\n    ##1. change standardize_batch\n    if debug:\n        print(\"test:\",batch.shape[1])\n    if batch.shape[1]==64:\n        if debug:\n            print(\"st_01\")\n        batch=batch/255.0\n        batch=(batch-mean)/std\n    elif isCutThresholdTile:\n        if debug:\n            print(\"st_02\")\n        batch=batch/255.0\n        batch=(mean-batch)/std\n    else:\n        if debug:\n            print(\"st_03\")\n        batch=batch/255.0\n    return batch\n\ndef get_batch_of_image(paths, sz, N, phase = 0, index_df = None):\n    isCutThreshold = ensemble_shujun_list[phase]['isCutThreshold']\n    isTileAll = ensemble_shujun_list[phase]['TILE_ALL']\n    if debug:\n        print('sz',sz)\n        print('N',N)\n        print('isCutThreshold',isCutThreshold)\n    images=[]\n    for path in paths:\n        if isCutThreshold:\n            tile_idx = index_df.loc[index_df['image_id']== path]['tile_idx'].tolist()[0]\n            tile_idx=[int(i) for i in tile_idx]\n            if debug:\n                print(tile_idx)\n                \n        path=os.path.join(test_image_dir,path+'.tiff')\n        img = skimage.io.MultiImage(path,conserve_memory=False,dtype='tiff')[1]\n        if isCutThreshold:\n            \n            if isTileAll:\n                ## first just get 20 aknell tile\n                tile_idx = tile_idx[:20]\n                if debug:\n                    print(tile_idx)\n                Max_Indices_N = max(tile_idx)+1\n                if debug:\n                    print(\"Max_Indices_N\",Max_Indices_N)\n                img, idxs = tile_all(img, sz=sz, N=Max_Indices_N)\n                tiles = []\n                for sorted_index in idxs:\n                    if sorted_index not in tile_idx:\n                        tiles.append(img[sorted_index])\n                    if len(tiles)>=N-20:\n                        break\n                ## 5. add padding function for combine tile models:\n                if len(tiles) < N-20:\n                    tiles = np.pad(tiles,[[0,N-len(tiles)],[0,0],[0,0],[0,0]],constant_values=255)\n                tiles = np.asarray(tiles)\n                if debug:\n                    print(\"before_concate_tiles_shape\",tiles.shape)\n                    print(\"aksell_indices.shape\",img[tile_idx].shape)\n                tiles = np.concatenate([tiles,img[tile_idx]]).astype(\"uint8\")\n                if debug:\n                    print(\"tiles\",tiles.shape)\n                img = tiles\n                        \n            else:\n                if sz == 224: ## laffos cut with cancer index ## janey case's isCutThreshold is False so go to tile_shujun\n                    img = tile(img,tile_idx, N=NN)\n                else: ## expand tile with canner index\n                    img = expand_tile(img,tile_idx, sz=224, N=NN, expand_sz = sz)\n                \n        else:\n            img = tile_shujun(img, sz=sz, N=N)\n            \n        if(ensemble_shujun_list[phase]['CVT_COLOR']==True): ## CVT_COLOR is False in pandatest4,test5\n            if debug:\n                print(\"CVT_COLOR is True\")\n            for j in range(img.shape[0]):\n                img[j] = cv2.cvtColor(img[j],cv2.COLOR_RGB2BGR)\n        else:\n            if debug:\n                print(\"CVT_COLOR is False\")\n        img=np.asarray(img,dtype='uint8')\n        images.append(img)\n    images=np.asarray(images,dtype='uint8').transpose((0,1,4,2,3))\n    return images\n\n\ndef classification_threshold(tensor):\n    for i in range(len(tensor)):\n        if tensor[i] > 4.5:\n            tensor[i]=5\n        elif tensor[i] > 3.5:\n            tensor[i]=4\n        elif tensor[i] > 2.5:\n            tensor[i]=3\n        elif tensor[i] > 1.5:\n            tensor[i]=2\n        elif tensor[i] > 0.6:\n            tensor[i]=1\n        elif tensor[i] < 0.6:\n            tensor[i]=0\n    return tensor.astype('int')\n\ndef classification_threshold_item(item):\n    if item > 4.5:\n        item=5\n    elif item > 3.5:\n        item=4\n    elif item > 2.5:\n        item=3\n    elif item > 1.5:\n        item=2\n    elif item > 0.6:\n        item=1\n    elif item < 0.6:\n        item=0\n    return int(item)#tensor.astype('int')\n\ndef hflip(tensor):\n    for i in range(tensor.shape[0]):\n        for j in range(tensor.shape[1]):\n            tensor[i,j]=np.flip(tensor[i,j],axis=0)\n    return tensor\n\n\ndef vflip(tensor):\n    for i in range(tensor.shape[0]):\n        for j in range(tensor.shape[1]):\n            tensor[i,j]=np.flip(tensor[i,j],axis=1)\n    return tensor","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nimport torch.nn as nn\nclass JaneyMultiheadAttentionClassifier(nn.Module):\n    def __init__(self,num_classes,out_features,ninp,nhead,dropout,nlayers=1,attention_dropout=0.1):\n        super(JaneyMultiheadAttentionClassifier, self).__init__()\n        encoder_layers = nn.TransformerEncoderLayer(ninp, nhead, ninp*4, attention_dropout)\n        encoder_layers.activation=Mish()\n        self.attention = nn.TransformerEncoder(encoder_layers, nlayers)\n        self.classifier=nn.Linear(ninp*2,num_classes)\n        self.dropout=nn.Dropout(dropout)\n\n    def forward(self,x):\n        x=self.dropout(x)\n        x=x.permute(1,0,2)\n        x=self.attention(x)\n        x=x.permute(1,0,2)\n        max_x,_=torch.max(x,dim=1)\n        x=torch.cat([torch.mean(x,dim=1),max_x],dim=-1)\n        x=self.dropout(x)\n        x=self.classifier(x)\n        return x\n\n\nclass JaneyNetwork(nn.Module):\n    def __init__(self,num_classes,efficientNet_name='efficientnet-b0',dropout_p=0.5,nhead=8,ninp=512, nhid=512,attention_dropout=0.1):\n        super(JaneyNetwork, self).__init__()\n#         self.backbone=torch.hub.load('facebookresearch/semi-supervised-ImageNet1K-models', 'resnext50_32x4d_ssl')\n        self.backbone=models.resnext50_32x4d(pretrained=False)\n        self.backbone.avgpool=GeM()\n        self.num_classes=num_classes\n        self.out_features = self.backbone.fc.in_features\n        self.ninp=ninp\n        self.backbone.fc=nn.Identity()\n        regression_head=JaneyMultiheadAttentionClassifier(1,self.out_features,ninp,nhead,dropout_p)\n        classifier_head=JaneyMultiheadAttentionClassifier(num_classes[0],self.out_features,ninp,nhead,dropout_p)\n        regression_head2=JaneyMultiheadAttentionClassifier(1,self.out_features,ninp,nhead,dropout_p)\n        regression_head3=JaneyMultiheadAttentionClassifier(1,self.out_features,ninp,nhead,dropout_p)\n\n        self.heads=nn.ModuleList([regression_head,classifier_head,regression_head2,regression_head3,nn.Linear(self.out_features,ninp)])\n\n    def forward(self,x):\n        shape = x[0].shape\n        bs=x.shape[0]\n        n = len(x)\n        x = x.reshape((-1,shape[1],shape[2],shape[3]))\n        features=self.backbone(x)\n        features=self.heads[4](features)\n        features=features.reshape(bs,shape[0],self.ninp)\n        outputs=[self.heads[0](features).squeeze(-1),F.log_softmax(self.heads[1](features),dim=1),\n                 self.heads[2](features).squeeze(-1),self.heads[3](features).squeeze(-1)]\n        return outputs\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"### make segment model index_df for shujun ###\nMax_Cut_Num = NN\nif debug:\n    print('Max_Cut_Num',Max_Cut_Num)\n\nimid=[]\nidxs=[]\ntiles=[]\nlevel=2 #low res\nfor i in tqdm(range(len(df))):\n    img = skimage.io.MultiImage(os.path.join(DATA,df.iloc[i].image_id+'.tiff'))[level]\n    ti,idx=tileSegm(img, N=NN)\n    imid.append(df.iloc[i].image_id)\n    idxs.append(idx)\n    tiles.append(ti)\n\ntiles= np.array(tiles)\ntiles=tiles.reshape(tiles.shape[0]*tiles.shape[1],tiles.shape[2],tiles.shape[3],3  )\nidxs=np.array(idxs).flatten()\nimid =np.repeat(imid, NN) \n\ndataset = PandaSegmDataset(tiles)\nloader = DataLoader(dataset, batch_size=128, shuffle=False, num_workers=2, pin_memory=True)\n\nwith torch.no_grad():\n    y=predict(loader,segmmodel)\n\nindex_df=pd.DataFrame({ 'image_id':imid ,  'idxs':idxs,'pred':y}) \nindex_df=index_df.sort_values([\"image_id\",\"pred\"],ascending=False)\nindex_df['oq'] = index_df.groupby('image_id').cumcount() + 1\nindex_df=index_df.loc[index_df.oq<=20] ## maybe 64 index.. sorted","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"### insert index to df file \ndf=df.set_index('image_id')\ndf[\"tile_idx\"]=np.nan\ndf=df.astype(object)\n\niuniq=index_df.image_id.unique()\nfor i in tqdm(iuniq):\n    idxs=index_df.loc[index_df.image_id==i].idxs.values\n    df.at[i,\"tile_idx\"]=idxs\ndf = df.reset_index()\ndel dataset\ndel loader\ndel index_df\ndel y\nimport gc\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Shujun_PRED_LIST=[]\nfor pred_list_index in range(len(ensemble_shujun_list)):\n    Shujun_PRED_LIST.append([])\n\n\nfor phase_index, ensemble_recipe in enumerate(ensemble_shujun_list):\n    print(\"shujun_ensemble_phase\",phase_index)\n\n    MODELS=[]\n    top=3\n    num_classes=[6,4,4,]\n\n    if ensemble_recipe['tileImageSize'] == 288:\n        print(\"top_fold is 3\")\n        top_fold = 3 ## just 2 phase.. 4th ensemble model's top fold is 3(20x288x288)\n    else:\n        top_fold = 2\n    for i in range(top_fold,top_fold+1):\n        for j in range(top):\n            \n            if ensemble_recipe['TILE_SIZE'] == 64: ## janey network.\n                if debug:\n                    print(\"Janey Network\")\n                model = JaneyNetwork(num_classes).to(device)\n            else:\n                model = Network(num_classes,arch = ensemble_recipe['arch']).to(device)\n            model = model.to(device)\n            model = nn.DataParallel(model)\n            weights_paths=ensemble_recipe['path'].format(i,j+1)\n            if debug:\n                print(weights_paths)\n            model.load_state_dict(torch.load(weights_paths))\n            model.eval()\n            MODELS.append(model) \n\n    ####shujun code output ###\n\n    total_images=0\n    ## janey model's batch is 8 for OOM\n    if ensemble_recipe['TILE_SIZE'] == 64 or ensemble_recipe['tileImageSize'] == 288: ## janey network.\n        batch_size=8\n    else:\n        batch_size=16\n    if debug:\n            print(\"batch_size\",batch_size)\n    if len(df)%batch_size==0:\n        batches=int(len(df)/batch_size)\n    else:\n        batches=int(len(df)/batch_size)+1\n    model.eval()\n    predictions=[]\n    mean=torch.Tensor(ensemble_recipe['mean']).to(device).reshape(1,1,3,1,1)\n    std=torch.Tensor(ensemble_recipe['std']).to(device).reshape(1,1,3,1,1)\n    if debug:\n        print(mean)\n        print(std)\n    with torch.no_grad():\n        for i in tqdm(range(batches)):\n            paths=df.image_id[i*batch_size:(i+1)*batch_size].to_list()\n            x=get_batch_of_image(paths, sz = ensemble_recipe['tileImageSize'], N = ensemble_recipe['TILE_SIZE'], phase=phase_index, index_df = df)\n            x0=torch.Tensor(x).to(device)\n            x_h=torch.Tensor(x).to(device).flip(-1)\n            x_v=torch.Tensor(x).to(device).flip(-2)\n            x_vh=torch.Tensor(x).to(device).flip(-1,-2)\n            x0t=torch.Tensor(x).to(device).transpose(-1,-2)\n            x_ht=torch.Tensor(x).to(device).flip(-1).transpose(-1,-2)\n            x_vt=torch.Tensor(x).to(device).flip(-2).transpose(-1,-2)\n            x_vht=torch.Tensor(x).to(device).flip(-1,-2).transpose(-1,-2)\n            outputs=[]\n            isCutThresholdTile = ensemble_recipe['isCutThreshold']\n            if debug:\n                print('isCutThresholdTile',isCutThresholdTile)\n            for model in MODELS:\n                output = model(standardize_batch(x0,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x_h,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x_v,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x_vh,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x0t,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x_ht,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x_vt,mean,std,isCutThresholdTile=isCutThresholdTile))[0]+\\\n                         model(standardize_batch(x_vht,mean,std,isCutThresholdTile=isCutThresholdTile))[0]\n\n\n                output=output.cpu().numpy()/8\n                outputs.append(output)\n            outputs=np.asarray(outputs)\n            outputs=np.mean(outputs,axis=0)\n\n            predictions.append(output)\n    for pred in predictions:\n        Shujun_PRED_LIST[phase_index].extend(pred)\n    \n    del output, predictions, MODELS ### fix OOM memory issue.. hope..\n    torch.cuda.empty_cache()\n\n\n#### here shujun ensemble.. ####\nif debug:\n    for check_p_index in range(len(Shujun_PRED_LIST)):\n        print(len(Shujun_PRED_LIST[check_p_index]))\n    print(\"at last ensemble phase\")\n\nshujun_pred_list = np.asarray(Shujun_PRED_LIST)\n\nprint(\"shape\",shujun_pred_list.shape)\nif debug:\n    print(Aksell_PRED_LIST) \n    print(Shujun_PRED_LIST) \ntotal_list = np.vstack((np.asarray(Aksell_PRED_LIST),np.asarray(Shujun_PRED_LIST))).transpose()\n#shujun_ensemble_preds = np.asarray(PRED_LIST).mean(axis=0) ## shujun ensemble here","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#### here ensemble.. must do it!!!\nlabel_list = []\nfor total_list_index, list_item in enumerate(total_list.tolist()):\n    predictions = list(list_item)\n    final_value = np.mean(predictions)\n    label=classification_threshold_item(final_value)\n    if debug:\n        print(\"final_value\",final_value)\n        print(\"!!label!!\",label)\n    label_list.append(label)\n    \npredictions_output=np.asarray(label_list,dtype='int')\n\n\n###output###\nsub_df = pd.DataFrame({'image_id':df.image_id.tolist(), 'isup_grade': list(predictions_output)})\n\n\nif chk:\n    from sklearn import metrics\n    ground_truths=np.asarray(df.isup_grade,dtype='int')\n    score=metrics.cohen_kappa_score(ground_truths,predictions_output,weights='quadratic')\n    print(score)\n    sub_df['ig']=df.isup_grade[:nchk]\n\nsub_df.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_df.head(50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_df.tail(50)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub_df.isup_grade.unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from IPython.display import HTML\n# import pandas as pd\n# import numpy as np\n# import base64\n\n# # function that takes in a dataframe and creates a text link to  \n# # download it (will only work for files < 2MB or so)\n# def create_download_link(df, title = \"Download CSV file\", filename = \"submission.csv\"):  \n#     csv = df.to_csv()\n#     b64 = base64.b64encode(csv.encode())\n#     payload = b64.decode()\n#     html = '<a download=\"{filename}\" href=\"data:text/csv;base64,{payload}\" target=\"_blank\">{title}</a>'\n#     html = html.format(payload=payload,title=title,filename=filename)\n#     return HTML(html)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# create_download_link(sub_df)","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}