{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport sys\nimport shutil\nimport json\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport cv2\nfrom skimage import io,color\n\nimport time\nfrom glob import glob\nfrom pprint import pprint\nfrom collections import defaultdict\nfrom random import sample\nimport gc\nimport copy","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:12:30.504107Z","iopub.execute_input":"2022-08-20T10:12:30.504729Z","iopub.status.idle":"2022-08-20T10:12:30.510942Z","shell.execute_reply.started":"2022-08-20T10:12:30.504694Z","shell.execute_reply":"2022-08-20T10:12:30.509581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load and Save Utils\nFunctions for loading data,loading/normalizing/saving images,loading/saving info dicts. Define classes to store all saved box/cell/tile+info. Save/Load classes from dict\n","metadata":{}},{"cell_type":"code","source":"## Save or load dct to/from file\ndef loadjsonfile(pathfile):\n    if not os.path.isfile(pathfile):\n        f=open(pathfile,'w')\n        f.write('{}')\n        f.close()\n    with open(pathfile) as f:\n        return byteify(json.load(f))\ndef savejsonfile(obj,pathfile,indent=2,sort=True):\n    with open(pathfile,\"w\") as f:\n        json.dump(byteify(obj),f,indent=None,sort_keys=False)\n## Encodes any input from unicode to normal string  \ndef byteify(input):\n    if isinstance(input,dict):\n        return {byteify(key):byteify(value) for key,value in input.items()}\n    elif isinstance(input,list):\n        return [byteify(element) for element in input]\n    elif isinstance(input,str):                                                                                                                                       \n        try: return input.decode()\n        except: return input\n    elif isinstance(input,np.int64):\n        return int(input)\n    else: \n        return input\n    \n## Define class for storing meta data on selected box/cell/tile to save\n## All saved obj is 256*256*3,concatenated in a simgle numpy array. \n## The classes below are exported/loaded to json dicts per image.\n## Ordering of saved objects: original_img>boxes>cells>cell_tiles>box_tiles\nclass boxtile_class():\n    def __init__(self,idx,loc,box,img):\n        self.idx=idx\n        self.loc=loc ## loc in box\n        self.box=box\n        self.img=img\n        \nclass celltile_class():\n    def __init__(self,idx,loc,cell,box,img):\n        self.idx=idx\n        self.loc=loc ## loc in cell\n        self.cell=cell\n        self.box=box\n        self.img=img\n    \nclass cell_class():\n    def __init__(self,idx,loc,box,img):\n        self.idx=idx\n        self.loc=loc ## loc in box\n        self.box=box\n        self.img=img\n        self.ctiles=[]\n        self.tc_idxs=[0,0]\n    def addctiles(self,locs):\n        for c_idx,loc in enumerate(locs):\n            idx=self.img.next+0\n            self.img.next+=1\n            tc=celltile_class(idx,loc,self,self.box,self.img)\n            if self.tc_idxs[1]==0:\n                self.tc_idxs=[idx,idx]\n            self.tc_idxs[1]+=1\n            self.ctiles.append(tc)\n        for p in [self.box,self.img]:\n            p.ctiles+=self.ctiles\n            if p.tc_idxs[1]==0:\n                p.tc_idxs=self.tc_idxs+[]\n            else:\n                p.tc_idxs[1]+=len(self.ctiles)\n        \nclass box_class():\n    def __init__(self,idx,size,loc,img):\n        self.idx=idx\n        self.size=size ## size wrt img\n        self.loc=loc ## loc in img\n        self.img=img\n        self.cells=[]\n        self.btiles=[]\n        self.ctiles=[]\n        self.c_idxs=[0,0]\n        self.tb_idxs=[0,0]\n        self.tc_idxs=[0,0]\n    def addcells(self,locs):\n        for loc in locs:\n            idx=self.img.next+0\n            self.img.next+=1\n            c=cell_class(idx,loc,self,self.img)\n            if self.c_idxs[1]==0:\n                self.c_idxs=[idx,idx]\n            self.c_idxs[1]+=1\n            self.cells.append(c)\n        self.img.cells+=self.cells\n        if self.img.c_idxs[1]==0:\n            self.img.c_idxs=self.c_idxs+[]\n        else:\n            self.img.c_idxs[1]+=len(self.cells)\n    def addbtiles(self,locs):\n        for loc in locs:\n            idx=self.img.next+0\n            self.img.next+=1\n            tb=boxtile_class(idx,loc,self,self.img)\n            if self.tb_idxs[1]==0:\n                self.tb_idxs=[idx,idx]\n            self.tb_idxs[1]+=1\n            self.btiles.append(tb)\n        self.img.btiles+=self.btiles\n        if self.img.tb_idxs[1]==0:\n            self.img.tb_idxs=self.tb_idxs+[]\n        else:\n            self.img.tb_idxs[1]+=len(self.btiles)\n    def makeindex(self):\n        self.index=self.cells+self.ctiles+self.btiles\n        \nclass img_class():\n    def __init__(self,imgid=\"\",isplit=0,size=[],colorInfo=[]):\n        self.imgid=imgid\n        self.isplit=isplit\n        self.size=size ## orig size\n        self.colorInfo=colorInfo ## colorInfo\n        self.next=2 ## next idx in saved numpy array,0 is img0s,1 is img0s normalized with boxes \n        self.boxes=[]\n        self.cells=[]\n        self.btiles=[]\n        self.ctiles=[]\n        self.b_idxs=[0,0]\n        self.c_idxs=[0,0]\n        self.tb_idxs=[0,0]\n        self.tc_idxs=[0,0]\n    def addboxes(self,sizes,locs):\n        for size,loc in zip(sizes,locs):\n            idx=self.next+0\n            self.next+=1\n            b=box_class(idx,size,loc,self)\n            if self.b_idxs[1]==0:\n                self.b_idxs=[idx,idx]\n            self.b_idxs[1]+=1\n            self.boxes.append(b)\n    def makeindex(self):\n        self.index=self.boxes+self.cells+self.ctiles+self.btiles\n        \n## rebuild obj classes from dict\ndef make_classes(imglabel,tile_path):\n    book_path=tile_path.replace('tile','book').replace('.npy','.json')\n    if not os.path.isfile(book_path):\n        print(\"WARNING: File %s not found\"%book_path)\n        return\n    dct=loadjsonfile(book_path)\n    ImgC=img_class(dct['imgid'],dct['isplit'],dct['size'],dct['colorInfo'])\n    ## Boxes\n    sizes=[]\n    locs=[]\n    for b,box in enumerate(dct['boxes']):\n        sizes.append(box['size'])\n        locs.append(box['loc'])\n    ImgC.addboxes(sizes,locs)\n    ## Cells\n    for b,box in enumerate(dct['boxes']):\n        boxC=ImgC.boxes[b]\n        locs=[]\n        for cell in box['cells']:\n            locs.append(cell['loc'])\n        boxC.addcells(locs)\n    ## CellTiles\n    for b,box in enumerate(dct['boxes']):\n        boxC=ImgC.boxes[b]\n        for c,cell in enumerate(box['cells']):\n            cellC=boxC.cells[c]\n            locs=[]\n            for ctile in cell['ctiles']:\n                locs.append(ctile['loc'])\n            cellC.addctiles(locs)\n    ## BoxTiles\n    for b,box in enumerate(dct['boxes']):\n        boxC=ImgC.boxes[b]\n        locs=[]\n        for btile in box['btiles']:\n            locs.append(btile['loc'])\n        boxC.addbtiles(locs)\n    return ImgC\n\n## print info of stored class objs (verbose=0/1/2)\ndef print_classes(ImgC,verbose=0):\n    if verbose==2:\n        print(\"ImgSize:\",ImgC.size,\",ColorInfo:\",ImgC.colorInfo,\"\\n\")\n    ImgC.makeindex()\n    print(\"%s-tot %s-boxes%s %s-cells%s %s-ctiles%s %s-btiles%s\"%(len(ImgC.index),\n                                                                      len(ImgC.boxes),ImgC.b_idxs,\n                                                                      len(ImgC.cells),ImgC.c_idxs,\n                                                                      len(ImgC.ctiles),ImgC.tc_idxs,\n                                                                      len(ImgC.btiles),ImgC.tb_idxs))\n    if verbose:\n        for boxC in ImgC.boxes:\n            boxC.makeindex()\n            print(\" Box%s: %s-tot %s-cells%s %s-ctiles%s %s-btiles%s\"%(boxC.idx,len(boxC.index),\n                                                                  len(boxC.cells),boxC.c_idxs,\n                                                                  len(boxC.ctiles),boxC.tc_idxs,\n                                                                  len(boxC.btiles),boxC.tb_idxs))\n            if verbose==2:\n                print(\" BoxSize: %.2f,%.2f\"%(boxC.size[0],boxC.size[1]),\",BoxLoc: %.2f,%.2f\"%(boxC.loc[0],boxC.loc[1]))\n                for cellC in boxC.cells:\n                    print(\"  Cell%s: %s-ctiles%s\"%(cellC.idx,len(cellC.ctiles),cellC.tc_idxs))\n                    print(\"  CellLoc: %.2f,%.2f\"%(cellC.loc[0],cellC.loc[1]))\n                    if cellC.ctiles:\n                        print(\"   CTileLocs\",[\"%.2f,%.2f\"%(ct.loc[0],ct.loc[1]) for ct in cellC.ctiles])\n                print(\"   BTileLocs\",[\"%.2f,%.2f\"%(bt.loc[0],bt.loc[1]) for bt in boxC.btiles])\n                \n## get list of images\ndef get_data(lab): # lab=train/test/other\n    df=pd.read_csv(\"../input/mayo-clinic-strip-ai/%s.csv\"%lab)\n    tiles=sorted(glob(\"/kaggle/input/mybddata1/save/tile/*\"))\n    dct={'imglabel':[],'image_id':[],'tile_path':[]}\n    for tile_path in tiles:\n        imglabel=tile_path.rsplit('/',1)[1].split('.')[0]\n        dct['imglabel'].append(imglabel)\n        dct['image_id'].append(imglabel.rsplit('_',1)[0])\n        dct['tile_path'].append(tile_path)\n    image_data=pd.DataFrame(dct)\n    image_data=image_data.merge(df,on='image_id')\n#    image_data.sort_values('image_id',inplace=True)\n    image_data.reset_index(inplace=True,drop=True)\n    return image_data","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:12:32.642781Z","iopub.execute_input":"2022-08-20T10:12:32.643313Z","iopub.status.idle":"2022-08-20T10:12:32.686347Z","shell.execute_reply.started":"2022-08-20T10:12:32.643278Z","shell.execute_reply":"2022-08-20T10:12:32.685136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df=get_data(\"train\")\ndf.head()\n# df.set_index(\"image_id\",inplace=True)\n# imgid='992abf_0'\n# a,b=df.loc[imgid,['path','size']].values\n# df.index[0]","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:12:34.315992Z","iopub.execute_input":"2022-08-20T10:12:34.316368Z","iopub.status.idle":"2022-08-20T10:12:34.343146Z","shell.execute_reply.started":"2022-08-20T10:12:34.316333Z","shell.execute_reply":"2022-08-20T10:12:34.34213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## For testing\nimglabel='062387_0_1'\nrow=df.loc[df['imglabel']==imglabel].iloc[0]\nImgC=make_classes(imglabel,row.tile_path)\nprint_classes(ImgC,verbose=1)\ntiles=np.load(row.tile_path)\nprint(tiles.shape)\nfig,((ax1,ax2,ax3,ax4),(bx1,bx2,bx3,bx4))=plt.subplots(2,4,figsize=(20,10))\nax1.imshow(tiles[0]) ## orig img\nax2.imshow(tiles[1]) ## processed img\nax3.imshow(tiles[2]) ## first box\nax4.imshow(tiles[ImgC.b_idxs[1]-1]) ## last box\nif ImgC.cells: \n    bx1.imshow(tiles[ImgC.c_idxs[0]]) ## first cell\n    bx2.imshow(tiles[ImgC.c_idxs[1]-1]) ## last cell\n    bx3.imshow(tiles[ImgC.c_idxs[1]]) ## first tile\nelse:\n    bx1.imshow(tiles[ImgC.b_idxs[1]]) ## first 3 tiles\n    bx2.imshow(tiles[ImgC.b_idxs[1]+1])\n    bx3.imshow(tiles[ImgC.b_idxs[1]+2])    \nbx4.imshow(tiles[-1]) ## last tile","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:12:37.271146Z","iopub.execute_input":"2022-08-20T10:12:37.2715Z","iopub.status.idle":"2022-08-20T10:12:38.275443Z","shell.execute_reply.started":"2022-08-20T10:12:37.271469Z","shell.execute_reply":"2022-08-20T10:12:38.274603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset,Sampler,DataLoader,SubsetRandomSampler\nfrom torchvision import models","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:12:40.459274Z","iopub.execute_input":"2022-08-20T10:12:40.459655Z","iopub.status.idle":"2022-08-20T10:12:40.465234Z","shell.execute_reply.started":"2022-08-20T10:12:40.459616Z","shell.execute_reply":"2022-08-20T10:12:40.464275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Count boxes per image\ndct={'imgid':[],'imglabels':[],'counts':[],'label':[]}\nfor i,row in df.iterrows():\n    ImgC=make_classes(row.imglabel,row.tile_path)\n    count=len(ImgC.boxes)\n    imgid=row.image_id\n    if imgid in dct['imgid']:\n        idx=dct['imgid'].index(imgid)\n        dct['imglabels'][idx].append(row.imglabel)\n        dct['counts'][idx]+=count\n    else:\n        dct['imgid'].append(imgid)\n        dct['imglabels'].append([row.imglabel])\n        dct['counts'].append(count)\n        dct['label'].append(int(row.label=='CE'))\ncdf=pd.DataFrame(dct)\ncdf.sort_values('counts',ascending=False,inplace=True)\n\n## Split images in train/valid so same n boxes of each class\ntrain_imglabels=[]\nvalid_imglabels=[]\ntrain_count=[0,0]\nvalid_count=[0,0]\nsplit=0.2\nfor _,row in cdf.iterrows():\n    i=row.label\n    if train_count[i]==0 or valid_count[i]/(valid_count[i]+train_count[i])>split:\n        train_imglabels+=row.imglabels\n        train_count[i]+=row['counts']\n    else:\n        valid_imglabels+=row.imglabels\n        valid_count[i]+=row['counts']\nfor i in [0,1]:\n    print(train_count[i],valid_count[i],valid_count[i]/(valid_count[i]+train_count[i]))\nprint(train_count[0],train_count[1],train_count[0]/sum(train_count))\nprint(valid_count[0],valid_count[1],valid_count[0]/sum(valid_count))","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:14:41.707796Z","iopub.execute_input":"2022-08-20T20:14:41.70843Z","iopub.status.idle":"2022-08-20T20:14:43.936108Z","shell.execute_reply.started":"2022-08-20T20:14:41.708395Z","shell.execute_reply":"2022-08-20T20:14:43.935078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Get Dataset\nclass bdDataset(Dataset):\n    def __init__(self,df,imglabels):\n        cid_max=11\n        bsize_max=256*256\n        self.paths=[]\n        self.labels=[]\n        self.b_idxs=[]\n        self.b_meta=[] ## [center_id,H,W]\n        self.c_idxs=[]\n        self.c_meta=[] ## [1 or .25,hloc,wloc]\n        self.t_idxs=[]\n        self.t_meta=[] ## [hloc,wloc]\n        self.has_cell=[]\n        for imglabel in imglabels:\n            row=df.loc[df['imglabel']==imglabel].iloc[0]\n            ImgC=make_classes(imgid,row.tile_path)\n            for box in ImgC.boxes:\n                has_cell=len(box.cells)>0                \n                self.paths.append(row.tile_path)\n                self.labels.append(int(row.label=='CE'))\n                self.has_cell.append(int(has_cell))\n                self.b_idxs.append(box.idx)\n                self.b_meta.append([row.center_id/cid_max, box.size[0]/bsize_max, box.size[1]/bsize_max])\n                if False: ## PATCH\n                    self.c_idxs.append(0)                    \n                    self.c_meta.append(0)   \n                    self.t_idxs.append(0)                    \n                    self.t_meta.append(0)   \n                elif has_cell:\n                    self.c_idxs.append(box.c_idxs)\n                    self.c_meta.append([[1.]+cell.loc for cell in box.cells])\n                    self.t_idxs.append(box.tc_idxs)                    \n                    self.t_meta.append([])\n                    for cell in box.cells:\n                        self.t_meta[-1].append([ctile.loc for ctile in cell.ctiles])             \n                else:\n                    self.c_idxs.append(box.tb_idxs)\n                    self.c_meta.append([[.25]+btile.loc for btile in box.btiles])\n                    self.t_idxs.append(0)                    \n                    self.t_meta.append(0)                    \n                    \n    def __len__(self):\n        return len(self.labels)\n    \n    def __getitem__(self,i):\n        tiles=np.load(self.paths[i])\n        has_cell=self.has_cell[i]\n        b_tile=tiles[self.b_idxs[i]].transpose(2,0,1)/255\n#         ## PATCH\n#         c_tiles=0\n#         t_tiles=0\n        c_tiles=tiles[self.c_idxs[i][0]:self.c_idxs[i][1]].transpose(0,3,1,2)/255\n        t_tiles=tiles[self.t_idxs[i][0]:self.t_idxs[i][1]].transpose(0,3,1,2)/255 if has_cell else 0\n        return self.paths[i],self.b_idxs[i],b_tile,self.b_meta[i],c_tiles,self.c_meta[i],t_tiles,self.t_meta[i],self.labels[i]\n\ntrain_dataset=bdDataset(df,train_imglabels)\nvalid_dataset=bdDataset(df,valid_imglabels)\nprint(len(train_dataset),len(valid_dataset))","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:14:48.606561Z","iopub.execute_input":"2022-08-20T20:14:48.607171Z","iopub.status.idle":"2022-08-20T20:14:49.956942Z","shell.execute_reply.started":"2022-08-20T20:14:48.607137Z","shell.execute_reply":"2022-08-20T20:14:49.955903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Get DataLoaders\ndef my_collate(batch):\n    # imgpaths,b_idxs,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels\n    n_batch=len(batch)\n    n_outs=len(batch[0])\n    outs=[]\n    for j in range(n_outs):\n        jouts=[batch[i][j] for i in range(n_batch)]\n        outs.append(jouts)\n    imgpaths,b_idxs,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels=outs\n    b_tiles=[torch.from_numpy(o).unsqueeze(0) for o in b_tiles]\n    b_tiles=torch.cat(b_tiles,dim=0).float() ## tensor(n_batch*img)\n    b_metas=[torch.FloatTensor(o).unsqueeze(0) for o in b_metas]\n    b_metas=torch.cat(b_metas,dim=0) ## tensor(n_batch*3)\n#     ## PATCH\n#     c_tiles=torch.empty(0)\n#     c_metas=torch.empty(0)   \n#     t_tiles=torch.empty(0)\n#     t_metas=torch.empty(0) \n    c_tiles=[torch.from_numpy(o) for o in c_tiles]\n    c_tiles=torch.cat(c_tiles,dim=0).float() ## tensor(sum(n_cells)*img)\n    c_metas=[torch.FloatTensor(o) for o in c_metas] ## list(n_batch)[tensor(n_cells,3)]\n    if t_metas[0]!=0:\n        t_tiles=[torch.from_numpy(o) for o in t_tiles]\n        t_tiles=torch.cat(t_tiles,dim=0).float() ## tensor(sum(n_tiles)*img)\n        tmp_t_metas=[]\n        for i in range(n_batch):\n            tmp_t_metas.append([torch.FloatTensor(o) for o in t_metas[i]])\n        t_metas=tmp_t_metas ## list(n_batch)[list(n_cells)[tensor(n_tiles,3)]]\n    else:\n        t_tiles=torch.empty(0)\n        t_metas=torch.empty(0)\n    labels=torch.tensor(labels) ## tensor(n_batch)\n    return [imgpaths,b_idxs,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels]\n\n## split boxes with/without cells in separate batches\nclass my_sampler(Sampler):\n    def __init__(self,split_indices,batch_size):\n        self.split_indices=split_indices ## list of list of indices, batches created per sublists\n        self.batch_size=batch_size\n        self.batches={}\n        self.n_batches=0\n        self.generate_batches()\n    def generate_batches(self):\n        batch_idx=0\n        for indices in self.split_indices:\n            n=len(indices)\n            n_batches=n//self.batch_size+1\n            if n>0 and n%self.batch_size==0:\n                n_batches-=1\n            batches=np.array_split(np.random.permutation(indices),n_batches)\n            for batch in batches:\n                self.batches[batch_idx]=batch\n                batch_idx+=1\n        self.n_batches=batch_idx\n    def __len__(self):\n        return self.n_batches\n    def __iter__(self):\n        self.generate_batches()\n        batch_order=np.random.permutation(np.arange(self.n_batches))\n        for i in batch_order:\n            yield self.batches[i]\n\nbatch_size=2\ndataloaders={}\nfor phase,dataset in zip(['train','valid'],[train_dataset,valid_dataset]):\n    yescell=[i for i,j in enumerate(dataset.has_cell) if j]\n    nocell=[i for i,j in enumerate(dataset.has_cell) if not j]\n    sampler=my_sampler([yescell,nocell],batch_size)\n    dataloaders[phase]=DataLoader(dataset,batch_sampler=sampler,collate_fn=my_collate)\n    \n# dataloaders={'train':DataLoader(train_dataset,batch_size=batch_size,shuffle=True,collate_fn=my_collate),\n#              'valid':DataLoader(valid_dataset,batch_size=batch_size,shuffle=True,collate_fn=my_collate)}\nprint(len(dataloaders['train']),len(dataloaders['valid']))","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:14:55.453567Z","iopub.execute_input":"2022-08-20T20:14:55.454116Z","iopub.status.idle":"2022-08-20T20:14:55.485742Z","shell.execute_reply.started":"2022-08-20T20:14:55.454079Z","shell.execute_reply":"2022-08-20T20:14:55.483865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## For testing\nimgpaths,b_idxs,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels=next(iter(dataloaders['valid']))","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:15:26.344286Z","iopub.execute_input":"2022-08-20T10:15:26.344691Z","iopub.status.idle":"2022-08-20T10:15:26.418699Z","shell.execute_reply.started":"2022-08-20T10:15:26.344657Z","shell.execute_reply":"2022-08-20T10:15:26.417702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## For testing\nimgpaths,b_idxs,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels=next(iter(dataloaders['valid']))\nbidx=0\ncidx=0\nprint(imgpaths[bidx])\nprint(b_idxs[bidx])\nprint(\"bt\",b_tiles.shape)\nprint(\"bm\",b_metas.shape,b_metas[bidx])\nprint(\"ct\",c_tiles.shape)\nprint(\"cm\",len(c_metas[bidx]),c_metas[bidx][cidx])\nif len(t_metas):\n    print(\"tt\",t_tiles[bidx].shape)\n    print(\"tm\",len(t_metas[bidx][cidx]),t_metas[bidx][cidx][0])\nelse:\n    print(t_tiles)\n    print(t_metas)\nprint(\"l\",labels[bidx])","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:15:28.719204Z","iopub.execute_input":"2022-08-20T10:15:28.719572Z","iopub.status.idle":"2022-08-20T10:15:28.796937Z","shell.execute_reply.started":"2022-08-20T10:15:28.71954Z","shell.execute_reply":"2022-08-20T10:15:28.79588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ## Get DataLoaders\n# batch_size=16\n# #batch_size=96\n# validation_split=.2\n# shuffle_dataset=True\n# random_seed=42\n\n# dataset_size=len(dataset)\n# indices=list(range(dataset_size))\n# split=int(np.floor(validation_split*dataset_size))\n# if shuffle_dataset :\n#     np.random.seed(random_seed)\n#     np.random.shuffle(indices)\n# train_indices,val_indices=indices[split:],indices[:split]\n# train_sampler=SubsetRandomSampler(train_indices)\n# valid_sampler=SubsetRandomSampler(val_indices)\n\n# dataloaders={'train':DataLoader(dataset,batch_size=batch_size,sampler=train_sampler),\n#              'valid':DataLoader(dataset,batch_size=batch_size,sampler=valid_sampler)}\n# print(len(dataloaders['train']),len(dataloaders['valid']))","metadata":{"execution":{"iopub.status.busy":"2022-08-20T01:14:43.647449Z","iopub.execute_input":"2022-08-20T01:14:43.648141Z","iopub.status.idle":"2022-08-20T01:14:43.652757Z","shell.execute_reply.started":"2022-08-20T01:14:43.648104Z","shell.execute_reply":"2022-08-20T01:14:43.651728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_densemodel():\n    model=models.densenet121(pretrained=True)\n    ## turn off grad descent\n    for name,param in model.named_parameters():\n        param.requires_grad=False\n    ## turn off classifier\n    model.classifier=nn.Identity()\n    return model\ndef printmodelfeatures(model,first=5,last=5):\n    n_feats=sum(1 for f in model.named_parameters())\n    if first>0:\n        print('- first')\n    for i,(name,params) in enumerate(model.named_parameters()):\n        if i==n_feats-5:\n            print('- last')\n        if i<first or n_feats-i<=5:\n            print(name,' ',list(params.shape),' ',params.requires_grad)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:15:32.504538Z","iopub.execute_input":"2022-08-20T10:15:32.505682Z","iopub.status.idle":"2022-08-20T10:15:32.513359Z","shell.execute_reply.started":"2022-08-20T10:15:32.505633Z","shell.execute_reply":"2022-08-20T10:15:32.512197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class mybdmodel(nn.Module):\n    def __init__(self):\n        super(mybdmodel,self).__init__()\n        ## Sub-features, sf*sf_iter total (pick sf_iter chunks of sf)\n        self.sf=64 ## n_sub_features\n        self.sf_iter=4 ## iter_sub_features \n        \n        ## classifier\n        self.classifier=nn.Linear(256,2)\n        \n        ## box features\n        self.dense_box=load_densemodel() ## out 1024\n        self.linear_box=nn.Sequential(\n#             nn.Dropout(0.3),\n            nn.Linear(1024+3,256), ## 1024 box features + 3 box meta (center_id,H,W)\n            nn.ReLU())\n#                       ,\n#             nn.Dropout(0.3)) ## out 512\n        ## box-cell combine\n        self.combiner_box_cell=nn.Sequential(\n            nn.Linear(256+self.sf+3,256), ## 512 box features + sf cell features + 3 cell meta (size,loc)\n            nn.ReLU()) ## out 512\n        \n        ## cell features\n        self.dense_cell=load_densemodel() ## out 1024 \n        self.linear_cell=nn.Sequential(\n#             nn.Dropout(0.3),\n            nn.Linear(1024+1,256), ## 1024 cell features + center_id\n            nn.ReLU())\n#                      ,\n#             nn.Dropout(0.3)) ## out 512\n        ## cell-tile combine\n        self.combiner_cell_tile=nn.Sequential(\n            nn.Linear(256+self.sf+2,self.sf*self.sf_iter), ## 512 cell features + sf tile features + 2 tile meta (loc)\n            nn.ReLU()) ## out sf_tot\n        \n        ## tile features (used also by cell if cell is tile)\n        self.dense_tile=load_densemodel() ## out 1024\n        self.linear_tile=nn.Sequential(\n#             nn.Dropout(0.3),\n            nn.Linear(1024+1,self.sf*self.sf_iter), ## 1024 tile features + center_id\n            nn.ReLU())\n#                       ,\n#             nn.Dropout(0.3)) ## out sf_tot\n        \n    def get_init_features(self,x,meta,dense,linear):\n        x=dense(x)\n        x=torch.cat([meta,x],dim=1)\n        return linear(x)\n            \n    def get_max_features(self,x,meta,split):\n        ## cell - x: sum(n_cells)*sf_tot, split=n_cells, N=n_boxs, n_i=n_cells_i\n        ## tile - x: sum(n_tiles_percell)*sf_tot, split=n_tiles_percell, N=n_cells, n_i=n_tiles_percell_i\n        N=len(split)\n        x=list(torch.split(x,split,dim=0)) ## list(N)[n_i*sf_tot]\n        for i in range(N):\n            x[i]=list(torch.split(x[i],self.sf,dim=1)) ## list(sf_iter)[n_i*sf]\n            xsums=[torch.sum(xsf,dim=1) for xsf in x[i]] ## list(sf_iter)[n_i]\n            max_idxs=[]\n            for xsum in xsums:\n                _,imax=torch.max(xsum,dim=0)\n                max_idxs.append(imax.cpu().data.numpy())\n            for j in range(self.sf_iter):\n                imax=max_idxs[j]\n                xmax=x[i][j][imax] ## sf                \n                meta_max=meta[i][imax].squeeze(dim=0) \n                x[i][j]=torch.cat([meta_max,xmax],dim=0).unsqueeze(1) ## (sf+meta)*1\n            x[i]=torch.cat(x[i],dim=1).unsqueeze(0) ## 1*(sf+meta)*sf_iter\n        x=torch.cat(x,dim=0) ## N*(sf+meta)*sf_iter\n        x=[xsf.squeeze(dim=2) for xsf in torch.split(x,1,dim=2)] ## list(sf_iter)[N*(sf+meta)]\n        return x\n    \n    def get_combined_features(self,x,list_sf,combiner):\n        ## box/cell - x: n_boxs*512 / list_sf: list(sf_iter)[n_boxs*(sf+3meta)] - n=n_boxs / n_out=512\n        ## cell/tile - x: n_cells*512 / list_sf: list(sf_iter)[n_cells*(sf+2meta)] - n=n_cells_i / n_out=sf\n        xc=[]\n        for sf in list_sf:\n            xsf=torch.cat([sf,x],dim=1) ## n*(512+sf+meta)\n            xsf=combiner(xsf) ## n*n_out\n            xc.append(xsf.unsqueeze(-1)) ## n*n_out*1\n        xc=torch.cat(xc,dim=2) ## n*n_out*sf_iter\n        xc,_=torch.max(xc,dim=2) ## n*n_out\n        return xc\n    \n    def forward(self,b,b_meta,c,c_meta,t,t_meta):\n        ## Count objects\n        has_cell=len(t_tiles)>0\n        n_boxs=b.shape[0]\n        n_cells=[cm.shape[0] for cm in c_meta]\n        if has_cell:\n            n_tiles_perbox=[]\n            n_tiles_percell=[]\n            for i in range(n_boxs):\n                n_tiles_percell.append([tm.shape[0] for tm in t_meta[i]])\n                n_tiles_perbox.append(sum(n_tiles_percell[-1]))\n        \n        ## Get box init features\n        b=self.get_init_features(b,b_meta,self.dense_box,self.linear_box) ## n_boxs*512\n        \n        ## Get cell init features\n        cid_meta=[]\n        for i in range(n_boxs):\n            cid_meta+=[b_meta[i][0].unsqueeze(0)]*n_cells[i]\n        cid_meta=torch.cat(cid_meta,dim=0).unsqueeze(1) ## sum(n_cells)*1\n        if has_cell:\n            c=self.get_init_features(c,cid_meta,self.dense_cell,self.linear_cell) ## sum(n_cells)*512\n            \n            ## Get tile init features\n            cid_meta=[]\n            for i in range(n_boxs):\n                cid_meta+=[b_meta[i][0].unsqueeze(0)]*n_tiles_perbox[i]\n            cid_meta=torch.cat(cid_meta,dim=0).unsqueeze(1) ## sum(n_tiles)*1\n            t=self.get_init_features(t,cid_meta,self.dense_tile,self.linear_tile) ## sum(n_tiles)*sf\n            \n            ## Split (cell and tile) per box\n            c=list(torch.split(c,n_cells,dim=0)) ## list(n_boxs)[n_cells*512]\n            t=list(torch.split(t,n_tiles_perbox,dim=0)) ## list(n_boxs)[n_tiles_perbox*512]\n            for i in range(n_boxs):\n                \n                ## Get tile max features\n                t[i]=self.get_max_features(t[i],t_meta[i],n_tiles_percell[i]) ## list(sf_iter)[n_cells*(sf+2meta)]\n                \n                ## Get cell+tile features\n                c[i]=self.get_combined_features(c[i],t[i],self.combiner_cell_tile) ## n_cells*sf\n            c=torch.cat(c,dim=0) ## sum(n_cells)*sf\n\n        else:\n            c=self.get_init_features(c,cid_meta,self.dense_tile,self.linear_tile) ## sum(n_cells)*sf\n            \n        ## Get cell max features\n        c=self.get_max_features(c,c_meta,n_cells) ## list(sf_iter)[n_boxs*(sf+3meta)]\n        \n        ## Get box+cell features\n        b=self.get_combined_features(b,c,self.combiner_box_cell) ## n_boxs*512\n        \n        ## Classify\n        if False: ## skip cells and tiles\n            b=torch.cat([torch.zeros(n_boxs,self.sf+3).to(device),b],dim=1) ## n_boxs*516\n            b=self.combiner_box_cell(b) ## n_boxs*512\n        return self.classifier(b)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:16:20.762037Z","iopub.execute_input":"2022-08-20T20:16:20.762601Z","iopub.status.idle":"2022-08-20T20:16:20.789829Z","shell.execute_reply.started":"2022-08-20T20:16:20.76255Z","shell.execute_reply":"2022-08-20T20:16:20.788774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## For testing\ndevice=torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nmodel=mybdmodel().to(device)\n# # model.load_state_dict(torch.load(\"../input/mybdnw/model_tiles_boxcell.pt\",map_location=torch.device(device)))\n# # model.eval()\n# print(next(model.parameters()).device)\n# printmodelfeatures(model,5,5)\n# print(\"\\n%s\"%model.dense_box.features.conv0)\n# print(model.classifier,'\\n')\n# printmodelfeatures(model,0,5)\n# print('\\n',model.classifier)","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:15:55.540559Z","iopub.execute_input":"2022-08-20T10:15:55.541556Z","iopub.status.idle":"2022-08-20T10:15:56.380756Z","shell.execute_reply.started":"2022-08-20T10:15:55.54152Z","shell.execute_reply":"2022-08-20T10:15:56.379775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## For testing\nimgpaths,b_idxs,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels=next(iter(dataloaders['valid']))\nbidx=0\ncidx=0\nprint(imgpaths[bidx])\nprint(b_idxs[bidx])\nprint(\"bt\",b_tiles.shape)\nprint(\"bm\",b_metas.shape,b_metas[bidx])\nprint(\"ct\",c_tiles.shape)\nprint(\"cm\",len(c_metas[bidx]),c_metas[bidx][cidx])\nif len(t_metas):\n    print(\"tt\",t_tiles[bidx].shape)\n    print(\"tm\",len(t_metas[bidx][cidx]),t_metas[bidx][cidx][0])\nelse:\n    print(t_tiles)\n    print(t_metas)\nprint(\"l\",labels[bidx])","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:15:59.049171Z","iopub.execute_input":"2022-08-20T10:15:59.049546Z","iopub.status.idle":"2022-08-20T10:15:59.098485Z","shell.execute_reply.started":"2022-08-20T10:15:59.049512Z","shell.execute_reply":"2022-08-20T10:15:59.097504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\nb_tiles=b_tiles.to(device)\nb_metas=b_metas.to(device)\nc_tiles=c_tiles.to(device)\nt_tiles=t_tiles.to(device)\nlabels=labels.to(device)\nfor i in range(len(c_metas)):\n    c_metas[i]=c_metas[i].to(device)\n    if len(t_tiles)>0:\n        for j in range(len(t_metas[i])):\n            t_metas[i][j]=t_metas[i][j].to(device)\noutputs=model(b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas)\noutputs=torch.nn.Softmax(dim=1)(outputs).cpu().data.numpy()\noutputs","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:16:01.777413Z","iopub.execute_input":"2022-08-20T10:16:01.777792Z","iopub.status.idle":"2022-08-20T10:16:01.943715Z","shell.execute_reply.started":"2022-08-20T10:16:01.77776Z","shell.execute_reply":"2022-08-20T10:16:01.94264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Get score values\ndef get_scores(outputs,labels,loss,dct={}):\n    outputs=torch.nn.Softmax(dim=1)(outputs).cpu().data.numpy()\n    labels=labels.cpu().data.numpy()\n    loss=loss.item()\n    if 'loss' not in dct: dct['loss']=0\n    dct['loss']+=loss\n    for out,lab in zip(outputs,labels):\n        if lab not in dct:\n            dct[lab]={'count':0,'acc':0,'accF':0,'score':0,'scoreI':0}\n        dct[lab]['count']+=1\n        dct[lab]['accF']+=out[lab]\n        dct[lab]['score']+=-np.log(max(min(out[lab],1-1e-15),1e-15))\n        if np.where(out==max(out))==lab:\n            dct[lab]['acc']+=1\n            dct[lab]['scoreI']+=-np.log(1-1e-15)\n        else:\n            dct[lab]['scoreI']+=-np.log(1e-15)\n    ## compute and replace running scores (except for loss)\n    if 0 in dct and 1 in dct:\n        for key in ['acc','accF','score','scoreI']:\n            dct[key]=0.5*dct[0][key]/dct[0]['count']+0.5*dct[1][key]/dct[1]['count']\n    return dct\n\n## Print score values\ndef print_scores(dct,printlabel):\n    stri=printlabel+': '\n    counts=[dct[0]['count'],dct[1]['count'],dct[0]['count']+dct[1]['count']]\n#    for key in ['count','loss','acc','accF','score','scoreI']:\n    for key in ['count','loss','acc','score']:\n        stri+=key+'('\n        for lab in [0,1,'comb']:\n            if lab=='comb':\n                if key=='count': stri+=\"%s) \"%counts[2]\n                elif key=='loss': stri+=\"%.3f) \"%(dct[key]/counts[2])\n                else: stri+=\"%.2f) \"%dct[key]\n            else:\n                if key=='count': stri+=\"%s,\"%counts[lab]\n                elif key=='loss': continue\n                else: stri+=\"%.2f,\"%(dct[lab][key]/counts[lab])\n    print(stri[:-1])","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:16:05.949625Z","iopub.execute_input":"2022-08-20T10:16:05.950316Z","iopub.status.idle":"2022-08-20T10:16:05.966346Z","shell.execute_reply.started":"2022-08-20T10:16:05.950281Z","shell.execute_reply":"2022-08-20T10:16:05.965331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Reinit\ndevice=torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nmodel=mybdmodel()\nmodel=model.to(device)\nparams_to_update=[]\nfor name,param in model.named_parameters():\n    if param.requires_grad==True:\n        params_to_update.append(param)\n        print(\"\\t\",name)\n#optimizer=torch.optim.SGD(params_to_update,lr=0.001,momentum=0.9)\noptimizer=torch.optim.AdamW(params_to_update,lr=1e-4)\n#criterion=nn.CrossEntropyLoss(weight=torch.tensor([0.7,0.3]).to(device))\nnum_epochs=1\nscoredct={'train':[],'valid':[]} ## scores per phase and epoch\nbest_model_wts=copy.deepcopy(model.state_dict())\nbest_score=1e9","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:16:14.268141Z","iopub.execute_input":"2022-08-20T10:16:14.268561Z","iopub.status.idle":"2022-08-20T10:16:15.553367Z","shell.execute_reply.started":"2022-08-20T10:16:14.268527Z","shell.execute_reply":"2022-08-20T10:16:15.552379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.load_state_dict(torch.load(\"../input/mybdnw/model_boom_statedct.pt\",map_location=torch.device(device)))\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs=3\n## Set all parameters to trainable\nfor name,param in model.named_parameters():\n    param.requires_grad=True","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:16:24.066014Z","iopub.execute_input":"2022-08-20T10:16:24.066386Z","iopub.status.idle":"2022-08-20T10:16:24.078773Z","shell.execute_reply.started":"2022-08-20T10:16:24.066355Z","shell.execute_reply":"2022-08-20T10:16:24.077753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for name,param in model.named_parameters():\n# #     if 'dense_box' in name:\n#         param.requires_grad=False","metadata":{"execution":{"iopub.status.busy":"2022-08-20T01:33:44.859235Z","iopub.execute_input":"2022-08-20T01:33:44.860184Z","iopub.status.idle":"2022-08-20T01:33:44.871271Z","shell.execute_reply.started":"2022-08-20T01:33:44.860127Z","shell.execute_reply":"2022-08-20T01:33:44.870188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# del criterion\n# del b_tiles\n# del c_tiles\n# del t_tiles\n# del t_metas\ntorch.cuda.empty_cache()\ngc.collect()\nlws=[0.7,0.3]","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:13:17.923483Z","iopub.execute_input":"2022-08-20T20:13:17.924064Z","iopub.status.idle":"2022-08-20T20:13:18.713719Z","shell.execute_reply.started":"2022-08-20T20:13:17.924021Z","shell.execute_reply":"2022-08-20T20:13:18.712741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"next_epoch=len(scoredct['valid'])\n## Training\nsince=time.time()\n## Loop on epochs\nfor epoch in range(next_epoch,next_epoch+num_epochs):\n    print('Epoch {}/{}'.format(epoch,next_epoch+num_epochs-1))\n    if epoch<2:\n        lws=[0.7,0.3]\n#     elif epoch==1:\n#         pass\n# #         for name,param in model.named_parameters():\n# #             param.requires_grad=True\n    else:\n        tdct=scoredct['valid'][-1]\n        s0=tdct[0]['score']/tdct[0]['count']\n        s1=tdct[1]['score']/tdct[1]['count']\n        c=0.1*(s1-s0)/(s1+s0)\n#         print(s0,s1,c)\n        lws=[lws[0]-c,lws[1]+c]\n    print(\"loss weights: [%.2f,%.2f]\"%(lws[0],lws[1]))\n    criterion=nn.CrossEntropyLoss(weight=torch.tensor(lws).float().to(device))\n    ## Loop on phase\n    for phase in ['train','valid']:\n        sdct={} ## scores for this phase/epoch\n        if phase=='train': model.train()\n        else: model.eval()\n        ## Loop on batches\n        for i,(tpath,tidx,b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas,labels) in enumerate(dataloaders[phase]):\n            b_tiles=b_tiles.to(device)\n            b_metas=b_metas.to(device)\n            c_tiles=c_tiles.to(device)\n            t_tiles=t_tiles.to(device)\n            labels=labels.to(device)\n            for i in range(len(c_metas)):\n                c_metas[i]=c_metas[i].to(device)\n                if len(t_tiles)>0:\n                    for j in range(len(t_metas[i])):\n                        t_metas[i][j]=t_metas[i][j].to(device)\n            optimizer.zero_grad()\n            with torch.set_grad_enabled(phase=='train'):\n                ## Get results\n                outputs=model(b_tiles,b_metas,c_tiles,c_metas,t_tiles,t_metas)\n                loss=criterion(outputs,labels)\n                ## Update and print scores\n                sdct=get_scores(outputs,labels,loss,sdct) \n                if i>0 and i%80==0:\n                    printlabel=\"- %s%s/%s\"%(phase,i,len(dataloaders[phase])-1)\n                    print_scores(sdct,printlabel)\n                ## Learn\n                if phase=='train':\n                    loss.backward()\n                    optimizer.step()\n            del b_tiles\n            del c_tiles\n            del t_tiles\n            del t_metas\n            gc.collect()\n        ## Print and save scores\n        print('\\033[91m',end=\"\")\n        print_scores(sdct,phase)\n        print('\\033[0m',end=\"\")\n        scoredct[phase].append(sdct)\n    ## Save model if improved\n    if scoredct['valid'][epoch]['score']<best_score:\n        print(\"improved score\")\n        best_score=scoredct['valid'][epoch]['score']\n        best_model_wts=copy.deepcopy(model.state_dict())\n    print()\n## Summary\ntime_elapsed=time.time() - since\nprint('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed//60,time_elapsed%60))\nprint('Best score: {:4f}'.format(best_score))\n## Update model to best\nmodel.load_state_dict(best_model_wts)\nprint(\"Done\")","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:16:53.463406Z","iopub.execute_input":"2022-08-20T10:16:53.463783Z","iopub.status.idle":"2022-08-20T19:51:38.494306Z","shell.execute_reply.started":"2022-08-20T10:16:53.46375Z","shell.execute_reply":"2022-08-20T19:51:38.493287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"savejsonfile(scoredct,\"scoredct.json\")\ntorch.save(model.state_dict(),'model_boom_statedct.pt')","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:11:57.603867Z","iopub.execute_input":"2022-08-20T20:11:57.60424Z","iopub.status.idle":"2022-08-20T20:11:58.080956Z","shell.execute_reply.started":"2022-08-20T20:11:57.604209Z","shell.execute_reply":"2022-08-20T20:11:58.07467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tdct=scoredct['train']\nvdct=scoredct['valid']\ntcounts=[tdct[0][0]['count'],tdct[0][1]['count'],tdct[0][0]['count']+tdct[0][1]['count']]\nvcounts=[vdct[0][0]['count'],vdct[0][1]['count'],vdct[0][0]['count']+vdct[0][1]['count']]\nxs=list(range(len(scoredct['valid'])))\nlosses=[]\naccs=[]\nscores=[]\n\nfor i in xs:\n    losses.append([tdct[i]['loss']/tcounts[2],vdct[i]['loss']/vcounts[2]])\n    accs.append([tdct[i]['acc'],vdct[i]['acc'],\n                 tdct[i][0]['acc']/tcounts[0],vdct[i][0]['acc']/vcounts[0],\n                 tdct[i][1]['acc']/tcounts[1],vdct[i][1]['acc']/vcounts[1]])\n    scores.append([tdct[i]['score'],vdct[i]['score'],\n                 tdct[i][0]['score']/tcounts[0],vdct[i][0]['score']/vcounts[0],\n                 tdct[i][1]['score']/tcounts[1],vdct[i][1]['score']/vcounts[1]])\nfig,(ax1,ax2,ax3)=plt.subplots(1,3,figsize=(21,7))\nax1.plot(xs,losses,label=['train','valid'])\nax2.plot(xs,accs,label=['train','valid','train0','valid0','train1','valid1'])\nax3.plot(xs,scores,label=['train','valid','train0','valid0','train1','valid1'])\nax1.legend()\nax2.legend()\nax3.legend()","metadata":{"execution":{"iopub.status.busy":"2022-08-20T20:12:08.021563Z","iopub.execute_input":"2022-08-20T20:12:08.022303Z","iopub.status.idle":"2022-08-20T20:12:08.558785Z","shell.execute_reply.started":"2022-08-20T20:12:08.022265Z","shell.execute_reply":"2022-08-20T20:12:08.557612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model_scripted=torch.jit.script(model)\n# model_scripted.save('model_boxcell.pt')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2022-08-18T16:59:48.568703Z","iopub.execute_input":"2022-08-18T16:59:48.569083Z","iopub.status.idle":"2022-08-18T16:59:48.829778Z","shell.execute_reply.started":"2022-08-18T16:59:48.569052Z","shell.execute_reply":"2022-08-18T16:59:48.828726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2022-08-20T10:03:36.624114Z","iopub.execute_input":"2022-08-20T10:03:36.624485Z","iopub.status.idle":"2022-08-20T10:03:37.810109Z","shell.execute_reply.started":"2022-08-20T10:03:36.624453Z","shell.execute_reply":"2022-08-20T10:03:37.808869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EVAL","metadata":{}},{"cell_type":"code","source":"# device=torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n# model=mybdmodel()\n# model.to(device)\n# model.load_state_dict(torch.load(\"../input/mybdnw/model_tiles_boxcell.pt\",map_location=torch.device(device)))\n# model.eval()\n# a=1","metadata":{"execution":{"iopub.status.busy":"2022-08-18T18:25:12.373693Z","iopub.execute_input":"2022-08-18T18:25:12.37411Z","iopub.status.idle":"2022-08-18T18:25:13.344791Z","shell.execute_reply.started":"2022-08-18T18:25:12.374074Z","shell.execute_reply":"2022-08-18T18:25:13.343936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:05:08.084049Z","iopub.execute_input":"2022-08-18T17:05:08.084444Z","iopub.status.idle":"2022-08-18T17:05:08.272497Z","shell.execute_reply.started":"2022-08-18T17:05:08.084387Z","shell.execute_reply":"2022-08-18T17:05:08.271458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# batch_size=1\n# dataloaders={'train':DataLoader(train_dataset,batch_size=batch_size,shuffle=True,collate_fn=my_collate),\n#              'valid':DataLoader(valid_dataset,batch_size=batch_size,shuffle=True,collate_fn=my_collate)}\n# print(len(dataloaders['train']),len(dataloaders['valid']))\n# criterion=nn.CrossEntropyLoss(weight=torch.tensor([0.5,0.5]).to(device))\n\n# dct={'pid':[],'imglabel':[],'t_idx':[],'out0':[],'out1':[],'prob0':[],'prob1':[],'acc':[],'score':[],'label':[]}\n# for phase in ['valid']:#['train','valid']:\n#     for i,(paths,t_idxs,b_tiles,b_metas,c_tiles,c_locs,labels) in enumerate(dataloaders[phase]):\n#         if i>0 and i%100==0:\n#             print(i)\n#         ## Get results\n#         b_tiles=b_tiles.float().to(device)\n#         b_metas=b_metas.float().to(device)\n#         c_tiles=c_tiles.to(device)\n#         c_locs=[c.to(device) for c in c_locs]\n#         labels=labels.to(device)\n#         outputs=model(b_tiles,b_metas,c_tiles,c_locs)\n#         loss=criterion(outputs,labels)\n#         ## Store results\n#         outs=outputs[0].cpu().data.numpy()\n#         probs=torch.nn.Softmax(dim=1)(outputs)[0].cpu().data.numpy()\n#         lab=labels[0].cpu().data.numpy()\n#         dct['imglabel'].append(paths[0].rsplit('/',1)[1].split('.')[0])\n#         dct['pid'].append(dct['imglabel'][-1].split('_')[0])\n#         dct['t_idx'].append(t_idxs[0])\n#         dct['out0'].append(outs[0])\n#         dct['out1'].append(outs[1])\n#         dct['prob0'].append(probs[0])\n#         dct['prob1'].append(probs[1])\n#         dct['acc'].append(int(np.where(outs==max(outs))==lab))\n#         dct['score'].append(-np.log(max(min(probs[lab],1-1e-15),1e-15)))\n#         dct['label'].append(lab)\n    \n# rdf=pd.DataFrame(dct)\n# rdf.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-18T18:26:43.494182Z","iopub.execute_input":"2022-08-18T18:26:43.494598Z","iopub.status.idle":"2022-08-18T18:28:28.81642Z","shell.execute_reply.started":"2022-08-18T18:26:43.494566Z","shell.execute_reply":"2022-08-18T18:28:28.815246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def get_results(rdf):\n#     rdf0=rdf[rdf['label']==0]\n#     rdf1=rdf[rdf['label']==1]\n#     dct={'acc':[],'score':[]}\n#     for res in ['acc','score']:\n#         for i,df in enumerate([rdf0,rdf1,rdf]):\n#             if i==2:\n#                 dct[res].append(0.5*sum(dct[res]))\n#             else:\n#                 dct[res].append(np.mean(df[res]))\n#     return dct['acc'],dct['score']\n    \n# print(get_results(rdf))","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:56:37.651007Z","iopub.execute_input":"2022-08-18T17:56:37.651619Z","iopub.status.idle":"2022-08-18T17:56:37.666801Z","shell.execute_reply.started":"2022-08-18T17:56:37.651585Z","shell.execute_reply":"2022-08-18T17:56:37.665686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for cut in np.linspace(0.5,.73,10):\n#     nrdf=rdf[((rdf['prob0']>cut) | ((rdf['prob1']>cut)))]\n#     print(\"%.2f %.2f\"%(cut,len(nrdf)/len(rdf)),get_results(nrdf))","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:18:09.673602Z","iopub.execute_input":"2022-08-18T17:18:09.674592Z","iopub.status.idle":"2022-08-18T17:18:09.707504Z","shell.execute_reply.started":"2022-08-18T17:18:09.674554Z","shell.execute_reply":"2022-08-18T17:18:09.706431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# rdf.to_pickle('boxcell_results.pkl') ","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:18:32.50707Z","iopub.execute_input":"2022-08-18T17:18:32.507486Z","iopub.status.idle":"2022-08-18T17:18:32.516674Z","shell.execute_reply.started":"2022-08-18T17:18:32.507447Z","shell.execute_reply":"2022-08-18T17:18:32.515681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import pandas as pd\n# rdf=pd.read_pickle('../input/mybdnw/boxcell_results.pkl')\n# rdf.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:41:44.248362Z","iopub.execute_input":"2022-08-18T17:41:44.249364Z","iopub.status.idle":"2022-08-18T17:41:44.269202Z","shell.execute_reply.started":"2022-08-18T17:41:44.249313Z","shell.execute_reply":"2022-08-18T17:41:44.268267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# dct={'id':[],'count':[],'meanprob':[],'acc':[],'score':[],'label':[]}\n# mdct={}\n# for i,row in rdf.iterrows():\n#     tid=row.imglabel.rsplit('_',2)[0]\n#     if tid in mdct:\n#         mdct[tid].append(row.prob0)\n#     else:\n#         mdct[tid]=[row.label,row.prob0]\n# for tid,probs in mdct.items():\n#     dct['id'].append(tid)\n#     dct['count'].append(len(probs))\n#     mprob=np.mean(probs[1:])\n#     dct['meanprob'].append(mprob)\n#     if probs[0]==0:\n#         dct['acc'].append(int(mprob<.5))\n#         dct['score'].append(-np.log(max(min(mprob,1-1e-15),1e-15)))\n#     else:\n#         dct['acc'].append(int(mprob>.5))\n#         dct['score'].append(-np.log(max(min(1-mprob,1-1e-15),1e-15)))\n#     dct['label'].append(probs[0])\n\n# pdf=pd.DataFrame(dct)","metadata":{"execution":{"iopub.status.busy":"2022-08-18T18:32:45.600931Z","iopub.execute_input":"2022-08-18T18:32:45.602026Z","iopub.status.idle":"2022-08-18T18:32:45.664344Z","shell.execute_reply.started":"2022-08-18T18:32:45.601982Z","shell.execute_reply":"2022-08-18T18:32:45.663084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# dct={'id':[],'count':[],'maxprob':[],'acc':[],'score':[],'label':[]}\n# for i,row in rdf.iterrows():\n#     tid=row.imglabel.rsplit('_',2)[0]\n#     maxprob=max(row.prob0,row.prob1)\n# #    maxprob=maxprob if maxprob>0.95 else .5\n#     if tid in dct['id']:\n#         idx=dct['id'].index(tid)\n#         dct['count'][idx]+=1\n#         if maxprob>dct['maxprob'][idx]:\n#             dct['maxprob'][idx]=maxprob\n#             dct['acc'][idx]=row.acc\n#             dct['score'][idx]=row.score\n#     else:\n#         dct['id'].append(tid)\n#         dct['count'].append(1)\n#         dct['maxprob'].append(maxprob)\n#         dct['acc'].append(row.acc)\n#         dct['score'].append(row.score)\n#         dct['label'].append(row.label)\n\n# mdf=pd.DataFrame(dct)","metadata":{"execution":{"iopub.status.busy":"2022-08-18T18:32:47.235364Z","iopub.execute_input":"2022-08-18T18:32:47.235781Z","iopub.status.idle":"2022-08-18T18:32:47.303658Z","shell.execute_reply.started":"2022-08-18T18:32:47.235748Z","shell.execute_reply":"2022-08-18T18:32:47.30232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print(get_results(rdf))\n# print(get_results(pdf))\n# print(get_results(mdf))","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:58:29.47137Z","iopub.execute_input":"2022-08-18T17:58:29.472216Z","iopub.status.idle":"2022-08-18T17:58:29.487638Z","shell.execute_reply.started":"2022-08-18T17:58:29.472171Z","shell.execute_reply":"2022-08-18T17:58:29.486827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print(len(pdf),len(pdf[pdf['label']==0])/len(pdf),len(pdf[pdf['label']==1])/len(pdf))\n# print(len(rdf),len(rdf[rdf['label']==0])/len(rdf),len(rdf[rdf['label']==1])/len(rdf))","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:32:04.114459Z","iopub.execute_input":"2022-08-18T17:32:04.11488Z","iopub.status.idle":"2022-08-18T17:32:04.128517Z","shell.execute_reply.started":"2022-08-18T17:32:04.114842Z","shell.execute_reply":"2022-08-18T17:32:04.127366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for cut in np.linspace(0.5,.75,11):\n#     npdf=pdf[pdf['maxprob']>cut]\n#     print(\"%.2f %.2f\"%(cut,len(npdf)/len(pdf)),get_results(npdf))","metadata":{"execution":{"iopub.status.busy":"2022-08-18T17:26:04.543045Z","iopub.execute_input":"2022-08-18T17:26:04.543679Z","iopub.status.idle":"2022-08-18T17:26:04.577165Z","shell.execute_reply.started":"2022-08-18T17:26:04.543644Z","shell.execute_reply":"2022-08-18T17:26:04.575988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}