{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":61446,"databundleVersionId":6962461,"sourceType":"competition"}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"In Exploratory Data Analysis (EDA) the aim is to discover general patterns in the dataset, data visualizations are one of the best techniques of doing this. One particular interesting visualization is the animation plot, which can assist in summarizing the data and uncovering insights. In this notebook, I have stitched an animation plot of the image and label scan slices from the datasets provided.\n\nThe second part of this notebook is a starter on a baseline CNN U-Net like model training...","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"## Import Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport rasterio\nimport warnings\n\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.animation as animation\nimport tensorflow as tf\n\nfrom rasterio.plot import show\nfrom IPython.display import HTML\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras import layers, Model\nfrom tensorflow.keras.utils import plot_model\nfrom keras.layers import Input\n\n%matplotlib inline\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:21.559108Z","iopub.execute_input":"2023-11-27T08:01:21.559455Z","iopub.status.idle":"2023-11-27T08:01:33.837415Z","shell.execute_reply.started":"2023-11-27T08:01:21.559407Z","shell.execute_reply":"2023-11-27T08:01:33.836417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Definitions","metadata":{}},{"cell_type":"code","source":"# dataset directories\ndataset = \"kidney_1_dense\"\ndata_dir = \"/kaggle/input/blood-vessel-segmentation/train/\"\nimages_dir = os.path.join(data_dir, dataset, \"images\")\nmasks_dir = os.path.join(data_dir, dataset, \"labels\")","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:33.839134Z","iopub.execute_input":"2023-11-27T08:01:33.839682Z","iopub.status.idle":"2023-11-27T08:01:33.844615Z","shell.execute_reply.started":"2023-11-27T08:01:33.839654Z","shell.execute_reply":"2023-11-27T08:01:33.843568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_image(path):\n    \"\"\" Retrieve image slice. \"\"\"\n    try:\n        with rasterio.open(path) as image:\n            image_array = rasterio.plot.reshape_as_image(image.read())\n        return image_array\n    except:\n        pass","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:33.846146Z","iopub.execute_input":"2023-11-27T08:01:33.846733Z","iopub.status.idle":"2023-11-27T08:01:33.873676Z","shell.execute_reply.started":"2023-11-27T08:01:33.846701Z","shell.execute_reply":"2023-11-27T08:01:33.872783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def resize_image(path, dims=[256, 256]):\n    \"\"\" \n    Returns resized image tensor. \n    i.e. input_shape = (img_width, img_height, 1)\n    \"\"\"\n    try:\n        image = get_image(path)\n        # Resize the image as needed\n        image_tensor = tf.image.resize(image, dims)\n        return image_tensor\n    except:\n        pass","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:33.874852Z","iopub.execute_input":"2023-11-27T08:01:33.875131Z","iopub.status.idle":"2023-11-27T08:01:33.884194Z","shell.execute_reply.started":"2023-11-27T08:01:33.875107Z","shell.execute_reply":"2023-11-27T08:01:33.883127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## EDA Animation","metadata":{}},{"cell_type":"code","source":"def display_animation(dataset, images_dir=images_dir, masks_dir=masks_dir, interval=50, figsize=(8,8), cmap_mask='jet', alpha_mask=0.5):\n    \"\"\" Display animations of kidney slices. \"\"\"\n    \n    # List image ids\n    img_ids = os.listdir(masks_dir)\n    img_ids = sorted(img_ids)\n    print(f\"There are {len(img_ids)} images for {dataset} scan.\")\n    \n    # Selection interval \n    select_ids = img_ids[::interval]\n\n    artists = []\n    fig, ax = plt.subplots(figsize=figsize)\n    \n    for select_id in select_ids:\n        \n        image_file = os.path.join(images_dir, select_id)\n        mask_file = os.path.join(masks_dir, select_id)\n\n        image = get_image(image_file)\n        mask = get_image(mask_file)\n\n        title_str = f\"{dataset} scan from {select_id.replace('.tif', '')} slice\"\n        title = ax.text(x = 0.5,\n                        y = 1.00,\n                        s = title_str,\n                        size = 12,\n                        ha = \"center\",\n                        transform = ax.transAxes\n                    )\n        \n        disp_mask = ax.imshow(mask, cmap=cmap_mask, alpha=alpha_mask, animated=True)\n        disp_img = ax.imshow(image, cmap=\"gray\", animated=True)\n\n        plt.axis(\"off\")\n        plt.close()\n\n        artists.append([disp_img, disp_mask, title])\n\n    # Stitch animation object\n    ani = animation.ArtistAnimation(fig = fig,\n                                    artists = artists,\n                                    interval = 200,\n                                    blit = True,\n                                    repeat = True)\n    \n    return display(HTML(ani.to_jshtml()))","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:33.887383Z","iopub.execute_input":"2023-11-27T08:01:33.887701Z","iopub.status.idle":"2023-11-27T08:01:33.900330Z","shell.execute_reply.started":"2023-11-27T08:01:33.887678Z","shell.execute_reply":"2023-11-27T08:01:33.899442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Kidney 1 Dense Dataset\n\nkidney_1_dense - The whole of a right kidney at 50um resolution. The entire 3D arterial vascular tree has been densely segmented, down to two generations from the glomeruli (i.e. the capillary bed). Uses beamline BM05.","metadata":{}},{"cell_type":"code","source":"%%time\ndisplay_animation(dataset = 'kidney_1_dense',\n                            interval = 50,\n                            figsize = (8, 8),\n                            cmap_mask ='jet',\n                            alpha_mask = 0.5)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:33.901458Z","iopub.execute_input":"2023-11-27T08:01:33.901699Z","iopub.status.idle":"2023-11-27T08:01:57.668362Z","shell.execute_reply.started":"2023-11-27T08:01:33.901678Z","shell.execute_reply":"2023-11-27T08:01:57.667381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Kidney 1 Voi Dataset\n\nkidney_1_voi - A high-resolution subset of kidney_1, at 5.2um resolution.","metadata":{}},{"cell_type":"code","source":"# %%time\n# display_animation(dataset = 'kidney_1_voi',\n#                             interval = 10,\n#                             figsize = (8, 8),\n#                             cmap_mask ='jet',\n#                             alpha_mask = 0.5)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.669660Z","iopub.execute_input":"2023-11-27T08:01:57.669973Z","iopub.status.idle":"2023-11-27T08:01:57.674456Z","shell.execute_reply.started":"2023-11-27T08:01:57.669946Z","shell.execute_reply":"2023-11-27T08:01:57.673474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Kidney 2 Dataset\n\nkidney_2 - The whole of a kidney from another donor, at 50um resolution. Sparsely segmented (about 65%).","metadata":{}},{"cell_type":"code","source":"# %%time\n# display_animation(dataset = 'kidney_2',\n#                             interval = 50,\n#                             figsize = (8, 8),\n#                             cmap_mask ='jet',\n#                             alpha_mask = 0.5)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.675537Z","iopub.execute_input":"2023-11-27T08:01:57.675806Z","iopub.status.idle":"2023-11-27T08:01:57.695751Z","shell.execute_reply.started":"2023-11-27T08:01:57.675783Z","shell.execute_reply":"2023-11-27T08:01:57.694811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Kidney 3 Dataset\n\nkidney_3_dense - A portion (500 slices) of a kidney at 50.16um resolution using BM05. Densely segmented. Note that we provide all of the images for kidney_3 in the kidney_3_sparse/images folder. This dataset accordingly has only a labels folder.\n\nkidney_3_sparse - The remainder of the segmentation masks for kidney_3. Sparsely segmented (about 85%).","metadata":{}},{"cell_type":"code","source":"# %%time\n# display_animation(dataset = 'kidney_3_sparse',\n#                             interval = 50,\n#                             figsize = (8, 8),\n#                             cmap_mask ='jet',\n#                             alpha_mask = 0.5)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.696859Z","iopub.execute_input":"2023-11-27T08:01:57.697172Z","iopub.status.idle":"2023-11-27T08:01:57.707305Z","shell.execute_reply.started":"2023-11-27T08:01:57.697145Z","shell.execute_reply":"2023-11-27T08:01:57.706469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"One insight gleaned from the scan animation of the HiP-CT kidney slices is that there is quite a bit of noise and a denoising step would be needed for pre-processing.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"## Model Training\n\nIn this step, model training of Tensorflow U-Net like segmenter.","metadata":{}},{"cell_type":"code","source":"class SegmentationBaseModel(Model):\n    \"\"\"\n    Segmentation Baseline:\n        1. Contractions [Downsampling] in the first network half using convulutions and maxpooling.\n        2. Expansions [Upsampling] in the second network using transpose.\n    \"\"\"\n    \n    def __init__(self, img_size):\n    \n        super(SegmentationBaseModel,self).__init__()\n        \n        self.img_size = img_size\n#         self.input_layer = Input(shape=(img_size[0], img_size[1], 2))\n        \n        self.conv11, self.conv12, self.pool1 = self.conv_block(filters=64,kernel_size=3,strides=1,padding='SAME',activation='relu',pool_size=2,pool_stride=2)\n        self.conv21, self.conv22, self.pool2 = self.conv_block(filters=128,kernel_size=3,strides=1,padding='SAME',activation='relu',pool_size=2,pool_stride=2)\n        self.conv31, self.conv32, self.pool3 = self.conv_block(filters=256,kernel_size=3,strides=1,padding='SAME',activation='relu',pool_size=2,pool_stride=2)\n        self.conv41, self.conv42, self.pool4 = self.conv_block(filters=512,kernel_size=3,strides=1,padding='SAME',activation='relu',pool_size=2,pool_stride=2)\n        self.conv51, self.conv52 = self.conv_block(filters=1024,kernel_size=3,strides=1,padding='SAME',activation='relu', pool_size=2,pool_stride=2,pool=False)\n\n        self.deconv1 = self.deconv_block(filters=1024,kernel_size=3,strides=2,padding='SAME',activation='relu')\n        self.deconv2 = self.deconv_block(filters=512,kernel_size=3,strides=2,padding='SAME',activation='relu')\n        self.deconv3 = self.deconv_block(filters=256,kernel_size=3,strides=2,padding='SAME',activation='relu')\n        self.deconv4 = self.deconv_block(filters=128,kernel_size=3,strides=2,padding='SAME',activation='relu')\n        self.convf = layers.Conv2D(filters=1,kernel_size=1,strides=1,padding='SAME')\n        \n        self.output_layer = layers.Dense(1)\n\n    def conv_block(self,filters,kernel_size,strides,padding,activation,pool_size,pool_stride,pool=True):\n        \n        conv11 = layers.Conv2D(filters=filters,kernel_size=kernel_size,strides=(strides,strides),padding=padding,activation=activation)\n        conv12 = layers.Conv2D(filters=filters,kernel_size=kernel_size,strides=(strides,strides),padding=padding,activation=activation)\n\n        if pool:\n            pool1 = layers.MaxPool2D(pool_size=(pool_size,pool_size),strides=(pool_stride,pool_stride))\n\n            return conv11, conv12, pool1\n\n        return conv11, conv12\n    \n    def deconv_block(self,filters,kernel_size,strides,padding,activation):\n        \n        deconv1 = layers.Conv2DTranspose(filters=filters,kernel_size=kernel_size,strides=(strides,strides),padding=padding,activation=activation)\n        \n        return deconv1\n    \n    def call(self,inputs):\n        img_size = inputs\n        \n        # build the first layer set\n        x = self.conv11(img_size)\n        x = self.conv12(x)\n        x = self.pool1(x)\n        # build the second layer set\n        x = self.conv21(x)\n        x = self.conv22(x)\n        x = self.pool2(x)\n        # build the third layer set\n        x = self.conv31(x)\n        x = self.conv32(x)\n        x = self.pool3(x)\n        # build the fourth layer set\n        x = self.conv41(x)\n        x = self.conv42(x)\n        x = self.pool4(x)\n        # build the fifth layer set\n        x = self.conv51(x)\n        x = self.conv52(x)\n        #\n        x = self.deconv1(x)\n        x = self.deconv2(x)\n        x = self.deconv3(x)\n        x = self.deconv4(x)\n        x = self.convf(x)\n        # return the constructed model\n        output = self.output_layer(x)\n        return output","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.708836Z","iopub.execute_input":"2023-11-27T08:01:57.709103Z","iopub.status.idle":"2023-11-27T08:01:57.730849Z","shell.execute_reply.started":"2023-11-27T08:01:57.709080Z","shell.execute_reply":"2023-11-27T08:01:57.729962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def data_gen(images_dir, masks_dir, images, batch_size, dims):\n    \"\"\"\n    Generator that we will use to read the data from directory.\n    \"\"\"\n    \n    while True:\n        ix = np.random.choice(np.arange(len(images)), batch_size)\n        imgs = []\n        labels = []\n        \n        for i in ix:\n            \n            # images\n            image_path = os.path.join(images_dir, images[i])\n            resized_img = resize_image(image_path, dims)\n            try:\n                imgs.append(resized_img)\n            except:\n                pass\n            \n            # masks\n            mask_path = os.path.join(masks_dir, images[i])\n            resized_mask = resize_image(mask_path, dims)\n            try:\n                labels.append(resized_mask[:, :, 0])\n                imgs = np.array(imgs)\n                labels = np.array(labels)\n            except:\n                pass\n        \n        yield imgs, labels.reshape(-1, dims[0], dims[1],1)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.732241Z","iopub.execute_input":"2023-11-27T08:01:57.732518Z","iopub.status.idle":"2023-11-27T08:01:57.743551Z","shell.execute_reply.started":"2023-11-27T08:01:57.732488Z","shell.execute_reply":"2023-11-27T08:01:57.742618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(images_dir=images_dir, masks_dir=masks_dir, train_val_split=[0.8,0.2], batch_size=5, img_height=256, img_width=256, lr=0.01, epochs=10):\n    \"\"\"\n    Train the model.\n    \"\"\"\n    tf.random.set_seed(RANDOM_SEED)\n    \n    # define the model\n    model = SegmentationBaseModel(img_size=[img_height,img_width])\n    model_graph = tf.function(model)\n        \n    # define data & split into train & validation\n    images = os.listdir(images_dir)\n    training_set, validation_set = train_test_split(images, train_size=train_val_split[0], test_size=train_val_split[1], random_state=RANDOM_SEED)\n    \n    # train & validation data generators\n    train_gen = data_gen(images_dir, masks_dir, training_set, batch_size=batch_size, dims=(img_height, img_width))\n    val_gen = data_gen(images_dir, masks_dir, validation_set, batch_size=batch_size, dims=(img_height, img_width))\n        \n    # define optimizer\n    optimizer = tf.keras.optimizers.Adam(lr)\n\n    # define loss function\n    loss_fn = tf.keras.losses.BinaryCrossentropy(from_logits=True)\n    \n    loss_trace, accuracy_trace = [], []\n    \n    for epoch in range(epochs):\n\n        num_train_recs, num_val_recs = len(training_set), len(validation_set)\n        num_batches = num_train_recs // batch_size\n\n        loss, accuracy = 0, 0\n        num_train_recs = 0\n\n        for batch in range(num_batches):\n            \n            X_batch, y_batch = next(train_gen)\n            X_batch, y_batch = tf.constant(X_batch), tf.constant(y_batch)\n            \n            num_train_recs += X_batch.shape[0]\n\n            with tf.GradientTape() as tape:\n                y_pred_batch = model_graph(X_batch,training=True)\n                loss_ = loss_fn(y_batch,y_pred_batch)\n            \n            gradients = tape.gradient(loss_,model.trainable_variables) # compute gradients\n            optimizer.apply_gradients(zip(gradients,model.trainable_variables)) # update paramters\n            \n            X_val, y_val = next(val_gen)\n            X_val, y_val = tf.constant(X_val), tf.constant(y_val)\n            \n            y_pred = model_graph(X_val, training=False)\n\n            accuracy += np.sum(y_batch == y_pred)\n            loss += loss_.numpy()\n            \n            # print(f\"Loss for epoch {epoch}, batch {batch} : {loss}\")\n\n        loss /= num_train_recs\n        accuracy /= num_train_recs\n        loss_trace.append(loss)\n        accuracy_trace.append(accuracy)\n        \n        print(f\"-------------------------------------------------------\\n\")\n        print(f\"Epoch {epoch} : loss : {np.round(loss, 4)} , accuracy : {np.round(accuracy, 4)}\\n\")\n        print(f\"-------------------------------------------------------\\n\")\n                \n    print(f\"End training batch : {batch}, train loss : {loss/batch_size}, val loss : {loss/batch_size}\")\n    \n    model.compile(optimizer, loss_fn, metrics=['accuracy'])\n    model.fit(X_batch, y_batch, \n              validation_data=(X_val, y_val), \n              batch_size=batch_size,\n              epochs=epochs)\n    \n    return model, model_graph, X_val, y_val, y_pred","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.745184Z","iopub.execute_input":"2023-11-27T08:01:57.745686Z","iopub.status.idle":"2023-11-27T08:01:57.766293Z","shell.execute_reply.started":"2023-11-27T08:01:57.745646Z","shell.execute_reply":"2023-11-27T08:01:57.765345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# training on the first dataset: kidney_1_dense\nRANDOM_SEED = 40\n# hyperparamter config\nmodel_kwargs = {\n        \"train_val_split\": [0.8,0.2],\n        \"batch_size\": 60,\n        \"img_height\": 256,\n        \"img_width\": 256,\n        \"lr\": 0.01,\n        \"epochs\": 10\n    }\nmodel, model_graph, X_val, y_val, y_pred = train(**model_kwargs)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:01:57.767398Z","iopub.execute_input":"2023-11-27T08:01:57.767719Z","iopub.status.idle":"2023-11-27T08:13:03.814923Z","shell.execute_reply.started":"2023-11-27T08:01:57.767692Z","shell.execute_reply":"2023-11-27T08:13:03.814103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:03.819337Z","iopub.execute_input":"2023-11-27T08:13:03.819715Z","iopub.status.idle":"2023-11-27T08:13:03.877201Z","shell.execute_reply.started":"2023-11-27T08:13:03.819689Z","shell.execute_reply":"2023-11-27T08:13:03.876293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_loss, val_acc = model.evaluate(X_val, y_val)\nprint(f\"Validation accuracy is : {val_acc}\")","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:03.878477Z","iopub.execute_input":"2023-11-27T08:13:03.878862Z","iopub.status.idle":"2023-11-27T08:13:03.967746Z","shell.execute_reply.started":"2023-11-27T08:13:03.878827Z","shell.execute_reply":"2023-11-27T08:13:03.966839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Inferencing","metadata":{}},{"cell_type":"code","source":"# test dataset directories\ndataset = \"kidney_5\"\ndata_dir = \"/kaggle/input/blood-vessel-segmentation/test/\"\nimages_dir = os.path.join(data_dir, dataset, \"images\")","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:03.969064Z","iopub.execute_input":"2023-11-27T08:13:03.969707Z","iopub.status.idle":"2023-11-27T08:13:03.974672Z","shell.execute_reply.started":"2023-11-27T08:13:03.969672Z","shell.execute_reply":"2023-11-27T08:13:03.973717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict(images_dir=images_dir, model=model):\n    \"\"\"\n    Generate predictions.\n    \"\"\"\n    images = sorted(os.listdir(images_dir))\n    dims = [256, 256]\n    imgs = []\n\n    for image in images:\n        # images\n        try:\n            image_path = os.path.join(images_dir, image)\n            resized_img = resize_image(image_path, dims)\n            imgs.append(resized_img)\n        except:\n            pass\n    \n    # Generate predictions for samples\n    try:\n        predictions = model.predict(imgs)\n    except:\n        pass\n    # print(predictions)\n    try:\n        thresholds = (predictions > 0.5).astype(np.uint8)\n    except:\n        pass\n    \n    try:\n        return images, thresholds\n    except:\n        pass","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:03.975720Z","iopub.execute_input":"2023-11-27T08:13:03.975975Z","iopub.status.idle":"2023-11-27T08:13:03.987017Z","shell.execute_reply.started":"2023-11-27T08:13:03.975953Z","shell.execute_reply":"2023-11-27T08:13:03.986197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encode(img):\n    \"\"\"\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    \"\"\"\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    rle = ' '.join(str(x) for x in runs)\n    if rle=='':\n        rle = '1 0'\n    return rle","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:03.988159Z","iopub.execute_input":"2023-11-27T08:13:03.988533Z","iopub.status.idle":"2023-11-27T08:13:03.997674Z","shell.execute_reply.started":"2023-11-27T08:13:03.988503Z","shell.execute_reply":"2023-11-27T08:13:03.996679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# images, predictions = predict(images_dir=images_dir, model=model)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:03.998852Z","iopub.execute_input":"2023-11-27T08:13:03.999126Z","iopub.status.idle":"2023-11-27T08:13:04.008418Z","shell.execute_reply.started":"2023-11-27T08:13:03.999102Z","shell.execute_reply":"2023-11-27T08:13:04.007584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# rles = [rle_encode(mask) for mask in predictions]\n# ids = [f'{p.split(\"/\")[-3]}_{os.path.basename(p).split(\".\")[0]}' for p in images]\n\n# submission = pd.DataFrame({\n#     \"id\": ids,\n#     \"rle\": rles\n# })","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:04.009540Z","iopub.execute_input":"2023-11-27T08:13:04.009796Z","iopub.status.idle":"2023-11-27T08:13:04.019392Z","shell.execute_reply.started":"2023-11-27T08:13:04.009774Z","shell.execute_reply":"2023-11-27T08:13:04.018591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:04.020499Z","iopub.execute_input":"2023-11-27T08:13:04.020804Z","iopub.status.idle":"2023-11-27T08:13:04.030173Z","shell.execute_reply.started":"2023-11-27T08:13:04.020781Z","shell.execute_reply":"2023-11-27T08:13:04.029158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-27T08:13:04.031354Z","iopub.execute_input":"2023-11-27T08:13:04.031701Z","iopub.status.idle":"2023-11-27T08:13:04.039547Z","shell.execute_reply.started":"2023-11-27T08:13:04.031666Z","shell.execute_reply":"2023-11-27T08:13:04.038688Z"},"trusted":true},"execution_count":null,"outputs":[]}]}