{"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":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:35:57.314179Z","iopub.execute_input":"2022-04-28T22:35:57.314648Z","iopub.status.idle":"2022-04-28T22:35:57.407764Z","shell.execute_reply.started":"2022-04-28T22:35:57.314515Z","shell.execute_reply":"2022-04-28T22:35:57.406984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Use the fastaiV2 version\nfrom fastai.vision.all import *\nfrom zipfile import ZipFile","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:35:57.410959Z","iopub.execute_input":"2022-04-28T22:35:57.411507Z","iopub.status.idle":"2022-04-28T22:36:00.121792Z","shell.execute_reply.started":"2022-04-28T22:35:57.411469Z","shell.execute_reply":"2022-04-28T22:36:00.121069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"debug = False","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:36:00.123199Z","iopub.execute_input":"2022-04-28T22:36:00.123448Z","iopub.status.idle":"2022-04-28T22:36:00.160306Z","shell.execute_reply.started":"2022-04-28T22:36:00.123414Z","shell.execute_reply":"2022-04-28T22:36:00.159526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Copy and extract the train file\nwith ZipFile('../input/carvana-image-masking-challenge/train.zip', 'r') as zip_ref:\n  zip_ref.extractall('')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:36:00.163246Z","iopub.execute_input":"2022-04-28T22:36:00.163463Z","iopub.status.idle":"2022-04-28T22:36:10.719556Z","shell.execute_reply.started":"2022-04-28T22:36:00.163438Z","shell.execute_reply":"2022-04-28T22:36:10.718618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with ZipFile('../input/carvana-image-masking-challenge/train_masks.zip', 'r') as zip_ref:\n  zip_ref.extractall('')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:36:10.727739Z","iopub.execute_input":"2022-04-28T22:36:10.729992Z","iopub.status.idle":"2022-04-28T22:36:11.753571Z","shell.execute_reply.started":"2022-04-28T22:36:10.729951Z","shell.execute_reply":"2022-04-28T22:36:11.752828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with ZipFile('../input/carvana-image-masking-challenge/sample_submission.csv.zip', 'r') as zip_ref:\n  zip_ref.extractall('')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:36:11.754862Z","iopub.execute_input":"2022-04-28T22:36:11.755118Z","iopub.status.idle":"2022-04-28T22:36:11.814925Z","shell.execute_reply.started":"2022-04-28T22:36:11.755081Z","shell.execute_reply":"2022-04-28T22:36:11.814318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with ZipFile('../input/carvana-image-masking-challenge/test.zip', 'r') as zip_ref:\n  zip_ref.extractall('')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:36:11.816120Z","iopub.execute_input":"2022-04-28T22:36:11.816383Z","iopub.status.idle":"2022-04-28T22:39:21.987255Z","shell.execute_reply.started":"2022-04-28T22:36:11.816345Z","shell.execute_reply":"2022-04-28T22:39:21.986434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#View the file\npath = Path('')\nfnames = get_image_files(path/'train')\nlbl_names = get_image_files(path/'train_masks')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:21.990860Z","iopub.execute_input":"2022-04-28T22:39:21.991072Z","iopub.status.idle":"2022-04-28T22:39:22.113302Z","shell.execute_reply.started":"2022-04-28T22:39:21.991046Z","shell.execute_reply":"2022-04-28T22:39:22.112636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#View train and mask file details\nprint (fnames[0],lbl_names[0])\nget_mask = lambda o:'train_masks/'+str(o.stem)+'_mask.gif' ","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:22.114491Z","iopub.execute_input":"2022-04-28T22:39:22.114718Z","iopub.status.idle":"2022-04-28T22:39:22.153929Z","shell.execute_reply.started":"2022-04-28T22:39:22.114684Z","shell.execute_reply":"2022-04-28T22:39:22.153107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_fn = fnames[random.randint(0,len(fnames))]\nim = PILImage.create(img_fn)\nim.show(figsize=(5,5))","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:22.155280Z","iopub.execute_input":"2022-04-28T22:39:22.155550Z","iopub.status.idle":"2022-04-28T22:39:22.821715Z","shell.execute_reply.started":"2022-04-28T22:39:22.155516Z","shell.execute_reply":"2022-04-28T22:39:22.821012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Print the paired mask\nmask_fn = get_mask(img_fn)\nmsk = PILMask.create(mask_fn)\nmsk.show(figsize=(5,5), alpha=1)\nmsk.shape","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:22.825362Z","iopub.execute_input":"2022-04-28T22:39:22.827699Z","iopub.status.idle":"2022-04-28T22:39:23.407890Z","shell.execute_reply.started":"2022-04-28T22:39:22.827656Z","shell.execute_reply":"2022-04-28T22:39:23.407227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Verify and obtain all the categories of masks,\n#for semantic segmentation, there should be several outcomes for a few classes.\n#This step, when running at the first time, needs to perform a full operation;\n#later it can be sampled. But the full amount is time-consuming\ndef n_codes(fnames, is_partial=True):\n  \"Gather the codes from a list of `fnames`\"\n  vals = set()\n  if is_partial:\n    random.shuffle(fnames)\n    fnames = fnames[:10]\n  for fname in fnames:\n    msk = np.array(PILMask.create(fname))\n    for val in np.unique(msk):\n      if val not in vals:\n        vals.add(val)\n  vals = list(vals)\n  p2c = dict()\n  for i,val in enumerate(vals):\n    p2c[i] = vals[i]\n  return p2c\np2c=n_codes(lbl_names)\np2c","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:23.412150Z","iopub.execute_input":"2022-04-28T22:39:23.414336Z","iopub.status.idle":"2022-04-28T22:39:24.195940Z","shell.execute_reply.started":"2022-04-28T22:39:23.414268Z","shell.execute_reply":"2022-04-28T22:39:24.195189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Classify the values in the label as 0, 1, etc\ndef get_mask2(fn,p2c=n_codes(lbl_names)):\n    fn = 'train_masks/'+str(fn.stem)+'_mask.gif'\n    msk = np.array(PILMask.create(fn))\n    mx = np.max(msk)\n    for i,val in enumerate(p2c):\n        msk[msk == p2c[i]] = val\n    return PILMask.create(msk)","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:24.197174Z","iopub.execute_input":"2022-04-28T22:39:24.197449Z","iopub.status.idle":"2022-04-28T22:39:24.723049Z","shell.execute_reply.started":"2022-04-28T22:39:24.197414Z","shell.execute_reply":"2022-04-28T22:39:24.722343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Generate a DataBlock\nbinary = DataBlock(blocks=(ImageBlock, MaskBlock( ['Background', 'car'])),    \n                   get_items=get_image_files,    #x is obtained in get_image_files\n                   splitter=RandomSplitter(),    #Random segmentation\n                   get_y=get_mask2,              #The method of getting y\n                   item_tfms=Resize((512,512),ResizeMethod.Squish),# “Squish” isimportant     \n                   batch_tfms=[Normalize.from_stats(*imagenet_stats)])   ","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:24.726193Z","iopub.execute_input":"2022-04-28T22:39:24.726594Z","iopub.status.idle":"2022-04-28T22:39:28.338977Z","shell.execute_reply.started":"2022-04-28T22:39:24.726564Z","shell.execute_reply":"2022-04-28T22:39:28.338154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Read the picture and display the sample\ndls = binary.dataloaders(path/'train',bs=3)\ndls.show_batch(cmap='Greens', vmin=0, vmax=1)","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:28.340238Z","iopub.execute_input":"2022-04-28T22:39:28.340502Z","iopub.status.idle":"2022-04-28T22:39:29.315903Z","shell.execute_reply.started":"2022-04-28T22:39:28.340468Z","shell.execute_reply":"2022-04-28T22:39:29.315186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Select the model, for semantic segmentation, metrics generally choose Dice; \n#to_fp16 ( ) is a hybrid-precision model that increases training speed\nlearn = unet_learner(dls,resnet34,metrics = Dice).to_fp16()","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:29.317063Z","iopub.execute_input":"2022-04-28T22:39:29.317367Z","iopub.status.idle":"2022-04-28T22:39:38.138266Z","shell.execute_reply.started":"2022-04-28T22:39:29.317329Z","shell.execute_reply":"2022-04-28T22:39:38.137524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Select lr and start training. The higher the DICE value, the better\nif(debug):\n    learn.fit_one_cycle(1)\nelse:\n    learn.fit_one_cycle(12)\nlearn.recorder.plot_loss()","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:39:38.139578Z","iopub.execute_input":"2022-04-28T22:39:38.139830Z","iopub.status.idle":"2022-04-28T22:41:56.510026Z","shell.execute_reply.started":"2022-04-28T22:39:38.139787Z","shell.execute_reply":"2022-04-28T22:41:56.508147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The model has been successfully trained and saved\nlearn.save('carvana_stage1')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.511367Z","iopub.status.idle":"2022-04-28T22:41:56.511962Z","shell.execute_reply.started":"2022-04-28T22:41:56.511731Z","shell.execute_reply":"2022-04-28T22:41:56.511755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Read the sample_submission\nsubmit_mask = pd.read_csv('sample_submission.csv')\nsubmit_mask","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.513164Z","iopub.status.idle":"2022-04-28T22:41:56.513780Z","shell.execute_reply.started":"2022-04-28T22:41:56.513549Z","shell.execute_reply":"2022-04-28T22:41:56.513574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Verify that the test directory and csv data are consistent\nif(debug):\n    for idx,name in (enumerate(submit_mask['img'].iloc[:])):\n        name =  'test/'+ str(name)\n        if(not(os.path.exists(name))):\n            print (idx,name)\nprint('done')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.514936Z","iopub.status.idle":"2022-04-28T22:41:56.515548Z","shell.execute_reply.started":"2022-04-28T22:41:56.515316Z","shell.execute_reply":"2022-04-28T22:41:56.515340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_csv = 'test/'+submit_mask['img']\ntest_csv","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.516701Z","iopub.status.idle":"2022-04-28T22:41:56.517326Z","shell.execute_reply.started":"2022-04-28T22:41:56.517081Z","shell.execute_reply":"2022-04-28T22:41:56.517105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encode(mask):\n    pixels = mask.flatten()\n    pixels[0] = 0\n    pixels[-1] = 0\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 2\n    runs[1::2] = runs[1::2] - runs[:-1:2]\n    return runs","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.518998Z","iopub.status.idle":"2022-04-28T22:41:56.519628Z","shell.execute_reply.started":"2022-04-28T22:41:56.519399Z","shell.execute_reply":"2022-04-28T22:41:56.519424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#To avoid overflow, the method of batch infer is used\nfor ibatch in range(100):\n    test_csv_part = test_csv[1000*ibatch:1000*(ibatch+1)]\n    test_dl = learn.dls.test_dl(test_csv_part)\n    preds=[]\n    if(not debug):\n        preds = learn.get_preds(dl=test_dl)\n    print(ibatch,time.time())\n    for idx in range(1000):\n        if(debug):\n            rle = 'rle'\n        else:\n            submit_np = np.array(preds[0][idx][0]<0.5).astype(np.uint8) \n            msk = PILMask.create(submit_np)\n            #The middle upside down one more time is due to \n            #the observation of npresize causing the image to be distorted\n            msk = msk.resize((1918,1280),Image.ANTIALIAS)  \n            submit_np2 = np.array(msk)\n            rle = rle_encode(submit_np2)\n            rle = ' '.join(str(x) for x in rle)\n        submit_mask['rle_mask'][1000*ibatch+idx]=rle\n","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.520809Z","iopub.status.idle":"2022-04-28T22:41:56.521434Z","shell.execute_reply.started":"2022-04-28T22:41:56.521184Z","shell.execute_reply":"2022-04-28T22:41:56.521209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_mask.to_csv('submission0.csv',index=False, header=True)\nprint('end 0')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.522572Z","iopub.status.idle":"2022-04-28T22:41:56.523177Z","shell.execute_reply.started":"2022-04-28T22:41:56.522947Z","shell.execute_reply":"2022-04-28T22:41:56.522972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_csv_part = test_csv[100000:100064]\ntest_dl = learn.dls.test_dl(test_csv_part)\npreds=[]\nif(not debug):\n    preds = learn.get_preds(dl=test_dl)\nprint(ibatch,time.time())\nfor idx in range(64):\n    if(debug):\n        rle = 'rle'\n    else:\n        submit_np = np.array(preds[0][idx][0]<0.5).astype(np.uint8) \n        msk = PILMask.create(submit_np)\n        #The middle upside down one more time is due to \n        #the observation of npresize causing the image to be distorted\n        msk = msk.resize((1918,1280),Image.ANTIALIAS)  \n        submit_np2 = np.array(msk)\n        rle = rle_encode(submit_np2)\n        rle = ' '.join(str(x) for x in rle)\n    submit_mask['rle_mask'][100000+idx]=rle","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.524337Z","iopub.status.idle":"2022-04-28T22:41:56.524944Z","shell.execute_reply.started":"2022-04-28T22:41:56.524705Z","shell.execute_reply":"2022-04-28T22:41:56.524729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_mask.to_csv('submission.csv',index=False, header=True)\nprint('end')","metadata":{"execution":{"iopub.status.busy":"2022-04-28T22:41:56.526082Z","iopub.status.idle":"2022-04-28T22:41:56.526707Z","shell.execute_reply.started":"2022-04-28T22:41:56.526478Z","shell.execute_reply":"2022-04-28T22:41:56.526504Z"},"trusted":true},"execution_count":null,"outputs":[]}]}