{"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":"# <h1 style=\"text-align:center\">EDA + Baseline Model  - Sartorius cell segmentation</h1>\n\n\n\n* [1. Introduction](#section1)\n* [2. Importing libraries](#section2)\n* [3. Understanding data](#section3)\n* [4. Basic Analysis](#section4)\n  * [4.1 Checking for missing values and duplicates](#section4)\n  * [4.2 Analysis on cell types](#section6)\n* [5. Analysis on images and masks](#section7)\n   * [5.1 Basic analysis on images](#section7)\n   * [5.2 RLE encoding](#section8)\n   * [5.3 Visualizing images and masks](#section9)\n* [6. Baseline model](#section10)\n   * [6.1 Load data using tf data api](#section11)\n   * [6.2 Model](#section12)\n   * [6.3 Training](#section13)\n   * [6.4 Inference](#section14)\n   * [6.5. Test image prediction and submission](#section15)\n\n\n\n<img src=\"https://image.shutterstock.com/image-illustration/3d-illustration-t-cells-cancer-600w-433526728.jpg\" height=\"200px\" width=\"1000px\">\n\n  ","metadata":{}},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section1\"></a>\n## 1. Introduction\n\n\n\n### Understanding business problem\n\nNeurological disorders like Alzheimer's and brain tumors are one of the leading causes of death and disability across the globe. Once a person is opted for treatment, it is very hard to find how the person is responding to treatment. One accepted method for that is to review neuronal cells are viewed via light microscopy. But to segment neuronal cells in microscopic images can be challenging.\n\nHere comes the need of computer vision. Accurate instance segmentation of these cells could lead to new and effective drug discoveries to treat the millions of people with these disorders. So our problem is to **segment the cell present in the microscopic images**. ie, We have an instance segmentation problem.\n\n\nNote: Current solutions have limited accuracy for neuronal cells in particular. Also it is important to note that cell types like SH-SY5Y consistently exhibits the lowest precision scores. This could be because neuronal cells have a very unique, irregular and concave morphology associated with them, making them challenging to segment with commonly used mask heads. \n\n\n<a class=\"anchor\" id=\"section2\"></a>\n## 2. Importing libraries\n","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport os,random,glob\nfrom collections import Counter\nimport cv2\nimport tqdm.notebook as tqdm\nplt.style.use('seaborn-whitegrid')\n\nimport os,random,glob\nfrom collections import Counter\nimport cv2\nimport time\nimport tqdm.notebook as tqdm\n\nimport tensorflow as tf\nfrom tensorflow import keras\nimport albumentations as A\ntf.random.set_seed(42)\nimport warnings\nwarnings.simplefilter(\"ignore\")\ntf.config.run_functions_eagerly(True)\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:50:59.692065Z","iopub.execute_input":"2021-12-07T09:50:59.692353Z","iopub.status.idle":"2021-12-07T09:50:59.701593Z","shell.execute_reply.started":"2021-12-07T09:50:59.692320Z","shell.execute_reply":"2021-12-07T09:50:59.700736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section3\"></a>\n## 3. Understanding data","metadata":{}},{"cell_type":"code","source":"MAIN_PATH = '../input/sartorius-cell-instance-segmentation'\nCSV_PATH = '../input/sartorius-cell-instance-segmentation/train.csv'\nTRAIN_DIR_PATH = '../input/sartorius-cell-instance-segmentation/train'\nTEST_DIR_PATH = '../input/sartorius-cell-instance-segmentation/test'\n\nos.listdir(MAIN_PATH)","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:01.298188Z","iopub.execute_input":"2021-12-07T09:44:01.298429Z","iopub.status.idle":"2021-12-07T09:44:01.309262Z","shell.execute_reply.started":"2021-12-07T09:44:01.298396Z","shell.execute_reply":"2021-12-07T09:44:01.308402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(CSV_PATH)\nprint(df_train.shape)\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:01.310459Z","iopub.execute_input":"2021-12-07T09:44:01.310850Z","iopub.status.idle":"2021-12-07T09:44:01.851894Z","shell.execute_reply.started":"2021-12-07T09:44:01.310797Z","shell.execute_reply":"2021-12-07T09:44:01.851202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<b>Train.csv</b> -- This contains ids and rle encoded masks to corresponding ids.\n\n\n* <b>id</b> : <i>unique identifier for object.</i><br>\n\n* <b>annotation</b> : <i>run length encoded pixels for the identified neuronal cell.</i><br>\n\n* <b>width</b> : <i>source image width.</i><br>\n\n* <b>height</b> : <i>source image height</i> <br>\n\n* <b>cell_type</b> : <i>the cell line.</i><br>\n\n* <b>plate_time</b> : <i>time plate was created.</i><br>\n\n* <b>sample_date</b> : <i>date sample was created.</i><br>\n\n* <b>sample_id</b> : <i>sample identifier.</i> <br>\n\n* <b>elapsed_timedelta</b> : <i>time since first image taken of sample.</i><br>\n\n\n<b>train and test directory</b> -- This folders contains train and test images for our model\n\n<b>LIVECell_dataset_2021 directory</b> -- This folder contains more images, if we are intrested in transfer learning approach. This is a  mirror of the data from the LIVECell dataset.LIVECell is the predecessor dataset to this competition. \n\n<b>train_semi_supervised directory</b> -- This folder containe unlabelled data, We can use it if we are doing any semi supervised approach.\n","metadata":{}},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section4\"></a>\n## 4. Basic Analysis\n\n<a class=\"anchor\" id=\"section5\"></a>\n### Checking for missing values and duplicates\n\nLet us check for missing values and duplicate entries.","metadata":{}},{"cell_type":"code","source":"#checking for missing values\ndf_train.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:01.854283Z","iopub.execute_input":"2021-12-07T09:44:01.854565Z","iopub.status.idle":"2021-12-07T09:44:01.912979Z","shell.execute_reply.started":"2021-12-07T09:44:01.854528Z","shell.execute_reply":"2021-12-07T09:44:01.912157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[df_train.duplicated()]","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:01.915725Z","iopub.execute_input":"2021-12-07T09:44:01.916001Z","iopub.status.idle":"2021-12-07T09:44:02.030082Z","shell.execute_reply.started":"2021-12-07T09:44:01.915969Z","shell.execute_reply":"2021-12-07T09:44:02.029340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* We don't have any missing values. \n* For a single id,we have multiple annotations present. We can understand it further when are visualizing the image\n\n\n<a class=\"anchor\" id=\"section6\"></a>\n## Analysis on cell types\n\nWe have diffeent cell types present. Let us see the number of images present in each.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(10,6))\nsns.countplot(df_train['cell_type'])\nplt.title('No of images under each cell type')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:02.031410Z","iopub.execute_input":"2021-12-07T09:44:02.031676Z","iopub.status.idle":"2021-12-07T09:44:02.289666Z","shell.execute_reply.started":"2021-12-07T09:44:02.031641Z","shell.execute_reply":"2021-12-07T09:44:02.288964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let us plot images of various cell types and see there any difference","metadata":{}},{"cell_type":"code","source":"def load_image(img_path):\n    \"\"\"\n    function to load image\n    Args:\n        img_path: path to image\n    Returns:\n        img: image array\n       \n    \"\"\"\n    \n    img_src = cv2.imread(img_path)\n    img = cv2.cvtColor(img_src,cv2.COLOR_BGR2RGB)\n    return img\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:02.291039Z","iopub.execute_input":"2021-12-07T09:44:02.291291Z","iopub.status.idle":"2021-12-07T09:44:02.296145Z","shell.execute_reply.started":"2021-12-07T09:44:02.291257Z","shell.execute_reply":"2021-12-07T09:44:02.295216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cell_types = list(np.unique(df_train['cell_type']))\nfor ct in cell_types:\n        fig,axes = plt.subplots(1,3,figsize=(20,6))\n        df_ct = df_train[df_train['cell_type'] == ct]\n        for i,id_ in enumerate(np.unique(df_ct['id'])[0:3]):\n            img_path = os.path.join(TRAIN_DIR_PATH,id_+'.png')\n            img = load_image(img_path)\n            axes[i].imshow(img)\n\n        plt.suptitle(f'Cell type- {ct}')\n        plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:02.297260Z","iopub.execute_input":"2021-12-07T09:44:02.298689Z","iopub.status.idle":"2021-12-07T09:44:04.508208Z","shell.execute_reply.started":"2021-12-07T09:44:02.298649Z","shell.execute_reply":"2021-12-07T09:44:04.507499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the above microscopic images, we can see the difference in pattern among various cell types. Our objective is to segment these cells from microscopic images.","metadata":{}},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section7\"></a>\n\n## 5. Analysis On Images and Masks\n\nWe have our image id and corresponding rle encoding present in our train.csv.  Let us see the mean of images.\n\n### Basic analysis on images\n\n**No of images in each directory**","metadata":{}},{"cell_type":"code","source":"print(f'No of images in train directory: {len(os.listdir(TRAIN_DIR_PATH))}')\nprint(f'No of images in test directory: {len(os.listdir(TEST_DIR_PATH))}')                                             ","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:04.509440Z","iopub.execute_input":"2021-12-07T09:44:04.510066Z","iopub.status.idle":"2021-12-07T09:44:04.583369Z","shell.execute_reply.started":"2021-12-07T09:44:04.510031Z","shell.execute_reply":"2021-12-07T09:44:04.582539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Checking for image shapes**","metadata":{}},{"cell_type":"code","source":"def check_shapes(dir_path):\n    \"\"\"\n    check for unique image shapes\n    \"\"\"\n    img_shapes = []\n    for im in os.listdir(dir_path):\n        img_path = os.path.join(dir_path,im)\n        img = cv2.imread(img_path)\n        img_shapes.append(img.shape)\n    \n    img_shapes = Counter(img_shapes)\n    return len(img_shapes), img_shapes\n        \nlen_,shapes_ = check_shapes(TRAIN_DIR_PATH)\nprint(f'There are {len_} Unique image shapes in train images.They are: {shapes_}')\nlen_,shapes_ = check_shapes(TEST_DIR_PATH)\nprint(f'There are  {len_ } Unique image shapes in test images.They are {shapes_}')","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:04.584726Z","iopub.execute_input":"2021-12-07T09:44:04.585056Z","iopub.status.idle":"2021-12-07T09:44:14.030174Z","shell.execute_reply.started":"2021-12-07T09:44:04.585013Z","shell.execute_reply":"2021-12-07T09:44:14.029373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"So we have all image of shape 520,704,3 \n\n\n\n","metadata":{"execution":{"iopub.status.busy":"2021-11-22T04:14:15.788161Z","iopub.execute_input":"2021-11-22T04:14:15.788457Z","iopub.status.idle":"2021-11-22T04:14:15.794177Z","shell.execute_reply.started":"2021-11-22T04:14:15.788428Z","shell.execute_reply":"2021-11-22T04:14:15.792903Z"}}},{"cell_type":"code","source":"#sample\npath = '../input/sartorius-cell-instance-segmentation/train/04928f0866b0.png'\nim = load_image(path)\nplt.imshow(im)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:14.031656Z","iopub.execute_input":"2021-12-07T09:44:14.031936Z","iopub.status.idle":"2021-12-07T09:44:14.282913Z","shell.execute_reply.started":"2021-12-07T09:44:14.031884Z","shell.execute_reply":"2021-12-07T09:44:14.282244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# check the train images\nmeans = []\ntrain_paths = glob.glob(TRAIN_DIR_PATH+'/*')\nfor im in tqdm.tqdm(train_paths):\n    img = load_image(im)\n    means.append(img.mean())\nprint(\"Train mean: \", np.mean(means))\n\n# check the test images\nmeans = []\ntest_paths = glob.glob(TEST_DIR_PATH+'/*')\nfor im in tqdm.tqdm(test_paths):\n    img = load_image(im)\n    means.append(img.mean())\nprint(\"Test mean: \", np.mean(means))\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:14.284282Z","iopub.execute_input":"2021-12-07T09:44:14.284558Z","iopub.status.idle":"2021-12-07T09:44:20.115047Z","shell.execute_reply.started":"2021-12-07T09:44:14.284524Z","shell.execute_reply":"2021-12-07T09:44:20.114385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see that both train and test images share almost same mean. Let us explore further","metadata":{}},{"cell_type":"markdown","source":"\n\n<a class=\"anchor\" id=\"section8\"></a>\n\n### RLE Encoding\n### What is RLE encoding?\n\nRun-length encoding (RLE) is a form of lossless data compression in which runs of data are stored as a single data value and count, rather than as the original run. Let's understand how to generate masks if EncodedPixels(RLE) is given instead of mask images with an example. Let us take an example, take the image with the following rle:\n```\n118145 6 118849 7 119553 8 120257.......118145 6 118849 7 119553 8 120257\n```\nThis indicates that if the image is flattened to 1D, starting from 118145 pixel we have 6 pixels for mask. Similarly starting from 118145 pixel we have 7 pixels for mask and this goes on.\n\nNote: It is important to note that corresponding to same image id we have multiple rle indicates multiple cell segments. Also we do not have any image without rle.\n\nLet us try to visualize a mask and image.","metadata":{}},{"cell_type":"code","source":"# let us see how run length encoding looks\nrow = df_train.iloc[0]\nrle = row['annotation']\nrle[0:100]","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:20.118343Z","iopub.execute_input":"2021-12-07T09:44:20.119092Z","iopub.status.idle":"2021-12-07T09:44:20.125548Z","shell.execute_reply.started":"2021-12-07T09:44:20.119046Z","shell.execute_reply":"2021-12-07T09:44:20.124798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section9\"></a>\n### Visualizing images and masks","metadata":{}},{"cell_type":"code","source":"\n\ndef rle_decode(rle, img_shape,color=1):\n    \"\"\"\n    decode rle and generate mask\n    \n    Args:\n       rle: coded rle\n       img_shape: shape of input image\n       color: color of the rle\n    Returns:\n       mask: generated mask\n    \"\"\"\n    s = rle.split()\n    lengths = list(map(int, s[1::2]))\n    starts = list(map(int, s[0::2]))\n    ends = [v+lengths[i] for i,v in enumerate(starts)]\n    \n    msk = np.zeros((img_shape[0] * img_shape[1]), dtype=np.float32)\n    for i,v in enumerate(starts):\n        msk[v:v+lengths[i]] = color\n    \n    mask = msk.reshape(img_shape)\n    return mask\n\n\ndef build_mask(rles,img_shape):\n    \"\"\"\n    Generate mask from multiple encodigs\n    Args:\n      rles: list of rle\n    Returns:\n      mask: generated mask\n    \"\"\"\n    mask = np.zeros(img_shape)\n    for rle in rles:\n        mask += rle_decode(rle,img_shape)\n    return mask","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:20.126804Z","iopub.execute_input":"2021-12-07T09:44:20.127569Z","iopub.status.idle":"2021-12-07T09:44:20.138222Z","shell.execute_reply.started":"2021-12-07T09:44:20.127526Z","shell.execute_reply":"2021-12-07T09:44:20.137407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_paths = glob.glob(TRAIN_DIR_PATH+'/*')\nidx = random.randint(0,len(img_paths))\nimg_path = img_paths[idx]\nimg_id = img_path.split('/')[-1].split('.')[-2]\n\n#create list of rles\ndf = df_train[df_train['id'] == img_id]\nrles = df['annotation'].values\n#get image and mask\nimg = load_image(img_path)\nmask = build_mask(rles,img.shape[0:2])\nfig,axes = plt.subplots(3,1,figsize=(10,20))\naxes[0].imshow(img)\naxes[0].set_title('image')\naxes[1].imshow(mask,cmap=\"gray\")\naxes[1].set_title('mask')\naxes[2].imshow(img,cmap='bone')\naxes[2].imshow(mask,alpha=0.3,cmap='Reds')\naxes[2].set_title('Image Annoted')\nplt.show()\n    ","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:20.139303Z","iopub.execute_input":"2021-12-07T09:44:20.139754Z","iopub.status.idle":"2021-12-07T09:44:20.896126Z","shell.execute_reply.started":"2021-12-07T09:44:20.139722Z","shell.execute_reply":"2021-12-07T09:44:20.895448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_image_mask(n,dir_path):\n    img_paths = glob.glob(dir_path+'/*')\n\n    for i in range(n):\n        #generate random image\n        idx = random.randint(0,len(img_paths))\n        img_path = img_paths[idx]\n        img_id = img_path.split('/')[-1].split('.')[-2]\n        #create list of rles\n        df = df_train[df_train['id'] == img_id]\n        rles = df['annotation'].values\n        #get image and mask\n        img = load_image(img_path)\n        mask = build_mask(rles,img.shape[0:2])\n        fig,axes = plt.subplots(1,3,figsize=(15,5))\n        axes[0].imshow(img)\n        axes[0].set_title('image')\n        axes[1].imshow(mask,cmap=\"gray\")\n        axes[1].set_title('mask')\n        axes[2].imshow(img,cmap='bone')\n        axes[2].imshow(mask,alpha=0.3,cmap='Reds')\n        axes[2].set_title('Image Annoted')\n        plt.suptitle(f'Image id {img_id}')\n        plt.show()\n    ","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:20.897425Z","iopub.execute_input":"2021-12-07T09:44:20.897823Z","iopub.status.idle":"2021-12-07T09:44:20.909686Z","shell.execute_reply.started":"2021-12-07T09:44:20.897788Z","shell.execute_reply":"2021-12-07T09:44:20.908677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_image_mask(n=5,dir_path=TRAIN_DIR_PATH)","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:20.910981Z","iopub.execute_input":"2021-12-07T09:44:20.911744Z","iopub.status.idle":"2021-12-07T09:44:24.242815Z","shell.execute_reply.started":"2021-12-07T09:44:20.911709Z","shell.execute_reply":"2021-12-07T09:44:24.242167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section10\"></a>\n# 6. Baseline Model\n\nWe will be using tensorflow to create a baseline model. We will begin with a Unet for semantic segmentation. After prediction we can convert it to a semantic segmentation model.\n\n\n### About business Problem\n\nActually our objective is to segment each cell present in microscopic image. It is a kind of instance segmentation. But if we are able to do semantic segmentation of whole microscopic image and then we can get each of the cell from it and utimatly proceed towards instance segmentation. So we will train our model to do semantic segmentation from microscopic images.\n\n","metadata":{}},{"cell_type":"code","source":"print(tf.__version__)\n!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:24.249466Z","iopub.execute_input":"2021-12-07T09:44:24.249978Z","iopub.status.idle":"2021-12-07T09:44:24.955533Z","shell.execute_reply.started":"2021-12-07T09:44:24.249938Z","shell.execute_reply":"2021-12-07T09:44:24.954572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section11\"></a>\n## TF data API to load the data\n\nWe will use tensorflow data api to load and process the data","metadata":{}},{"cell_type":"code","source":"TRAIN_DIR_PATH = '../input/sartorius-cell-instance-segmentation'\nTRAIN_IMG_DIR_PATH = '../input/sartorius-cell-instance-segmentation/train'\nTRAIN_CSV_PATH = TRAIN_DIR_PATH+'/train.csv'\n\ndf = pd.read_csv(TRAIN_CSV_PATH)\ndf.shape\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:24.957192Z","iopub.execute_input":"2021-12-07T09:44:24.957876Z","iopub.status.idle":"2021-12-07T09:44:25.244607Z","shell.execute_reply.started":"2021-12-07T09:44:24.957832Z","shell.execute_reply":"2021-12-07T09:44:25.243858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Helper functions","metadata":{}},{"cell_type":"code","source":"\"\"\"\nNote: Comparison to tf.py_function: tf.py_function and tf.numpy_function are very similar, \nexcept that tf.numpy_function takes numpy arrays, and not tf.Tensors. If you want the function to contain tf.Tensors,\nand have any TensorFlow operations executed in the function be differentiable, please use tf.py_function.\n\"\"\"\n\ndef generate_image_paths(dir_=TRAIN_IMG_DIR_PATH):\n    \"\"\"\n    generate train validation image paths\n    \"\"\"\n    val_size = 0.8\n    img_paths = glob.glob(dir_+'/*.png')\n    idx = int(val_size*len(img_paths))\n    train_paths, val_paths = img_paths[0:idx],img_paths[idx:]\n    return train_paths,val_paths\n\n\ndef rle_decode(rle, img_shape,color=1):\n    \"\"\"\n    decode rle and generate mask\n    \n    Args:\n       rle: coded rle\n       img_shape: shape of input image\n       color: color of the rle\n    Returns:\n       mask: generated mask\n    \"\"\"\n    s = rle.split()\n    lengths = list(map(int, s[1::2]))\n    starts = list(map(int, s[0::2]))\n    ends = [v+lengths[i] for i,v in enumerate(starts)]\n    \n    msk = np.zeros((img_shape[0] * img_shape[1]), dtype=np.float32)\n    for i,v in enumerate(starts):\n        msk[v:v+lengths[i]] = color\n    \n    mask = msk.reshape(img_shape)\n    return mask\n\n\n# augmentations\ntrain_transforms = A.Compose([\n            A.Rotate(limit=40),\n            A.HorizontalFlip(p=0.2),\n            A.Resize(512, 512)\n            ])\n\n\nval_transforms = A.Compose([\n            A.Resize(512, 512)\n            ])\n\n\ndef train_augmentation(image,mask):\n\n    def train_aug(image,mask):\n        \"\"\"\n        augmenting train images and masks\n        \"\"\"\n        data = {\"image\": image,\"mask\":mask}\n        aug_data = train_transforms(**data)\n        aug_img = aug_data[\"image\"]\n        aug_mask = aug_data[\"mask\"]\n        \n        #normalizing image\n        aug_img = aug_img/255.0\n        \n        # aug_img = tf.image.resize(aug_img, size=[img_size, img_size])\n        return aug_img,aug_mask\n    \n    \n    aug_img,aug_mask = tf.numpy_function(train_aug, [image,mask], [tf.float32,tf.float32])\n    return aug_img,aug_mask\n\n\ndef val_augmentation(image,mask):\n\n    def aug(image,mask):\n        \"\"\"\n        augmenting train images and masks\n        \"\"\"\n        data = {\"image\": image,\"mask\":mask}\n        aug_data = val_transforms(**data)\n        aug_img = aug_data[\"image\"]\n        aug_mask = aug_data[\"mask\"]\n        \n        #normalizing image\n        aug_img = aug_img/255.0\n        \n        # aug_img = tf.image.resize(aug_img, size=[img_size, img_size])\n        return aug_img,aug_mask\n    \n    \n    aug_img,aug_mask = tf.numpy_function(aug, [image,mask], [tf.float32,tf.float32])\n    return aug_img,aug_mask\n\n\ndef set_shapes(img, mask, img_shape=(512,512,3),mask_shape=(512,512)):\n    \"\"\"\n    image and mask will loss shape after tf_py function.So this function again sets shape\n    \"\"\"\n    img.set_shape(img_shape)\n    mask.set_shape(mask_shape)\n    return img, mask\n\ndef generate_data_from_paths(img_path):\n    \"\"\"\n    execute numpy function from tensrflow end.generate image and mask\n    Args:\n      img_path: path of image from tensor slices\n    Returns:\n      img : image 3D rray\n      mask: mask 1D array\n    \"\"\"\n    def build_image_mask(img_path,df=df):\n        \"\"\"\n        Generate image and mask from img_path\n        Args:\n          img_path : path of image(byte encoded)\n          df: dataframe containing rle details\n        Returns:\n         mask: generated mask\n        \"\"\"\n\n        # read and load image from image path\n        img_path = img_path.numpy().decode()\n    \n        img = cv2.imread(img_path)\n        img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n        img_shape = img.shape[0:2]\n\n        #resizing and normalizing image\n        \n        # img = img / 255.0\n        img = img.astype(np.float32)\n\n        # get rle \n        img_id = img_path.split('/')[-1].split('.')[0]\n        df = df[df['id'] == img_id]\n        rles = df['annotation'].values\n    \n\n        #generate mask\n        mask = np.zeros(img_shape)\n        for rle in rles:\n            mask += rle_decode(rle,img_shape)\n    \n        #resing mask\n        mask = mask.astype(np.float32)\n        return img,mask\n\n    img,mask = tf.py_function(build_image_mask, [img_path], [tf.float32,tf.float32])\n    return img,mask\n\n\ndef load_data(data_paths,batch_size,prefetch_size,mode=\"train\"):\n    \"\"\"\n    load data using tf api\n    \"\"\"\n    #load data using tf data api\n    data = tf.data.Dataset.from_tensor_slices(data_paths)\n    data = data.shuffle(buffer_size=1000)\n    # Set `num_parallel_calls` so multiple images are loaded/processed in parallel\n    data = data.map(map_func=generate_data_from_paths,num_parallel_calls=tf.data.AUTOTUNE)\n    # augmentations\n    if mode==\"train\":\n        data = data.map(map_func=train_augmentation,num_parallel_calls=tf.data.AUTOTUNE)\n    else:\n        data = data.map(map_func=val_augmentation,num_parallel_calls=tf.data.AUTOTUNE)\n    \n    data = data.map(map_func=set_shapes,num_parallel_calls=tf.data.AUTOTUNE)\n    # data = data.cache()\n    # batch and prefetc\n    data = data.batch(batch_size)\n    data = data.prefetch(prefetch_size) \n    return data\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:25.246246Z","iopub.execute_input":"2021-12-07T09:44:25.246538Z","iopub.status.idle":"2021-12-07T09:44:25.273334Z","shell.execute_reply.started":"2021-12-07T09:44:25.246475Z","shell.execute_reply":"2021-12-07T09:44:25.272559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_paths,val_paths = generate_image_paths()\n\n#saving train and val data\nnp.save('trainnp.npy',train_paths)\nnp.save('valnp.npy',val_paths)\n#for loading use- np.load(name)\n\nBATCH_SIZE = 4\nPREFETCH_SIZE = 2\n\n#load train and validation data\ntrain_data = load_data(train_paths,batch_size=BATCH_SIZE,prefetch_size=PREFETCH_SIZE,mode=\"train\")\nval_data = load_data(val_paths,batch_size=BATCH_SIZE,prefetch_size=PREFETCH_SIZE,mode=\"validation\")","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:25.276563Z","iopub.execute_input":"2021-12-07T09:44:25.276887Z","iopub.status.idle":"2021-12-07T09:44:27.926432Z","shell.execute_reply.started":"2021-12-07T09:44:25.276858Z","shell.execute_reply":"2021-12-07T09:44:27.925691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Train image and mask shapes:')\niter_ = train_data.as_numpy_iterator()\nimage,mask = next(iter_)\nprint(image.shape,mask.shape)\n\nprint('Validation image and mask shapes:')\niter_ = val_data.as_numpy_iterator()\nimage,mask = next(iter_)\nprint(image.shape,mask.shape)","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:27.927544Z","iopub.execute_input":"2021-12-07T09:44:27.927773Z","iopub.status.idle":"2021-12-07T09:44:29.497701Z","shell.execute_reply.started":"2021-12-07T09:44:27.927740Z","shell.execute_reply":"2021-12-07T09:44:29.496972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualizing images/masks in batches","metadata":{}},{"cell_type":"code","source":"# plottig images and masks\n\niter_ = train_data.as_numpy_iterator()\nimages,masks = next(iter_)\nfor i in range(len(images)):\n    image = images[i]\n    mask = masks[i]\n    fig,axes = plt.subplots(1,3,figsize=(10,20))\n    axes[0].imshow(image)\n    axes[0].set_title('Image')\n    axes[1].imshow(mask,cmap=\"gray\")\n    axes[1].set_title('Mask')\n    axes[2].imshow(image,cmap='bone')\n    axes[2].imshow(mask,alpha=0.3,cmap='Reds')\n    axes[2].set_title('Image Annoted')\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T09:44:29.498807Z","iopub.execute_input":"2021-12-07T09:44:29.499053Z","iopub.status.idle":"2021-12-07T09:44:33.905208Z","shell.execute_reply.started":"2021-12-07T09:44:29.499021Z","shell.execute_reply":"2021-12-07T09:44:33.904377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section12\"></a>\n## Model (Modified Unet)\n\n\n![image.png](attachment:7a8a467f-b918-46b9-903c-3ac6311f3d6f.png)","metadata":{},"attachments":{"7a8a467f-b918-46b9-903c-3ac6311f3d6f.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAuYAAAHOCAYAAADUjsyVAAAABHNCSVQICAgIfAhkiAAAIABJREFUeF7snQd8HMX1x590p95dJPfeCwYb2xQDDobQTP9THVoooScQCAECCQlJIBj4Q/6UkIRACDiYngCmmY4Bg23cO26SLdmSJdnq9T9vz3va22uze7e3u6fffD62tLszb958ZzXz9u2b2ZROkQgJBEAABEAABEAABEAABEDAVgKpttaOykEABEAABEAABEAABEAABBQCXqdx2FLVRG+urIqoVqa3ky6c0pdysjwR87360S56avXeiHky01Lp9Z+MjZhHvXjpP9ZReX172LwF6Sn04lXjwl7HBRAAARAAARAAARAAARAIR8BxhvnqnfW0YEU1lWyvC6cz7RqSR8eN7UVDoxjmZSkd1Hfrfhr+4Lqwsj7/89Sw1/QX2CifccM3+tP+YyOywgrBBRAAARAAARAAARAAgW5JwHGGOfdCemtnRGN6lwFjulv2KhoNAiAAAiAAAiAAAiDgOgKIMXddl0FhEAABEAABEAABEACBZCTgSI95MoJGm0AABEAABEAg0QTqG9uprb3DX21zeydleFKC1Njb3E6RPHVZ3lQqLkgPKmfHiU3ljXT9y99HrHpCSRbNPWdYxDxWXFy5q4Hu+s82ahE8O1KDOffJ8dAzl42xomrITBICSWuYYxPIJLlD0QwQAAEQAAHTBJ79uoLaiXdFZrObDXTV/O76/fMN1VTbEnnnZCMbJZhWVrLg/hbfJgzTblgpWhT4OJEqzlSe15s2/aCfpLT4Zmtq7qCm1g469KdrQgr+9s/jQ57HSRBQCSStYZ4S/KCKXgcBEAABEACBbkWgnXgy5H+qIa56z7sMdTbKD/7zRsrdUBOSTQtl0uI/Twx5zc6T6dQUsvrs0kbKSIn8oBGyYBxPZlJDHKVBVHcikLSGOTzm3ek2RltBAARAAARCEwg2xH359IZ66NJuPdvcCe+cW/uuu+udtIY5PObd/dZG+0EABEAABLoIqAa6+pOvaH8HKxAAAScQiLTWwwn6mdYBHnPT6FAQBEAABEAABEAABEDABgJJa5jDY27D3YQqQQAEQAAEQAAEQAAETBNIWsMcHnPT9wQKggAIgAAIgAAIgAAI2EAgaQ1zWY95aoe9K7dt6HNUCQIgAAIgAAIgAAIg4EACSWuYy3rMQ30AwIH9BJVAAARAAARAAARAAASSnEDSGuayHvMk7180DwRAAARAAARAAARAwCUEktYwl/WYu6SfoCYIgAAIgAAIgAAIgECSE0haw1zWY44Y8yS/w9E8EAABEAABEAABEHAJgaQ1zGU95ogxd8mdCjVBAARAAARAAARAIMkJJK1hLusxT/L+RfNAAARAAARAAARAAARcQiBpDXNZj7lL+glqggAIgAAIgAAIgAAIJDmBpDXMZT3miDFP8jsczQMBEAABEAABEAABlxBIWsNc1mOOGHOX3KlQEwRAAARAAARAAASSnEDSGuayHvMk7180DwRAAARAAARAAARAwCUEktYwl/WYu6SfoCYIgAAIgAAIgAAIgECSE0haw1zWY44Y8yS/w9E8EAABEAABEAABEHAJgaQ1zGU95ogxd8mdCjVBAARAAARAAARAIMkJJK1hLusxT/L+RfNAAARAAARAAARAAARcQiBpDXNZj7lL+glqggAIgAAIgAAIgAAIJDmBpDXMZT3miDFP8jsczQMBEAABEAABEAABlxBIWsO8s7NDqgsQYy6FCZlAAARAAARAAARAAAQsJpC0hnlKStI2zeJbAuJBAARAAARAAARAAATsIJC01itizO24nVAnCIAACIAACIAACICAWQJJa5gjxtzsLYFyIAACIAACIAACIAACdhBIWsMcMeZ23E6oEwRAAARAAARAAARAwCyBpDXMEWNu9pZAORAAARAAARAAARAAATsIJK1hjhhzO24n1AkCIAACIAACIAACIGCWQNIa5ogxN3tLoBwIgAAIgAAIgAAIgIAdBJLWMEeMuR23E+oEARAAARAAARAAARAwSyBpDXPEmJu9JVAOBEAABEAABEAABEDADgJJa5gjxtyO2wl1ggAIgAAIgAAIgAAImCWQtIY5YszN3hIoBwIgAAIgAAIgAAIgYAeBpDXMEWNux+2EOkEABEAABEAABEAABMwSSFrDHDHmZm8JlAMBEAABEAABEAABELCDQNIa5ogxt+N2Qp0gAAIgAAIgAAIgAAJmCSStYY4Yc7O3BMqBAAiAAAiAAAiAAAjYQSBpDXPEmNtxO6FOEAABEAABEAABEAABswSS1jBHjLnZWwLlQAAEQAAEQAAEQAAE7CCQtIY5YsztuJ1QJwiAAAiAAAiAAAiAgFkCSWuYI8bc7C2BciAAAiAA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"}}},{"cell_type":"code","source":"class Downsample_Block(tf.keras.Model):\n    def __init__(self,out_ch,down_sample=True,batch_norm=True):\n        super(Downsample_Block, self).__init__()\n        self.down_sample = down_sample\n        self.batch_norm = batch_norm \n        self.bn = tf.keras.layers.BatchNormalization()\n        self.pool = tf.keras.layers.MaxPool2D(pool_size=(2,2),strides=(2,2))\n        self.conv1 = tf.keras.layers.Conv2D(filters=out_ch, kernel_size=3,padding=\"same\")\n        self.conv2 = tf.keras.layers.Conv2D(filters=out_ch, kernel_size=3,padding=\"same\")\n    \n    @tf.function\n    def call(self,x):\n        if self.down_sample:\n            x = self.pool(x)\n        if self.batch_norm:\n            x = self.bn(x)\n        x = tf.nn.relu(self.conv1(x))\n        x = tf.nn.relu(self.conv2(x))\n        return x\n\n\nclass Upsample_Block(tf.keras.Model):\n    def __init__(self,out_ch):\n        super(Upsample_Block, self).__init__()\n        self.upsample = tf.keras.layers.UpSampling2D(size=(2,2),interpolation='bilinear')\n        self.bn = tf.keras.layers.BatchNormalization()\n        self.conv1 = tf.keras.layers.Conv2D(filters=out_ch,kernel_size=(3,3), padding=\"same\")\n        self.conv2 = tf.keras.layers.Conv2D(filters=out_ch,kernel_size=(3,3), padding=\"same\")\n    \n    @tf.function\n    def call(self,x,skip):\n        up = self.upsample(x)  #size of image gets doubles..ie (16x16) becomes (32x32)\n        out = tf.keras.layers.concatenate([up, skip],axis=-1)\n        out = self.bn(out)\n        out = tf.nn.relu(self.conv1(out))\n        out = tf.nn.relu(self.conv2(out))\n        return out\n\n\nclass Unet(tf.keras.Model):\n    def __init__(self):\n        super(Unet, self).__init__()                                                                   # input          #output\n        self.encoder_block1 = Downsample_Block(out_ch=32,down_sample=False,batch_norm=False) #(512,512,3) -> (512,512,32)  \n        self.encoder_block2 = Downsample_Block(out_ch=64)  #(512,512,32) -> (256,256,64)\n        self.encoder_block3 = Downsample_Block(out_ch=128)  #(256,256,64) -> (128,128,128)\n        self.encoder_block4 = Downsample_Block(out_ch=256)  #(128,128,128) -> (64,64,256)\n        self.encoder_block5 = Downsample_Block(out_ch=512)  #(64,64,256) -> (32,32,512)\n        self.encoder_block6 = Downsample_Block(out_ch=1024) #(32,32,512) -> (16,16,1024)\n\n                                                   # input            skip       output\n        self.decoder_block1 = Upsample_Block(512)  # (16,16,1024)    (32,32,512)  (32,32,512)\n        self.decoder_block2 = Upsample_Block(256)  # (32,32,512)    (64,64,256)  (64,64,256)\n        self.decoder_block3 = Upsample_Block(128)  #(64,64,256)     (128,128,128) (128,128,128)\n        self.decoder_block4 = Upsample_Block(64)   #(128,128,128)   (256,256,64)  (256,256,64)\n        self.decoder_block5 = Upsample_Block(32)   #(256,256,64)   (512,512,32)  (512,512,32)\n        \n        self.last_layer = keras.layers.Conv2D(1,kernel_size=3,padding=\"same\")\n    \n    \n    @tf.function\n    def call(self,x):\n        d1 = self.encoder_block1(x)\n        d2 = self.encoder_block2(d1)\n        d3 = self.encoder_block3(d2)\n        d4 = self.encoder_block4(d3)\n        d5 = self.encoder_block5(d4)\n        d6 = self.encoder_block6(d5)\n\n        u1 = self.decoder_block1(d6,d5)\n        u2 = self.decoder_block2(u1,d4) \n        u3 = self.decoder_block3(u2,d3)\n        u4 = self.decoder_block4(u3,d2)\n        u5 = self.decoder_block5(u4,d1)\n\n        out = self.last_layer(u5)\n\n        return out\n\n    def summary(self,input_shape=(512,512,3)):\n        \"\"\" \n        overriding summary function\n        \"\"\"\n        x = tf.keras.layers.Input(shape=input_shape)\n        model = tf.keras.Model(inputs=[x], outputs=self.call(x))\n        return model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:13:19.651886Z","iopub.execute_input":"2021-12-07T10:13:19.652342Z","iopub.status.idle":"2021-12-07T10:13:19.674161Z","shell.execute_reply.started":"2021-12-07T10:13:19.652305Z","shell.execute_reply":"2021-12-07T10:13:19.673464Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#test code\nmodel = Unet() \nmodel.summary(input_shape=(512,512,3))","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:13:19.840840Z","iopub.execute_input":"2021-12-07T10:13:19.841260Z","iopub.status.idle":"2021-12-07T10:13:20.152284Z","shell.execute_reply.started":"2021-12-07T10:13:19.841219Z","shell.execute_reply":"2021-12-07T10:13:20.151461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section13\"></a>\n## Training\n\n### About competition metric\n![image.png](attachment:c19f12ce-73be-4084-95f8-2d548f2c1e84.png)\n\n```\nThis competition is evaluated on the mean average precision at different intersection over union (IoU) thresholds.\nUsed thresholds = (0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95)\nAt each threshold value t, a precision value is calculated based on the number of true positives (TP), false negatives (FN), and false positives (FP) resulting from comparing the predicted object to all ground truth objects. Basically it will be pixels.\n```\n","metadata":{},"attachments":{"c19f12ce-73be-4084-95f8-2d548f2c1e84.png":{"image/png":"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"}}},{"cell_type":"code","source":"@tf.function\ndef iou_calculator(y_pred,y_true):\n    \"\"\"\n    computes average iou at various thresholds\n    \"\"\"\n    def IoU(y_pred, y_true):\n        I = tf.reduce_sum(y_pred * y_true, axis=(1, 2))\n        U = tf.reduce_sum(y_pred + y_true, axis=(1, 2)) - I\n        return tf.reduce_mean(I / U)\n    \n    ious = []\n    thresholds = [0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95]\n    for thresh in thresholds:\n        y_pred_ = tf.cast(tf.math.greater(y_pred,thresh),dtype=tf.float32)\n        iou = IoU(y_pred_,y_true)\n        ious.append(iou)\n    return tf.reduce_mean(ious)\n\n\n@tf.function\ndef train_step(x, y):\n    '''\n    input: x, y <- typically batches \n    return: loss value,iou_value\n    '''\n\n    # start the scope of gradient \n    with tf.GradientTape() as tape:\n        logits = model(x, training=True) # forward pass\n\n        y_pred_prob = tf.nn.sigmoid(logits)\n        y_pred_prob = tf.squeeze(y_pred_prob,axis=-1)\n        train_loss_value = bce(y, y_pred_prob) # compute loss \n        train_iou_value = iou_calculator(y, y_pred_prob)\n\n    # compute gradient \n    grads = tape.gradient(train_loss_value, model.trainable_weights)\n\n    # update weights\n    optimizer.apply_gradients(zip(grads, model.trainable_weights))\n    \n    return train_loss_value.numpy(),train_iou_value.numpy()\n\n\n@tf.function\ndef val_step(X,y):\n\n    # forward pass\n    yhat = model(X, training=False)\n    \n    # calculate loss\n    y_pred_prob = tf.nn.sigmoid(yhat)\n    y_pred_prob = tf.squeeze(y_pred_prob,axis=-1)\n    val_loss_value = bce(y, y_pred_prob) # compute loss \n    val_iou_value = iou_calculator(y, y_pred_prob)\n    \n    return val_loss_value.numpy(), val_iou_value.numpy()\n","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:13:23.235271Z","iopub.execute_input":"2021-12-07T10:13:23.235555Z","iopub.status.idle":"2021-12-07T10:13:23.247957Z","shell.execute_reply.started":"2021-12-07T10:13:23.235516Z","shell.execute_reply":"2021-12-07T10:13:23.246728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As of now we will train our model for about 15 epochs and will see the results","metadata":{}},{"cell_type":"code","source":"epochs=15\nmodel_weight_dir = './model_weights'\n#loss\nbce = tf.keras.losses.BinaryCrossentropy()\n#optimizer\noptimizer = tf.keras.optimizers.Adam()\n\n\n\nif not os.path.exists(model_weight_dir):\n    os.makedirs(model_weight_dir)\n\nepoch_train_losses,epoch_val_losses = [],[]\nepoch_train_ious,epoch_val_ious = [],[]\n\nepoch_loss_min = float('inf')\n\nfor epoch in range(epochs):\n    print('Epoch {}/{}'.format(epoch+1, epochs))\n    t = time.time()\n    train_loss,train_iou = [],[]\n    train_progbar = tf.keras.utils.Progbar(len(train_data))\n    for idx,data in enumerate(train_data):\n        image,mask = data\n        batch_train_loss,batch_train_iou = train_step(image,mask)     \n        train_progbar.update(idx+1) \n        train_loss.append(batch_train_loss)\n        train_iou.append(batch_train_iou)\n    \n    val_loss,val_iou = [],[]\n    val_progbar = tf.keras.utils.Progbar(len(val_data))\n    for idx,data in enumerate(val_data):\n        image,mask = data\n        batch_val_loss,batch_val_iou = val_step(image,mask)\n        val_progbar.update(idx+1)\n        val_loss.append(batch_val_loss)\n        val_iou.append(batch_val_iou)\n       \n    epoch_train_loss = np.mean(train_loss)\n    epoch_val_loss = np.mean(val_loss)\n    epoch_train_iou = np.mean(train_iou)\n    epoch_val_iou = np.mean(val_iou)\n\n\n    epoch_train_losses.append(epoch_train_loss)\n    epoch_val_losses.append(epoch_val_loss)\n    epoch_train_ious.append(epoch_train_iou)\n    epoch_val_ious.append(epoch_val_iou)\n\n\n\n    #save model if loss decreases\n    if epoch_val_loss < epoch_loss_min:\n        print(f'Saving model--Loss decreased from {str(epoch_loss_min)} to {str(epoch_val_loss)}')\n        weight_name = 'bestmodel.h5'\n        weight_path = os.path.join(model_weight_dir,weight_name)\n        model.save_weights(weight_path)\n        epoch_loss_min = epoch_val_loss\n        \n    template = 'ETA: {} \\n Train loss: {} Train iou: {} Validation loss:{} Validation iou:{}'\n    \n    print(template.format(round((time.time() - t)/60, 2),round(epoch_train_loss,4),round(epoch_train_iou,4),round(epoch_val_loss,4),round(epoch_val_iou,4)))","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:13:24.911597Z","iopub.execute_input":"2021-12-07T10:13:24.912144Z","iopub.status.idle":"2021-12-07T10:33:06.186914Z","shell.execute_reply.started":"2021-12-07T10:13:24.912106Z","shell.execute_reply":"2021-12-07T10:33:06.186165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Actually you can train more epochs.For the ease of use iam stopping here.","metadata":{}},{"cell_type":"code","source":"#plot\nepochs = [i for i in range(15)]\nfig,axes = plt.subplots(1,2,figsize=(15,6))\naxes[0].plot(epochs,epoch_train_losses,label=\"train loss\")\naxes[0].plot(epochs,epoch_val_losses,label=\"val loss\")\naxes[1].plot(epochs,epoch_train_ious,label=\"train iou\")\naxes[1].plot(epochs,epoch_val_ious,label=\"val iou\")\naxes[0].legend()\naxes[1].legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:33:47.450093Z","iopub.execute_input":"2021-12-07T10:33:47.450807Z","iopub.status.idle":"2021-12-07T10:33:47.790330Z","shell.execute_reply.started":"2021-12-07T10:33:47.450766Z","shell.execute_reply":"2021-12-07T10:33:47.789679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We know training is not smooth. But as a baseline we can go ahead with this model","metadata":{}},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section14\"></a>\n## Inference","metadata":{}},{"cell_type":"code","source":"class Downsample_Block(tf.keras.Model):\n    def __init__(self,out_ch,down_sample=True,batch_norm=True):\n        super(Downsample_Block, self).__init__()\n        self.down_sample = down_sample\n        self.batch_norm = batch_norm \n        self.bn = tf.keras.layers.BatchNormalization()\n        self.pool = tf.keras.layers.MaxPool2D(pool_size=(2,2),strides=(2,2))\n        self.conv1 = tf.keras.layers.Conv2D(filters=out_ch, kernel_size=3,padding=\"same\")\n        self.conv2 = tf.keras.layers.Conv2D(filters=out_ch, kernel_size=3,padding=\"same\")\n    \n    @tf.function\n    def call(self,x):\n        if self.down_sample:\n            x = self.pool(x)\n        if self.batch_norm:\n            x = self.bn(x)\n        x = tf.nn.relu(self.conv1(x))\n        x = tf.nn.relu(self.conv2(x))\n        return x\n\n\nclass Upsample_Block(tf.keras.Model):\n    def __init__(self,out_ch):\n        super(Upsample_Block, self).__init__()\n        self.upsample = tf.keras.layers.UpSampling2D(size=(2,2),interpolation='bilinear')\n        self.bn = tf.keras.layers.BatchNormalization()\n        self.conv1 = tf.keras.layers.Conv2D(filters=out_ch,kernel_size=(3,3), padding=\"same\")\n        self.conv2 = tf.keras.layers.Conv2D(filters=out_ch,kernel_size=(3,3), padding=\"same\")\n    \n    @tf.function\n    def call(self,x,skip):\n        up = self.upsample(x)  #size of image gets doubles..ie (16x16) becomes (32x32)\n        out = tf.keras.layers.concatenate([up, skip],axis=-1)\n        out = self.bn(out)\n        out = tf.nn.relu(self.conv1(out))\n        out = tf.nn.relu(self.conv2(out))\n        return out\n\n\nclass Unet(tf.keras.Model):\n    def __init__(self):\n        super(Unet, self).__init__()                                                                   # input          #output\n        self.encoder_block1 = Downsample_Block(out_ch=32,down_sample=False,batch_norm=False) #(512,512,3) -> (512,512,32)  \n        self.encoder_block2 = Downsample_Block(out_ch=64)  #(512,512,32) -> (256,256,64)\n        self.encoder_block3 = Downsample_Block(out_ch=128)  #(256,256,64) -> (128,128,128)\n        self.encoder_block4 = Downsample_Block(out_ch=256)  #(128,128,128) -> (64,64,256)\n        self.encoder_block5 = Downsample_Block(out_ch=512)  #(64,64,256) -> (32,32,512)\n        self.encoder_block6 = Downsample_Block(out_ch=1024) #(32,32,512) -> (16,16,1024)\n\n                                                   # input            skip       output\n        self.decoder_block1 = Upsample_Block(512)  # (16,16,1024)    (32,32,512)  (32,32,512)\n        self.decoder_block2 = Upsample_Block(256)  # (32,32,512)    (64,64,256)  (64,64,256)\n        self.decoder_block3 = Upsample_Block(128)  #(64,64,256)     (128,128,128) (128,128,128)\n        self.decoder_block4 = Upsample_Block(64)   #(128,128,128)   (256,256,64)  (256,256,64)\n        self.decoder_block5 = Upsample_Block(32)   #(256,256,64)   (512,512,32)  (512,512,32)\n        \n        self.last_layer = keras.layers.Conv2D(1,kernel_size=3,padding=\"same\")\n    \n    \n    @tf.function\n    def call(self,x):\n        d1 = self.encoder_block1(x)\n        d2 = self.encoder_block2(d1)\n        d3 = self.encoder_block3(d2)\n        d4 = self.encoder_block4(d3)\n        d5 = self.encoder_block5(d4)\n        d6 = self.encoder_block6(d5)\n\n        u1 = self.decoder_block1(d6,d5)\n        u2 = self.decoder_block2(u1,d4) \n        u3 = self.decoder_block3(u2,d3)\n        u4 = self.decoder_block4(u3,d2)\n        u5 = self.decoder_block5(u4,d1)\n\n        out = self.last_layer(u5)\n\n        return out\n\n    def summary(self,input_shape=(512,512,3)):\n        \"\"\" \n        overriding summary function\n        \"\"\"\n        x = tf.keras.layers.Input(shape=input_shape)\n        model = tf.keras.Model(inputs=[x], outputs=self.call(x))\n        return model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:34:04.386606Z","iopub.execute_input":"2021-12-07T10:34:04.386872Z","iopub.status.idle":"2021-12-07T10:34:04.410125Z","shell.execute_reply.started":"2021-12-07T10:34:04.386840Z","shell.execute_reply":"2021-12-07T10:34:04.409395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#load weights\n\nmodel = Unet()\nx = tf.keras.layers.Input(shape=(512,512,3))\nmodel = tf.keras.Model(inputs=[x], outputs=model.call(x))\n\n# model.built = True\nmodel.load_weights('./model_weights/bestmodel.h5')","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:34:05.462333Z","iopub.execute_input":"2021-12-07T10:34:05.463077Z","iopub.status.idle":"2021-12-07T10:34:05.901555Z","shell.execute_reply.started":"2021-12-07T10:34:05.463032Z","shell.execute_reply":"2021-12-07T10:34:05.900745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### visualizing train images","metadata":{}},{"cell_type":"code","source":"#train infernce\nthresh = 0.5\niter_ = train_data.as_numpy_iterator()\nimages,masks = next(iter_)\nout_mask = np.squeeze(tf.nn.sigmoid(model.predict(images)))\nout_mask = tf.cast(tf.math.greater(out_mask,thresh),dtype=tf.float32)\nfor i in range(len(images)):\n    image = images[i]\n    mask = masks[i]\n    mask_pred = out_mask[i]\n    fig,axes = plt.subplots(1,3,figsize=(10,20))\n    axes[0].imshow(image)\n    axes[0].set_title('Image')\n    axes[1].imshow(mask,cmap=\"gray\")\n    axes[1].set_title('Mask')\n    axes[2].imshow(mask_pred,cmap='gray')\n    axes[2].set_title('Predicted mask')","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:34:15.144429Z","iopub.execute_input":"2021-12-07T10:34:15.144915Z","iopub.status.idle":"2021-12-07T10:34:18.946525Z","shell.execute_reply.started":"2021-12-07T10:34:15.144877Z","shell.execute_reply":"2021-12-07T10:34:18.945652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## visualizing validation images","metadata":{}},{"cell_type":"code","source":"#validation infernce\nthresh = 0.5\niter_ = val_data.as_numpy_iterator()\nimages,masks = next(iter_)\nout_mask = np.squeeze(tf.nn.sigmoid(model.predict(images)))\nout_mask = tf.cast(tf.math.greater(out_mask,thresh),dtype=tf.float32)\n\nfor i in range(len(images)):\n    image = images[i]\n    mask = masks[i]\n    mask_pred = out_mask[i]\n    fig,axes = plt.subplots(1,3,figsize=(10,20))\n    axes[0].imshow(image)\n    axes[0].set_title('Image')\n    axes[1].imshow(mask,cmap=\"gray\")\n    axes[1].set_title('Mask')\n    axes[2].imshow(mask_pred,cmap='gray')\n    axes[2].set_title('Predicted mask')","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:34:22.447143Z","iopub.execute_input":"2021-12-07T10:34:22.447432Z","iopub.status.idle":"2021-12-07T10:34:26.262584Z","shell.execute_reply.started":"2021-12-07T10:34:22.447391Z","shell.execute_reply":"2021-12-07T10:34:26.261754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### visualizing test images","metadata":{}},{"cell_type":"code","source":"def load_and_predict(img_path,thresh=0.5):\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img,(512,512))\n    img = img/255.0\n    img = tf.cast(img,dtype=tf.float32)\n    img = tf.expand_dims(img,axis=0)\n    \n    #predict\n    out_mask = np.squeeze(tf.nn.sigmoid(model.predict(img)))\n    if thresh:\n        out_mask = tf.cast(tf.math.greater(out_mask,thresh),dtype=tf.float32)\n    return out_mask","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:34:46.887233Z","iopub.execute_input":"2021-12-07T10:34:46.887884Z","iopub.status.idle":"2021-12-07T10:34:46.894140Z","shell.execute_reply.started":"2021-12-07T10:34:46.887843Z","shell.execute_reply":"2021-12-07T10:34:46.893380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_DIR_PATH = '../input/sartorius-cell-instance-segmentation/test'\nfor img_name in os.listdir(TEST_DIR_PATH):\n    \n    img_path = os.path.join(TEST_DIR_PATH,img_name)\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img,(512,512))\n    \n    mask = load_and_predict(img_path,thresh=0.5)\n    fig,axes = plt.subplots(1,2,figsize=(10,20))\n    axes[0].imshow(img)\n    axes[0].set_title('Image')\n    axes[1].imshow(mask,cmap=\"gray\")\n    axes[1].set_title('Predicted Mask')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-07T10:34:47.121579Z","iopub.execute_input":"2021-12-07T10:34:47.122246Z","iopub.status.idle":"2021-12-07T10:34:48.592164Z","shell.execute_reply.started":"2021-12-07T10:34:47.122199Z","shell.execute_reply":"2021-12-07T10:34:48.591522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a class=\"anchor\" id=\"section15\"></a>\n## Test Image Prediction and submission","metadata":{}},{"cell_type":"markdown","source":"You can refer my [prediction](http://https://www.kaggle.com/arunmohan003/inference-cell-segmentation-baseline-unet) kernel for a baseline submission\n\n","metadata":{}}]}