{"cells":[{"metadata":{},"cell_type":"markdown","source":"This is inference with submission notebook - full training notebook can be found here:\nhttps://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-train\n\n# Versions\n* V1 (V7 train notebook) 4-CV efficientunetb0 512x512 (LB .834)\n* V2 (V8 train notebook) loss bce (LB .835)\n* V3 (V9 train notebook) efficientunetb1 (CV .871, LB .830)\n* V4 (V10 train notebook) efficientunetb4 (CV .874, LB .839)\n* V5 (V12 train notebook) efficientunetb7 (CV .858, LB .835)\n* V6 (V13 train notebook) efficientunetb4 (CV .877, LB .836)\n* V7 (V14 train notebook) efficientunetb4 with overlapped train data, summing preds in inference (CV .879, LB .843)\n* V8 (V14 train notebook) efficientunetb4  THRESHOLD=0.4, interpolation = cv2.INTER_AREA, rle_encode_less_memory (LB .846)\n* V9 (V14 train notebook) efficientunetb4, MIN_OVERLAP = 300"},{"metadata":{},"cell_type":"markdown","source":"# Refferences:\n* https://www.kaggle.com/joshi98kishan/hubmap-keras-pipeline-training-inference\n* https://www.kaggle.com/bguberfain/memory-aware-rle-encoding/\n* https://www.kaggle.com/leighplt/pytorch-fcn-resnet50"},{"metadata":{},"cell_type":"markdown","source":"# Parameters\nRead parameteres from notebook output, actually only **DIM** is used:"},{"metadata":{"trusted":true},"cell_type":"code","source":"!nvidia-smi","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mod_path = '../input/unetkers/'\nimport yaml\nimport pprint\nwith open(mod_path+'params.yaml') as file:\n    P = yaml.load(file, Loader=yaml.FullLoader)\n    pprint.pprint(P)\n    \nTHRESHOLD = 0.4\nWINDOW = 1024\nMIN_OVERLAP = 300\nNEW_SIZE = P['DIM']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Metrics"},{"metadata":{"trusted":true},"cell_type":"code","source":"import json\n\nwith open(mod_path + 'metrics.json') as json_file:\n    M = json.load(json_file)\nprint('Model run datetime: '+M['datetime'])\nprint('OOF val_dice_coe: ' + str(M['oof_dice_coe']))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Packages"},{"metadata":{"trusted":true},"cell_type":"code","source":"! pip install ../input/kerasapplications/keras-team-keras-applications-3b180cb -f ./ --no-index -q\n! pip install ../input/efficientnet/efficientnet-1.1.0/ -f ./ --no-index -q\nimport numpy as np\nimport pandas as pd\nimport os\nimport glob\nimport gc\n\nimport rasterio\nfrom rasterio.windows import Window\n\nimport pathlib\nfrom tqdm.notebook import tqdm\nimport cv2\n\nimport tensorflow as tf\nimport efficientnet as efn\nimport efficientnet.tfkeras","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Functions"},{"metadata":{"trusted":true},"cell_type":"code","source":"def rle_encode_less_memory(img):\n    pixels = img.T.flatten()\n    pixels[0] = 0\n    pixels[-1] = 0\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 2\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\ndef make_grid(shape, window=256, min_overlap=32):\n    \"\"\"\n        Return Array of size (N,4), where N - number of tiles,\n        2nd axis represente slices: x1,x2,y1,y2 \n    \"\"\"\n    x, y = shape\n    nx = x // (window - min_overlap) + 1\n    x1 = np.linspace(0, x, num=nx, endpoint=False, dtype=np.int64)\n    x1[-1] = x - window\n    x2 = (x1 + window).clip(0, x)\n    ny = y // (window - min_overlap) + 1\n    y1 = np.linspace(0, y, num=ny, endpoint=False, dtype=np.int64)\n    y1[-1] = y - window\n    y2 = (y1 + window).clip(0, y)\n    slices = np.zeros((nx,ny, 4), dtype=np.int64)\n    \n    for i in range(nx):\n        for j in range(ny):\n            slices[i,j] = x1[i], x2[i], y1[j], y2[j]    \n    return slices.reshape(nx*ny,4)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Models"},{"metadata":{"trusted":true},"cell_type":"code","source":"identity = rasterio.Affine(1, 0, 0, 0, 1, 0)\nfold_models = []\nfor fold_model_path in glob.glob(mod_path+'*.h5'):\n    print(fold_model_path)\n    fold_models.append(tf.keras.models.load_model(fold_model_path,compile = False))\nprint(len(fold_models))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Results"},{"metadata":{"trusted":true},"cell_type":"code","source":"p = pathlib.Path('../input/hubmap-kidney-segmentation')\nsubm = {}\nif len(os.listdir('../input/hubmap-kidney-segmentation/test/'))!=10:\n    for i, filename in tqdm(enumerate(p.glob('test/*.tiff')), \n                        total = len(list(p.glob('test/*.tiff')))):\n\n        print(f'{i+1} Predicting {filename.stem}')\n\n        dataset = rasterio.open(filename.as_posix(), transform = identity)\n        slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n        preds = np.zeros(dataset.shape, dtype=np.uint8)\n\n        for (x1,x2,y1,y2) in slices:\n            image = dataset.read([1,2,3],\n                        window=Window.from_slices((x1,x2),(y1,y2)))\n            image = np.moveaxis(image, 0, -1)\n            image = cv2.resize(image, (NEW_SIZE, NEW_SIZE),interpolation = cv2.INTER_AREA)\n            image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)\n            image = np.expand_dims(image, 0)\n\n            pred = None\n\n            for fold_model in fold_models:\n                if pred is None:\n                    pred = np.squeeze(fold_model.predict(image))\n                else:\n                    pred += np.squeeze(fold_model.predict(image))\n\n            pred = pred/len(fold_models)\n\n            pred = cv2.resize(pred, (WINDOW, WINDOW))\n            preds[x1:x2,y1:y2] += (pred > THRESHOLD).astype(np.uint8)\n\n        preds = (preds > 0.5).astype(np.uint8)\n\n        subm[i] = {'id':filename.stem, 'predicted': rle_encode_less_memory(preds)}\n        #print(np.sum(preds))\n        del preds\n        gc.collect();\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# p = pathlib.Path('../input/hubmap-kidney-segmentation')\n# subm = {}\n# #if len(os.listdir('../input/hubmap-kidney-segmentation/test/'))!=10:\n# if 1:\n#     for i, filename in tqdm(enumerate(p.glob('test/*.tiff')), \n#                             total = len(list(p.glob('test/*.tiff')))):\n\n#         print(f'{i+1} Predicting {filename.stem}')\n\n#         dataset = rasterio.open(filename.as_posix(), transform = identity)\n#         slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n#         preds = np.zeros(dataset.shape, dtype=np.uint8)\n\n#         for (x1,x2,y1,y2) in slices:\n#             image = dataset.read([1,2,3],\n#                         window=Window.from_slices((x1,x2),(y1,y2)))\n#             image = np.moveaxis(image, 0, -1)\n#             image = cv2.resize(image, (NEW_SIZE, NEW_SIZE),interpolation = cv2.INTER_AREA)\n#             image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)\n#             image = np.expand_dims(image, 0)\n\n#             pred = None\n\n#             for fold_model in fold_models:\n#                 if pred is None:\n#                     pred = np.squeeze(fold_model.predict(image))\n#                 else:\n#                     pred += np.squeeze(fold_model.predict(image))\n        \n#         pred = pred/len(fold_models)\n        \n#         pred = cv2.resize(pred, (WINDOW, WINDOW))\n#         preds[x1:x2,y1:y2] += (pred > THRESHOLD).astype(np.uint8)\n    \n#     preds = (preds > 0.5).astype(np.uint8)\n    \n#     subm[i] = {'id':filename.stem, 'predicted': rle_encode_less_memory(preds)}\n#     #print(np.sum(preds))\n#     del preds\n#     gc.collect();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"open('../input/effnetmodels/params.yaml').readlines()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Making submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.DataFrame.from_dict(subm, orient='index')\nsubmission.to_csv('submission_1.csv', index=False)\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\ndef rle2mask(mask_rle, shape=(1600,256)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (width,height) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T\n\n\n#https://www.kaggle.com/bguberfain/memory-aware-rle-encoding\ndef rle_encode_less_memory(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    This simplified method requires first and last pixel to be zero\n    '''\n    pixels = img.T.flatten()\n    \n    # This simplified method requires first and last pixel to be zero\n    pixels[0] = 0\n    pixels[-1] = 0\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 2\n    runs[1::2] -= runs[::2]\n    \n    return ' '.join(str(x) for x in runs)\n\ndef image_size_dict(img_id, x, y):\n    image_id = [thing[:-5] for thing in img_id]\n    x_y = [(x[i], y[i]) for i in range(0, len(x))]    \n    return dict(zip(image_id, x_y))\n\n\ndef global_shift_mask(maskpred1, y_shift, x_shift):\n    \"\"\"\n    applies a global shift to a mask by padding one side and cropping from the other\n    \"\"\"\n    if y_shift <0 and x_shift >=0:\n        maskpred2 = np.pad(maskpred1, [(0,abs(y_shift)), (abs(x_shift), 0)], mode='constant', constant_values=0)\n        maskpred3 = maskpred2[abs(y_shift):, :maskpred1.shape[1]]\n    elif y_shift >=0 and x_shift <0:\n        maskpred2 = np.pad(maskpred1, [(abs(y_shift),0), (0, abs(x_shift))], mode='constant', constant_values=0)\n        maskpred3 = maskpred2[:maskpred1.shape[0], abs(x_shift):]\n    elif y_shift >=0 and x_shift >=0:\n        maskpred2 = np.pad(maskpred1, [(abs(y_shift),0), (abs(x_shift), 0)], mode='constant', constant_values=0)\n        maskpred3 = maskpred2[:maskpred1.shape[0], :maskpred1.shape[1]]\n    elif y_shift < 0 and x_shift < 0:\n        maskpred2 = np.pad(maskpred1, [(0, abs(y_shift)), (0, abs(x_shift))], mode='constant', constant_values=0)\n        maskpred3 = maskpred2[abs(y_shift):, abs(x_shift):]\n    return maskpred3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dfpred = pd.read_csv('./submission_1.csv')\nTARGET_ID = 'afa5e8098'\ny_shift = -40\nx_shift = -24","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndfinfo = pd.read_csv('../input/hubmap-kidney-segmentation/HuBMAP-20-dataset_information.csv')\n\nsize_dict = image_size_dict(dfinfo.image_file, dfinfo.width_pixels, dfinfo.height_pixels)  #dict which contains image sizes mapped to id's\nmask_shape = size_dict.get(TARGET_ID)\n\ntaridx = dfpred[dfpred['id']==TARGET_ID].index.values[0]  #row of TARGET_ID in dfpred\nmaskpred = rle2mask(dfpred.iloc[taridx]['predicted'], mask_shape)\n\nmaskpred1 = maskpred.copy()\nmaskpred1[maskpred1>0]=1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mask_shifted = global_shift_mask(maskpred1, y_shift, x_shift)  #apply specified shift to mask\nnewrle = rle_encode_less_memory(mask_shifted)  #rle encode shifted mask\n\ndfpred.at[taridx, 'predicted'] = newrle\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dfsample = pd.read_csv('../input/hubmap-kidney-segmentation/sample_submission.csv')\n\nmydict = dict(zip(dfpred['id'], dfpred['predicted']))\n\ndfsample['predicted'] = dfsample['id'].map(mydict).fillna(dfsample['predicted'])\n\ndfsample = dfsample.replace(np.nan, '', regex=True)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dfsample.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!ls ../input/unetmodels","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}