{"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":"markdown","source":"## Origianl kernal\n* https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-subm\n## Tensorflow HuBMAP - Hacking the Kidney competition starter kit:\n* https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-tfrecs (how to create training and inference tfrecords)\n* https://www.kaggle.com/wrrosa/hubmap-tf-with-tpu-efficientunet-512x512-train (training pipeline)\n* this notebook (inference with submission)\n","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\n* https://www.kaggle.com/c/hubmap-kidney-segmentation/discussion/224883#1233186","metadata":{}},{"cell_type":"markdown","source":"# Parameters\nRead parameteres from notebook output, actually only **DIM** is used:","metadata":{}},{"cell_type":"code","source":"mod_path = '../input/hubmap-tensorflow-models-256x256/'\nimport yaml\nimport pprint\n# with open(mod_path+'params.yaml') as file:\n#     P = yaml.load(file, Loader=yaml.FullLoader)\n#     pprint.pprint(P)\n    \nTHRESHOLD = 0.4 # preds > THRESHOLD\nVOTERS = 0.5\nWINDOW = 1024\nMIN_OVERLAP = 300\nNEW_SIZE = 512\nSUM_PRED = 128\n \nSUBMISSION_MODE = 'FULL' # PUBLIC_TFREC or FULL\n# 'PUBLIC_TFREC' = use created tfrecords for public test set with MIN_OVERLAP = 300 tiling 1024-512, ignore other (private test) data\n# 'FULL' do not use tfrecords, just full submission \n\nCHECKSUM = False # compute mask sum for each image\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Metrics","metadata":{}},{"cell_type":"code","source":"# import json\n\n# with open(mod_path + 'metrics.json') as json_file:\n#     M = json.load(json_file)\n# print('Model run datetime: '+M['datetime'])\n# print('OOF val_dice_coe: ' + str(M['oof_dice_coe']))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Packages","metadata":{}},{"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","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Functions","metadata":{}},{"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=1024, 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)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Models","metadata":{}},{"cell_type":"code","source":"models_path_list = [\n#     '../input/hubmap-tensorflow-models-256x256/densenet121_FPN_model_fold_0_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/densenet121_FPN_model_fold_3_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb4_Linknet_model_fold_0_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb4_Linknet_model_fold_2_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb4_Unet_model_fold_0_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb4_Unet_model_fold_3_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/resnet50_Unet_model_fold_0_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/resnet50_Unet_model_fold_3_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_0_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_3_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/seresnext101_Unet_model_fold_2_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/seresnext101_Unet_model_fold_3_ex.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_0_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_2_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_3_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_1_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models-256x256/efficientnetb7_Unet_model_fold_4_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models-256x256/seresnext101_Unet_model_fold_0_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models-256x256/seresnext101_Unet_model_fold_3_ex_sudo_test.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_0_sm.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_1_sm.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_2_sm.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_3_sm.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_4_sm.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_0_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_1_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_2_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_3_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_4_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/seresnet50_Unet_model_fold_0_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/seresnet50_Unet_model_fold_2_sm_ex_sl.h5',\n#     '../input/hubmap-tensorflow-models/seresnet50_Unet_model_fold_3_sm_ex_sl.h5',\n    \n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_0_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_1_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_2_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_3_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_4_sl_ex_hub_tst.h5',\n    \n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_0_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_1_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_2_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_3_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_4_sl_ex_hub_tst.h5',\n    \n    '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_0_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_1_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_2_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_3_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_Unet_model_fold_4_sl_ex_no_hub_tst.h5',\n    \n#     '../input/hubmap-tensorflow-models/efficientnetb2_Unet_model_fold_0_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb2_Unet_model_fold_1_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb2_Unet_model_fold_2_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb2_Unet_model_fold_3_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb2_Unet_model_fold_4_sl_ex_no_hub_tst.h5',\n    \n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_0_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_1_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_2_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_3_sl_ex_no_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/efficientnetb1_Unet_model_fold_4_sl_ex_no_hub_tst.h5',\n    \n#     '../input/hubmap-tensorflow-models/mobilenetv2_FPN_model_fold_0_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/mobilenetv2_FPN_model_fold_1_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/mobilenetv2_FPN_model_fold_2_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/mobilenetv2_FPN_model_fold_3_sl_ex_hub_tst.h5',\n#     '../input/hubmap-tensorflow-models/mobilenetv2_FPN_model_fold_4_sl_ex_hub_tst.h5',\n    \n    '../input/hubmap-tensorflow-models/efficientnetb0_FPN_model_fold_0_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_FPN_model_fold_1_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_FPN_model_fold_2_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_FPN_model_fold_3_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb0_FPN_model_fold_4_sl_ex_no_hub_tst.h5',\n    \n    '../input/hubmap-tensorflow-models/efficientnetb1_FPN_model_fold_0_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb1_FPN_model_fold_1_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb1_FPN_model_fold_2_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb1_FPN_model_fold_3_sl_ex_no_hub_tst.h5',\n    '../input/hubmap-tensorflow-models/efficientnetb1_FPN_model_fold_4_sl_ex_no_hub_tst.h5',\n    \n]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"identity = rasterio.Affine(1, 0, 0, 0, 1, 0)\nfold_models = []\n# for fold_model_path in glob.glob(mod_path+'*.h5'):\nfor fold_model_path in models_path_list:\n    model = tf.keras.models.load_model(fold_model_path,compile = False)\n#     for layer in model.layers:\n#             if isinstance(layer, tf.keras.layers.BatchNormalization):\n#                 layer.trainable = False\n                \n    fold_models.append(model)\nprint(len(fold_models))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Tfrecords functions","metadata":{}},{"cell_type":"code","source":"AUTO = tf.data.experimental.AUTOTUNE\n\nDIM = NEW_SIZE\n\nimage_feature = {\n    'image': tf.io.FixedLenFeature([], tf.string),\n    'x1': tf.io.FixedLenFeature([], tf.int64),\n    'y1': tf.io.FixedLenFeature([], tf.int64)\n}\ndef _parse_image(example_proto):\n    example = tf.io.parse_single_example(example_proto, image_feature)\n    image = tf.reshape( tf.io.decode_raw(example['image'],out_type=np.dtype('uint8')), (DIM,DIM, 3))\n    return tf.cast(image, tf.float32)/255.0, example['x1'], example['y1']\n\ndef load_dataset(filenames, ordered=True):\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False\n    dataset = tf.data.TFRecordDataset(filenames)\n    dataset = dataset.with_options(ignore_order)\n    dataset = dataset.map(_parse_image)\n    return dataset\n\ndef get_dataset(FILENAME):\n    dataset = load_dataset(FILENAME)\n    dataset  = dataset.batch(64)\n    dataset = dataset.prefetch(AUTO)\n    return dataset","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Results","metadata":{}},{"cell_type":"code","source":"p = pathlib.Path('../input/hubmap-kidney-segmentation')\nsubm = {}\n\nfor 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    preds = np.zeros(dataset.shape, dtype=np.uint8)    \n    \n    if SUBMISSION_MODE == 'PUBLIC_TFREC' and MIN_OVERLAP == 300 and WINDOW == 1024 and NEW_SIZE == 512:\n        print('SUBMISSION_MODE: PUBLIC_TFREC')\n        fnames = glob.glob('/kaggle/input/hubmap-tfrecords-1024-512-test/test/'+filename.stem+'*.tfrec')\n        \n        if len(fnames)>0: # PUBLIC TEST SET\n            for FILENAME in fnames:\n                pred = None\n                for fold_model in fold_models:\n                    tmp = fold_model.predict(get_dataset(FILENAME))/len(fold_models)\n                    if pred is None:\n                        pred = tmp\n                    else:\n                        pred += tmp\n                    del tmp\n                    gc.collect()\n\n                pred = tf.cast((tf.image.resize(pred, (WINDOW,WINDOW)) > THRESHOLD),tf.bool).numpy().squeeze()\n\n                idx = 0\n                for img, X1, Y1 in get_dataset(FILENAME):\n                    for fi in range(X1.shape[0]):\n                        x1 = X1[fi].numpy()\n                        y1 = Y1[fi].numpy()\n                        preds[x1:(x1+WINDOW),y1:(y1+WINDOW)] += pred[idx]\n                        idx += 1\n                        \n        else: # IGNORE PRIVATE TEST SET (CREATE TFRECORDS IN FUTURE)\n            pass\n    else:\n        print('SUBMISSION_MODE: FULL')\n        slices = make_grid(dataset.shape, window=WINDOW, min_overlap=MIN_OVERLAP)\n\n        if dataset.count != 3:\n            print('Image file with subdatasets as channels')\n            layers = [rasterio.open(subd) for subd in dataset.subdatasets]\n            \n        print(f'Dataset Shape: {dataset.shape}')\n        \n        EMPTY = np.zeros((NEW_SIZE, NEW_SIZE))\n            \n        for (x1,x2,y1,y2) in tqdm(slices):\n            if dataset.count == 3:\n                image = dataset.read([1,2,3],\n                            window=Window.from_slices((x1,x2),(y1,y2)))\n                image = np.moveaxis(image, 0, -1)\n            else:\n                image = np.zeros((WINDOW, WINDOW, 3), dtype=np.uint8)\n                for fl in range(3):\n                    image[:,:,fl] = layers[fl].read(window=Window.from_slices((x1,x2),(y1,y2)))\n                    \n            \n            hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n            h,s,v = cv2.split(hsv)\n            s_th = 40\n            p_th = 1000*(1024//256)**2\n            \n            if (s>s_th).sum() <= p_th or image.sum() <= p_th :\n                \n                pred = EMPTY\n            else:\n                    \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                image = tf.cast(image, tf.float32)/255.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#             if np.sum((pred > THRESHOLD).astype(np.uint8)) < SUM_PRED:\n#                 pred = EMPTY\n\n            pred = cv2.resize(pred, (WINDOW, WINDOW))\n            preds[x1:x2,y1:y2] += (pred > THRESHOLD).astype(np.uint8)\n\n    preds = (preds >= VOTERS).astype(np.uint8)\n    \n    subm[i] = {'id':filename.stem, 'predicted': rle_encode_less_memory(preds)}\n    \n    if CHECKSUM:\n        print('Checksum: '+ str(np.sum(preds)))\n    \n    del preds\n    gc.collect();","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Making submission","metadata":{}},{"cell_type":"code","source":"submission = pd.DataFrame.from_dict(subm, orient='index')\nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}