{"cells":[{"metadata":{},"cell_type":"markdown","source":"Original notebook: https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-subm¶\nThanks to @Wojtek Rosa for sharing his notebook.\nThe changes I made to the notebook:\n\n- pretrain for 4 epochs by freezing encoder layers and then train all layers at lower learning rate by using qubvel's segmentation_models set_trainable() function and encoder_freeze=True option.\n\n- use val_loss monitoring to save best model\n- the lower threshold=0.30 to determine prediction masks.\n- efficientnet b5 backbone with lower batch_size = 6*8\n- don't predict when committing, only on submission to save GPU time\n\nThe training notebook is [here](https://www.kaggle.com/isakev/hub-tf-tpu-valloss-pretrain-effunet5-lr1e-3-ml0-35)\n\nOOF loss 0.022605\nOOF dice_coe 0.863665\nOOF accuracy 0.992854"},{"metadata":{},"cell_type":"markdown","source":"# 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 [LB .830]\n* V4 (V10 train notebook) efficientunetb4 [...]"},{"metadata":{},"cell_type":"markdown","source":"# Credits\n* https://www.kaggle.com/joshi98kishan/hubmap-keras-pipeline-training-inference\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":"mod_path = '../input/hub-tf-tpu-valloss-pretrain-effunet5-lr1e-3-ml0-35/'  # '/kaggle/input/hubmap-tf-with-tpu-efficientunet-512x512-train/'\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.3  # 0.5\nWINDOW = 1024\nMIN_OVERLAP = 32\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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport glob\nimport gc\n\nimport numba\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":{"trusted":true},"cell_type":"code","source":"do_predict = False\nsample_sub = pd.read_csv('../input/hubmap-kidney-segmentation/sample_submission.csv')\nsample_sub.to_csv('submission.csv', index=False)\n\nif len(sample_sub) != 5:\n    do_predict = True\n    \nprint(len(sample_sub))\nsample_sub","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Functions"},{"metadata":{"trusted":true},"cell_type":"code","source":"@numba.njit()\ndef rle_numba(pixels):\n    size = len(pixels)\n    points = []\n    if pixels[0] == 1: points.append(0)\n    flag = True\n    for i in range(1, size):\n        if pixels[i] != pixels[i-1]:\n            if flag:\n                points.append(i+1)\n                flag = False\n            else:\n                points.append(i+1 - points[-1])\n                flag = True\n    if pixels[-1] == 1: points.append(size-points[-1]+1)    \n    return points\n\ndef rle_numba_encode(image):\n    pixels = image.flatten(order = 'F')\n    points = rle_numba(pixels)\n    return ' '.join(str(x) for x in points)\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":"if do_predict:\n    identity = rasterio.Affine(1, 0, 0, 0, 1, 0)\n    fold_models = []\n    for fold_model_path in glob.glob(mod_path+'*.h5'):\n        fold_models.append(tf.keras.models.load_model(fold_model_path,compile = False))\n    print(len(fold_models))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Results"},{"metadata":{"trusted":true},"cell_type":"code","source":"if do_predict:\n    p = pathlib.Path('../input/hubmap-kidney-segmentation')\n    subm = {}\n\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))\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        subm[i] = {'id':filename.stem, 'predicted': rle_numba_encode(preds)}\n        #print(np.sum(preds))\n        del preds\n        gc.collect();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Making submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"if do_predict:\n    submission = pd.DataFrame.from_dict(subm, orient='index')\n    submission.to_csv('submission.csv', index=False)\n    submission.head()","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}