{"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":"# **HuBMAP + HPA - Hacking the Human Body**\n##### **Segment multi-organ functional tissue units**","metadata":{}},{"cell_type":"markdown","source":"### **Importing necessary modules & packages**","metadata":{}},{"cell_type":"code","source":"# Importing EfficientNet models with intermediate endpoints\nimport sys\nsys.path.append('../input/efficientnetv2-head-1x1-endpoint-v2/')\nsys.path.append('../input/efficientnetv2-head-1x1-endpoint-v2/efficientnetv2/')","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:41.516635Z","iopub.execute_input":"2022-09-26T05:30:41.516971Z","iopub.status.idle":"2022-09-26T05:30:41.618098Z","shell.execute_reply.started":"2022-09-26T05:30:41.516901Z","shell.execute_reply":"2022-09-26T05:30:41.617373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport tensorflow.keras.backend as K\nimport tensorflow_addons as tfa\nimport matplotlib.pyplot as plt\n\nfrom tensorflow.keras.mixed_precision import experimental as mixed_precision\nfrom kaggle_datasets import KaggleDatasets\nfrom tqdm.notebook import tqdm\nfrom multiprocessing import cpu_count\nfrom sklearn import metrics\nfrom sklearn.model_selection import KFold\n\nimport effnetv2_model\nimport re, os, io, time, pickle, math\nimport random, sys, cv2, gc, tifffile","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:41.619943Z","iopub.execute_input":"2022-09-26T05:30:41.620525Z","iopub.status.idle":"2022-09-26T05:30:47.202821Z","shell.execute_reply.started":"2022-09-26T05:30:41.620491Z","shell.execute_reply":"2022-09-26T05:30:47.202094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Seeding Random number generators**","metadata":{}},{"cell_type":"code","source":"def seed_all(seed):\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    random.seed(seed)\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n    \nSEED = 42\nseed_all(SEED)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.204019Z","iopub.execute_input":"2022-09-26T05:30:47.204280Z","iopub.status.idle":"2022-09-26T05:30:47.209912Z","shell.execute_reply.started":"2022-09-26T05:30:47.204248Z","shell.execute_reply":"2022-09-26T05:30:47.208904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Threshold to classify a pixel as mask\nTHRESHOLD = 0.1\n\nDEBUG = False\nIS_TPU = True\n\n# Image dimensions\nIMG_SIZE = 640\nPATCH_SIZE = 640\nN_CHANNELS = 3\nN_PATCHES_PER_IMAGE = (IMG_SIZE // PATCH_SIZE) ** 2\n\nINPUT_SHAPE = (PATCH_SIZE, PATCH_SIZE, N_CHANNELS)\n\n# EfficientNet version\nEFN_SIZE = 'b8'\nLR_MAX = 0.02\nEPOCHS = 30\nMOMENTUM = 0.00\n\n# Batch size\nBATCH_SIZE = 64\n\n# Dataset Mean and Standard Deviation\nMEAN = np.load('/kaggle/input/hubmap-patched-tfrecords-300x300/MEAN.npy')\nSTD = np.load('/kaggle/input/hubmap-patched-tfrecords-300x300/STD.npy')\n\nprint(f'MEAN: {MEAN}, STD: {STD}')","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.211967Z","iopub.execute_input":"2022-09-26T05:30:47.212490Z","iopub.status.idle":"2022-09-26T05:30:47.266778Z","shell.execute_reply.started":"2022-09-26T05:30:47.212458Z","shell.execute_reply":"2022-09-26T05:30:47.266093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Hardware Configuration**","metadata":{}},{"cell_type":"code","source":"# Detect hardware, return appropriate distribution strategy\ntry:\n    # TPU detection\n    TPU = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print('Running on TPU ', TPU.master())\nexcept ValueError:\n    print('Running on GPU')\n    TPU = None\n\nif TPU:\n    tf.config.experimental_connect_to_cluster(TPU)\n    tf.tpu.experimental.initialize_tpu_system(TPU)\n    strategy = tf.distribute.experimental.TPUStrategy(TPU)\nelse:\n     # default distribution strategy in Tensorflow. Works on CPU and single GPU.\n    strategy = tf.distribute.get_strategy()\n\nREPLICAS = strategy.num_replicas_in_sync\nprint(f'REPLICAS: {REPLICAS}')","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.267970Z","iopub.execute_input":"2022-09-26T05:30:47.268248Z","iopub.status.idle":"2022-09-26T05:30:47.281713Z","shell.execute_reply.started":"2022-09-26T05:30:47.268217Z","shell.execute_reply":"2022-09-26T05:30:47.280985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **FPN**","metadata":{}},{"cell_type":"code","source":"def FPN(xs, output_channels, last_layer, debug=False):\n    def _conv(x):\n        x = tf.keras.layers.ZeroPadding2D(padding=1)(x)\n        x = tf.keras.layers.Conv2D(output_channels * 2, 3, padding='SAME', kernel_initializer='he_normal', activation='relu')(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.keras.layers.ZeroPadding2D(padding=1)(x)\n        x = tf.keras.layers.Conv2D(output_channels, 3, padding='SAME', kernel_initializer='he_normal')(x)\n        x = tf.image.resize(x, size=target_size, method=tf.image.ResizeMethod.BILINEAR)\n        x = tf.nn.relu(x)\n        return x\n\n    target_size = last_layer.shape[1:3]\n    xs = tf.keras.layers.Concatenate()([_conv(x) for x in xs])\n    x = tf.keras.layers.Concatenate()([xs, last_layer])\n\n    if debug:\n        return x, xs\n    else:\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.282871Z","iopub.execute_input":"2022-09-26T05:30:47.283528Z","iopub.status.idle":"2022-09-26T05:30:47.292448Z","shell.execute_reply.started":"2022-09-26T05:30:47.283496Z","shell.execute_reply":"2022-09-26T05:30:47.291703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **ASPP**","metadata":{}},{"cell_type":"code","source":"def ASPP(x, mid_c=320, dilations=[1, 2, 3, 4], out_c=640, debug=False):\n    def _aspp_module(x, filters, kernel_size, padding, dilation, groups=1):\n        x = tf.keras.layers.ZeroPadding2D(padding=padding)(x)\n        x = tf.keras.layers.Conv2D(\n                filters=filters,\n                kernel_size=kernel_size,\n                dilation_rate=dilation,\n                groups=1 if IS_TPU else groups,\n                kernel_initializer='he_uniform',\n            )(x)\n        x = tf.keras.layers.BatchNormalization()(x)\n        x = tf.nn.relu(x)\n        \n        return x\n    \n    x0 = tf.math.reduce_max(x, axis=(1,2), keepdims=True)\n    x0 = tf.keras.layers.Conv2D(filters=mid_c, kernel_size=1, strides=1, kernel_initializer='he_uniform', use_bias=False)(x0)\n    x0 = tf.keras.layers.BatchNormalization(gamma_initializer=tf.constant_initializer(value=0.25))(x0)\n    x0 = tf.nn.relu(x0)\n                                  \n                                  \n    xs = (\n        [_aspp_module(x, mid_c, 1, padding=0, dilation=1)] +\n        [_aspp_module(x, mid_c, 3, padding=d, dilation=d, groups=4) for d in dilations]\n    )\n    \n    x0= tf.image.resize(x0, size=xs[0].shape[1:3])\n    x = tf.keras.layers.Concatenate()([x0] + xs)\n    x = tf.keras.layers.Conv2D(filters=out_c, kernel_size=1, kernel_initializer='he_uniform', use_bias=False)(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.nn.relu(x)\n                       \n    if debug:\n        return x, x0, xs\n    else:\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.293431Z","iopub.execute_input":"2022-09-26T05:30:47.293845Z","iopub.status.idle":"2022-09-26T05:30:47.305983Z","shell.execute_reply.started":"2022-09-26T05:30:47.293813Z","shell.execute_reply":"2022-09-26T05:30:47.305270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Upsample**","metadata":{}},{"cell_type":"code","source":"def PixelShuffle(x, upscale_factor=2):\n    _, w, h, c = x.shape\n    n = -1\n\n    c_out = c // upscale_factor ** 2\n    w_out = w * upscale_factor\n    h_out = h * upscale_factor\n\n    x = tf.reshape(x, [-1, upscale_factor, upscale_factor, w, h, c_out])\n    x = tf.transpose(x, [0, 3, 1, 4, 2, 5])\n    x = tf.reshape(x, [-1, w_out, h_out, c_out])\n\n    return x","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.307114Z","iopub.execute_input":"2022-09-26T05:30:47.307452Z","iopub.status.idle":"2022-09-26T05:30:47.319316Z","shell.execute_reply.started":"2022-09-26T05:30:47.307421Z","shell.execute_reply":"2022-09-26T05:30:47.318503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Inspiration: https://www.tensorflow.org/tutorials/generative/pix2pix#build_an_input_pipeline_with_tfdata\ndef upsample(x, concat, target_filters, name, conv2dt_kernel_init_max, relu=True, dropout=0, debug=False):\n#     x = PixelShuffle(x)\n\n    filters = concat.shape[-1]\n    x_up = tf.keras.layers.Conv2DTranspose(\n            filters, # Number of Convolutional Filters\n            kernel_size=4, # Kernel Size\n            strides=2, # Kernel Steps\n            padding='SAME', # linear scaling\n            name=f'Conv2DTranspose_{name}', # Name of Layer\n            kernel_initializer='he_uniform',\n            use_bias=False,\n        )(x)\n    \n    concat = tf.keras.layers.BatchNormalization(\n        gamma_initializer=tf.constant_initializer(value=0.25),\n        name=f'BatchNormalization_{name}'\n    )(concat)\n    x = tf.keras.layers.Concatenate(name=f'Concatenate_{name}')([x_up, concat])\n    x = tf.nn.relu(x)\n    \n        \n    x = tf.keras.layers.Conv2D(target_filters, 3, padding='SAME', kernel_initializer='he_uniform', activation='relu', name=f'Conv2D_1_{name}')(x)\n    x = tf.keras.layers.Conv2D(target_filters, 3, padding='SAME', kernel_initializer='he_uniform', name=f'Conv2D_2_{name}')(x)\n    \n    if relu:\n        x = tf.nn.relu(x)\n    \n    x = tf.keras.layers.Dropout(dropout, name=f'Dropout_{name}')(x)\n\n    if debug:\n        return x, x_up, concat\n    else:\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.320563Z","iopub.execute_input":"2022-09-26T05:30:47.320892Z","iopub.status.idle":"2022-09-26T05:30:47.330667Z","shell.execute_reply.started":"2022-09-26T05:30:47.320861Z","shell.execute_reply":"2022-09-26T05:30:47.329984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Model**","metadata":{}},{"cell_type":"code","source":"def get_model(dropout_decoder=0, dropout_cnn=0, file_path=None, lr=1e-3, eps=1e-7, clipnorm=5.0, wd_coef=1e-2, cnn_trainable=True):\n    with strategy.scope():\n        # EfficientNetV2 Backbone # \n        cnn = effnetv2_model.get_model(f'efficientnet-{EFN_SIZE}', include_top=False, weights=None, model_config={ 'conv_dropout': dropout_cnn })\n        cnn.trainable = cnn_trainable\n\n        # Inputs, note the names are equal to the dictionary keys in the dataset\n        image = tf.keras.layers.Input(INPUT_SHAPE, name='image', dtype=tf.float32)\n        image_norm = tf.cast(image, tf.float32) / 255\n        image_norm = tf.keras.layers.experimental.preprocessing.Normalization(mean=MEAN, variance=STD, dtype=tf.float32)(image_norm)\n\n        embedding, up6, up5, up4, up3, up2, up1 = cnn(image_norm, with_endpoints=True)\n        print(f'embedding shape: {embedding.shape} up1 shape: {up1.shape}, up2 shape: {up2.shape}')\n        print(f'up3 shape: {up3.shape}, up4 shape: {up4.shape}, up5 shape: {up5.shape}, up6 shape: {up6.shape}')\n        \n        dec0 = ASPP(up2)\n        dec0 = tf.keras.layers.Dropout(0.50)(dec0)\n\n        dec1 = upsample(dec0, up3, up4.shape[-1] * 4, 'upsample1', 0.02, dropout=dropout_decoder)\n        dec2 = upsample(dec1, up4, up5.shape[-1] * 2, 'upsample2', 0.02, dropout=dropout_decoder)\n        dec3 = upsample(dec2, up5, up6.shape[-1] * 2, 'upsample3', 0.02)\n        dec4 = upsample(dec3, up6, 64, 'upsample4', 0.02)\n        \n        print(f'dec0 shape: {dec0.shape}, dec1 shape: {dec1.shape}, dec2 shape: {dec2.shape}, dec3 shape: {dec3.shape}, dec4 shape: {dec4.shape}')\n        \n        dec_fpn = FPN([dec0, dec1, dec2, dec3], 32, dec4)\n        \n        print(f'dec_fpn shape: {dec_fpn.shape}')\n        \n        # Head\n        x = tf.keras.layers.Dropout(0.10)(dec_fpn)\n        x = tf.keras.layers.Conv2D(\n            filters=1,\n            kernel_size=1,\n            padding='SAME',\n            kernel_initializer=tf.random_normal_initializer(0.00, 0.05),\n            activation='sigmoid',\n            name='Conv2D_3_head'\n        )(x)\n        output = tf.image.resize(x, size=[IMG_SIZE, IMG_SIZE], method=tf.image.ResizeMethod.BILINEAR)\n        \n        model = tf.keras.models.Model(inputs=image, outputs=output)\n\n        if file_path:\n            print('Loading pretrained weights...')\n            model.load_weights(file_path)\n            \n        model.trainable = False\n\n        return model","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.334010Z","iopub.execute_input":"2022-09-26T05:30:47.334318Z","iopub.status.idle":"2022-09-26T05:30:47.350591Z","shell.execute_reply.started":"2022-09-26T05:30:47.334292Z","shell.execute_reply":"2022-09-26T05:30:47.347174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pretrained File Path: '/kaggle/input/sartorius-training-dataset/model.h5'\nmodel = get_model(file_path='../input/hubmap-training-tf-tpu-efficientnet-b8-640640-p/model_0.h5')","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:30:47.354561Z","iopub.execute_input":"2022-09-26T05:30:47.355002Z","iopub.status.idle":"2022-09-26T05:31:11.926456Z","shell.execute_reply.started":"2022-09-26T05:30:47.354948Z","shell.execute_reply":"2022-09-26T05:31:11.925567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot model summary\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:11.927660Z","iopub.execute_input":"2022-09-26T05:31:11.927920Z","iopub.status.idle":"2022-09-26T05:31:12.019389Z","shell.execute_reply.started":"2022-09-26T05:31:11.927889Z","shell.execute_reply":"2022-09-26T05:31:12.018686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model, show_shapes=True, show_dtype=True, show_layer_names=True, expand_nested=False)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:12.020628Z","iopub.execute_input":"2022-09-26T05:31:12.020911Z","iopub.status.idle":"2022-09-26T05:31:15.195982Z","shell.execute_reply.started":"2022-09-26T05:31:12.020878Z","shell.execute_reply":"2022-09-26T05:31:15.194941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Utility Funtions**","metadata":{}},{"cell_type":"code","source":"# Resized a tensor to the specified size\ndef resize_tensor(tensor, size=IMG_SIZE, dtype=np.uint8):\n    return cv2.resize(tensor, [size, size], interpolation=cv2.INTER_CUBIC).astype(dtype)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.197649Z","iopub.execute_input":"2022-09-26T05:31:15.198026Z","iopub.status.idle":"2022-09-26T05:31:15.203925Z","shell.execute_reply.started":"2022-09-26T05:31:15.197970Z","shell.execute_reply":"2022-09-26T05:31:15.202909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ref: https://www.kaggle.com/paulorzp/run-length-encode-and-decode\ndef get_mask(image_id):\n    row = train.loc[train['id'] == image_id].squeeze()\n    h, w = row[['img_height', 'img_width']]\n    mask = np.zeros(shape=[h * w], dtype=np.uint8)\n    s = row['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    for lo, hi in zip(starts, ends):\n        mask[lo : hi] = 1\n        \n    mask = mask.reshape([h, w]).T\n        \n    mask = resize_tensor(mask)\n    \n    mask = np.expand_dims(mask, axis=2)\n        \n    return mask","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.205011Z","iopub.execute_input":"2022-09-26T05:31:15.205681Z","iopub.status.idle":"2022-09-26T05:31:15.216225Z","shell.execute_reply.started":"2022-09-26T05:31:15.205649Z","shell.execute_reply":"2022-09-26T05:31:15.215636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Reads an image and returns the image and original image size\ndef get_image(image_id, folder, negative=True):\n    image = tifffile.imread(f'/kaggle/input/hubmap-organ-segmentation/{folder}_images/{image_id}.tiff')\n    if len(image.shape) == 5:\n        image = image.squeeze().transpose(1, 2, 0)\n    \n    # Image Size\n    image_size, _, _ = image.shape\n    \n    # Reverse pixels to make tissue colored and background black\n    if negative:\n        image = image - image.min()\n        image = image / (image.max() - image.min())\n        image = image * 255\n        image = 255 - image.astype(np.uint8)\n        \n    # Resize\n    image = resize_tensor(image)\n    return image, image_size","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.217402Z","iopub.execute_input":"2022-09-26T05:31:15.217886Z","iopub.status.idle":"2022-09-26T05:31:15.228209Z","shell.execute_reply.started":"2022-09-26T05:31:15.217855Z","shell.execute_reply":"2022-09-26T05:31:15.227620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# extract patches from image\ndef extract_patches(image):\n    _, _, c = image.shape\n    image = tf.expand_dims(image, 0)\n    image_patches = tf.image.extract_patches(image, [1,PATCH_SIZE,PATCH_SIZE,1], [1, PATCH_SIZE, PATCH_SIZE, 1], [1, 1, 1, 1], padding='SAME')\n    image_patches = tf.reshape(image_patches, [N_PATCHES_PER_IMAGE, PATCH_SIZE, PATCH_SIZE, c])\n    image_patches = image_patches.numpy()\n\n    return image_patches","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.229198Z","iopub.execute_input":"2022-09-26T05:31:15.229679Z","iopub.status.idle":"2022-09-26T05:31:15.238036Z","shell.execute_reply.started":"2022-09-26T05:31:15.229649Z","shell.execute_reply":"2022-09-26T05:31:15.237257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encode_less_memory(img):\n    # transpose image\n    pixels = img.T.flatten()\n    pixels[0], pixels[-1] = 0, 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)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.239523Z","iopub.execute_input":"2022-09-26T05:31:15.240250Z","iopub.status.idle":"2022-09-26T05:31:15.250243Z","shell.execute_reply.started":"2022-09-26T05:31:15.240218Z","shell.execute_reply":"2022-09-26T05:31:15.249469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Inference**","metadata":{}},{"cell_type":"code","source":"# training DataFrame\ntrain = pd.read_csv('/kaggle/input/hubmap-organ-segmentation/train.csv')\n# test DataFrame\ntest = pd.read_csv('/kaggle/input/hubmap-organ-segmentation/test.csv')","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.251423Z","iopub.execute_input":"2022-09-26T05:31:15.252282Z","iopub.status.idle":"2022-09-26T05:31:15.623193Z","shell.execute_reply.started":"2022-09-26T05:31:15.252245Z","shell.execute_reply":"2022-09-26T05:31:15.622401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# reconstruct original image from patches\ndef merge_patches(patches):\n    image = np.zeros(shape=[IMG_SIZE, IMG_SIZE, patches.shape[-1]], dtype=patches.dtype)\n    s = int(N_PATCHES_PER_IMAGE ** 0.50)\n    for r in range(s):\n        for c in range(s):\n            start_x = r * PATCH_SIZE\n            end_x = (r + 1) * PATCH_SIZE\n            start_y = c * PATCH_SIZE\n            end_y = (c + 1) * PATCH_SIZE\n            image[start_x:end_x, start_y:end_y] = patches[r * s + c]\n            \n    return image","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.624682Z","iopub.execute_input":"2022-09-26T05:31:15.624948Z","iopub.status.idle":"2022-09-26T05:31:15.631141Z","shell.execute_reply.started":"2022-09-26T05:31:15.624916Z","shell.execute_reply":"2022-09-26T05:31:15.630116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Test**","metadata":{}},{"cell_type":"code","source":"# verify the trained weights are correctly loaded on 10 predictions\ntest_rows = []\nN = 10\n\nfor row_idx, row in tqdm(train[:N].iterrows(), total=N):\n    # preprocess image\n    image, image_size = get_image(row['id'], 'train')\n    image_patches = extract_patches(image)\n    \n    # prediction\n    mask_patches_pred = model.predict(image_patches)\n    mask_pred = merge_patches(mask_patches_pred)\n    mask_pred_resized = resize_tensor(mask_pred, size=image_size, dtype=np.float32)\n    \n    fig, axes = plt.subplots(1,2, figsize=(8,4))\n    axes[0].imshow(mask_pred_resized)\n    axes[1].imshow(image)\n    plt.show()\n        \n    mask_binary = (mask_pred_resized > THRESHOLD).astype(np.int8)\n    test_rows.append({\n        'id': row['id'],\n        'rle': rle_encode_less_memory(mask_binary)\n    })","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:15.632799Z","iopub.execute_input":"2022-09-26T05:31:15.633336Z","iopub.status.idle":"2022-09-26T05:31:49.206510Z","shell.execute_reply.started":"2022-09-26T05:31:15.633302Z","shell.execute_reply":"2022-09-26T05:31:49.205628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Inference Loop**","metadata":{}},{"cell_type":"code","source":"# store predictions in list of dictionaries\ntest_rows = []\nfor row_idx, row in tqdm(test.iterrows(), total=len(test)):\n    # preprocess image\n    image, image_size = get_image(row['id'], 'test')\n    image_patches = extract_patches(image)\n    \n    # prediction\n    mask_patches_pred = model.predict(image_patches)\n    # merge patches & resize mask to original size\n    mask_pred = merge_patches(mask_patches_pred)\n    mask_pred_resized = resize_tensor(mask_pred, size=image_size, dtype=np.float32)\n    \n    if row_idx == 0:\n        fig, axes = plt.subplots(1,2, figsize=(8,4))\n        axes[0].imshow(mask_pred_resized)\n        axes[1].imshow(image)\n        plt.show()\n        \n    # resize and binarize mask\n    mask_binary = (mask_pred_resized > THRESHOLD).astype(np.int8)\n    test_rows.append({\n        'id': row['id'],\n        'rle': rle_encode_less_memory(mask_binary)\n    })","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:49.208277Z","iopub.execute_input":"2022-09-26T05:31:49.208729Z","iopub.status.idle":"2022-09-26T05:31:50.382639Z","shell.execute_reply.started":"2022-09-26T05:31:49.208687Z","shell.execute_reply":"2022-09-26T05:31:50.381891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Submission**","metadata":{}},{"cell_type":"code","source":"test_df = pd.DataFrame(test_rows)\ntest_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-09-26T05:31:50.384016Z","iopub.execute_input":"2022-09-26T05:31:50.384477Z","iopub.status.idle":"2022-09-26T05:31:50.395246Z","shell.execute_reply.started":"2022-09-26T05:31:50.384439Z","shell.execute_reply":"2022-09-26T05:31:50.394528Z"},"trusted":true},"execution_count":null,"outputs":[]}]}