{"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":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport cv2\nfrom tensorflow import keras\nimport tensorflow as tf\nimport keras\nfrom keras import backend as K\nfrom keras.models import Model\nfrom keras.layers import Input\nfrom keras.layers.convolutional import Conv2D, Conv2DTranspose\nfrom keras.layers.pooling import MaxPooling2D\nfrom keras.layers.merge import concatenate\nfrom keras.losses import binary_crossentropy\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.models import load_model\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nfrom tensorflow.keras.utils import image_dataset_from_directory\nimport PIL,gc,os,sys\nimport imageio","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-28T06:00:24.523743Z","iopub.execute_input":"2021-11-28T06:00:24.524163Z","iopub.status.idle":"2021-11-28T06:00:30.565577Z","shell.execute_reply.started":"2021-11-28T06:00:24.524064Z","shell.execute_reply":"2021-11-28T06:00:30.564846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')\nprint(train_df.shape)\ntrain_df.head(4)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:30.567162Z","iopub.execute_input":"2021-11-28T06:00:30.567404Z","iopub.status.idle":"2021-11-28T06:00:31.098171Z","shell.execute_reply.started":"2021-11-28T06:00:30.567368Z","shell.execute_reply":"2021-11-28T06:00:31.097414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = ''\nimage_path = os.path.join(path, '../input/sartoriuscellinstancesegmentationmaskpng/TrainImage2x2/')\nmask_path = os.path.join(path, '../input/sartoriuscellinstancesegmentationmaskpng/TrainMask2x2/')\nimage_list = sorted(os.listdir(image_path))\nmask_list = sorted(os.listdir(mask_path))\nimage_list = [image_path+i for i in image_list]\nmask_list = [mask_path+i for i in mask_list]\n#print(image_list)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:31.099495Z","iopub.execute_input":"2021-11-28T06:00:31.100094Z","iopub.status.idle":"2021-11-28T06:00:31.220094Z","shell.execute_reply.started":"2021-11-28T06:00:31.100032Z","shell.execute_reply":"2021-11-28T06:00:31.219331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape, color=1):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background.\n    ref: https://www.kaggle.com/inversion/run-length-decoding-quick-start\n    '''\n    s = mask_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    img = np.zeros((shape[0] * shape[1]), dtype=np.float32)\n    for lo, hi in zip(starts, ends):\n        img[lo : hi] = color\n    return img.reshape(shape)\n\n\ndef rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    ref: https://www.kaggle.com/dragonzhang/positive-score-with-detectron-3-3-inference\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    return ' '.join(str(x) for x in runs)\n\ndef make_predictions(dataset, num, keras_model):\n    '''\n    For a tf.Dataset, makes predictions for n=num (num =-1 or all_images takes all images in the dataset), \n    images using a keras_model. Returns a list of predicted masks, each as ndarray. \n    '''\n    predictions = []\n    if dataset:\n        for image in dataset.take(num):\n            image = image[None]\n            pred_mask = keras_model.predict(image)\n            # changes shape from (1,512,512,1) to (512,512)\n            pred_mask = pred_mask[0, :, :, 0]\n            # fix overlaps\n            if check_overlap(msk=pred_mask)==True:\n                pred_mask = pred_mask[None]\n                pred_mask = fix_overlap(msk=pred_mask)\n            # transforms ndarray values to 0s and 1s\n            pred_mask =  np.where( pred_mask > 0.5, 1, 0)\n            predictions.append(pred_mask)\n    return predictions\n\ndef get_mask(image_id, df):\n    '''\n    Uses rle_decode() to get ndarray from mask using image_id in dataframe (df).\n    ref: https://www.kaggle.com/barteksadlej123/sartors-tf-starter\n    '''\n    current = df[df[\"id\"] == image_id]\n    labels = current[\"annotation\"].tolist()\n    \n    mask = np.zeros((HEIGHT, WIDTH))\n    for label in labels:\n        mask += rle_decode(label, (HEIGHT, WIDTH))\n    mask = mask.clip(0, 1)\n    \n    return mask\n\n\n#  fix overlaps: \n\ndef check_overlap(msk):\n    '''\n    Checks if there are overlap in a mask (msk).\n    ref: https://www.kaggle.com/awsaf49/sartorius-fix-overlap\n    '''\n    msk = msk.astype(np.bool).astype(np.uint8)\n    return np.any(np.sum(msk, axis=-1)>1)\n\n\ndef fix_overlap(msk):\n    '''\n    Args:\n        mask: multi-channel mask, each channel is an instance of cell, shape:(520,704,None)\n    Returns:\n        multi-channel mask with non-overlapping values, shape:(520,704,None) \n    ref: https://www.kaggle.com/awsaf49/sartorius-fix-overlap\n    '''\n    msk = np.array(msk)\n    msk = np.pad(msk, [[0,0],[0,0],[1,0]])\n    ins_len = msk.shape[-1]\n    msk = np.argmax(msk,axis=-1)\n    msk = tf.keras.utils.to_categorical(msk, num_classes=ins_len)\n    msk = msk[...,1:]\n    msk = msk[...,np.any(msk, axis=(0,1))]\n    return msk\n","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:31.222758Z","iopub.execute_input":"2021-11-28T06:00:31.223354Z","iopub.status.idle":"2021-11-28T06:00:31.241225Z","shell.execute_reply.started":"2021-11-28T06:00:31.223314Z","shell.execute_reply":"2021-11-28T06:00:31.240468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(image_list)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:31.242206Z","iopub.execute_input":"2021-11-28T06:00:31.242400Z","iopub.status.idle":"2021-11-28T06:00:31.266012Z","shell.execute_reply.started":"2021-11-28T06:00:31.242377Z","shell.execute_reply":"2021-11-28T06:00:31.264875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_list[0:4]","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:31.270641Z","iopub.execute_input":"2021-11-28T06:00:31.271076Z","iopub.status.idle":"2021-11-28T06:00:31.279928Z","shell.execute_reply.started":"2021-11-28T06:00:31.271025Z","shell.execute_reply":"2021-11-28T06:00:31.279171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_list[0:4]","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:31.281678Z","iopub.execute_input":"2021-11-28T06:00:31.282357Z","iopub.status.idle":"2021-11-28T06:00:31.303741Z","shell.execute_reply.started":"2021-11-28T06:00:31.282300Z","shell.execute_reply":"2021-11-28T06:00:31.302092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Check out the some of the unmasked and masked images from the dataset:","metadata":{}},{"cell_type":"code","source":"N = 1000\nimg = cv2.imread(image_list[N])\nmask = cv2.imread(mask_list[N],cv2.IMREAD_GRAYSCALE)\nprint(mask.shape)\n#mask = np.array([max(mask[i, j]) for i in range(mask.shape[0]) for j in range(mask.shape[1])]).reshape(img.shape[0], img.shape[1])\n\nfig, arr = plt.subplots(1, 2, figsize=(14, 10))\narr[0].imshow(img)\narr[0].set_title('Image')\narr[1].imshow(mask)\narr[1].set_title('Segmentation')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:31.306676Z","iopub.execute_input":"2021-11-28T06:00:31.307177Z","iopub.status.idle":"2021-11-28T06:00:32.091426Z","shell.execute_reply.started":"2021-11-28T06:00:31.307138Z","shell.execute_reply":"2021-11-28T06:00:32.088060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape, color=1):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = mask_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    img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n    for lo, hi in zip(starts, ends):\n        img[lo : hi] = color\n    return img.reshape(shape)\n\n\ndef build_masks(labels,input_shape, colors=True):\n    height, width = input_shape\n    if colors:\n        mask = np.zeros((height, width, 3))\n        for label in labels:\n            mask += rle_decode(label, shape=(height,width , 3), color=np.random.rand(3))\n    else:\n        mask = np.zeros((height, width, 1))\n        for label in labels:\n            mask += rle_decode(label, shape=(height, width, 1))\n    mask = mask.clip(0, 1)\n    return mask\n\ndef rle2maskResize(rle):\n    # CONVERT RLE TO MASK \n    if (len(rle)==0): \n        return np.zeros((256,256) ,dtype=np.uint8)\n    \n    height= 520\n    width = 704\n    mask= np.zeros( width*height ,dtype=np.uint8)\n\n    array = np.asarray([int(x) for x in rle.split()])\n    starts = array[0::2]-1\n    lengths = array[1::2]    \n    for index, start in enumerate(starts):\n        mask[int(start):int(start+lengths[index])] = 1\n    \n    return mask.reshape( (height,width), order='F' )[::2,::2]\n\ndef make_predictions(dataset, num, keras_model):\n    '''\n    For a tf.Dataset, makes predictions for n=num (num =-1 or all_images takes all images in the dataset), \n    images using a keras_model. Returns a list of predicted masks, each as ndarray. \n    '''\n    predictions = []\n    if dataset:\n        for image in dataset.take(num):\n            image = image[None]\n            pred_mask = keras_model.predict(image)\n            # changes shape from (1,512,512,1) to (512,512)\n            pred_mask = pred_mask[0, :, :, 0]\n            # fix overlaps\n            if check_overlap(msk=pred_mask)==True:\n                pred_mask = pred_mask[None]\n                pred_mask = fix_overlap(msk=pred_mask)\n            # transforms ndarray values to 0s and 1s\n            pred_mask =  np.where( pred_mask > 0.5, 1, 0)\n            predictions.append(pred_mask)\n    return predictions","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2021-11-28T06:00:32.092569Z","iopub.execute_input":"2021-11-28T06:00:32.092822Z","iopub.status.idle":"2021-11-28T06:00:32.112377Z","shell.execute_reply.started":"2021-11-28T06:00:32.092788Z","shell.execute_reply":"2021-11-28T06:00:32.111717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 2.1 - Split Your Dataset into Unmasked and Masked Images","metadata":{}},{"cell_type":"code","source":"image_list_ds = tf.data.Dataset.list_files(image_list, shuffle=False)\nmask_list_ds = tf.data.Dataset.list_files(mask_list, shuffle=False)\n\nfor path in zip(image_list_ds.take(3), mask_list_ds.take(3)):\n    print(path)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:32.117419Z","iopub.execute_input":"2021-11-28T06:00:32.117615Z","iopub.status.idle":"2021-11-28T06:00:36.064464Z","shell.execute_reply.started":"2021-11-28T06:00:32.117583Z","shell.execute_reply":"2021-11-28T06:00:36.063701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_filenames = tf.constant(image_list)\nmasks_filenames = tf.constant(mask_list)\n\ndataset = tf.data.Dataset.from_tensor_slices((image_filenames, masks_filenames))\n\nfor image, mask in dataset.take(5):\n    print(image)\n    print(mask)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.065814Z","iopub.execute_input":"2021-11-28T06:00:36.066671Z","iopub.status.idle":"2021-11-28T06:00:36.082538Z","shell.execute_reply.started":"2021-11-28T06:00:36.066630Z","shell.execute_reply":"2021-11-28T06:00:36.081507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In addition, the image color values are normalized to the [0,1] range.","metadata":{}},{"cell_type":"code","source":"def normalize(input_image, input_mask):\n    input_image = tf.cast(input_image, tf.float32) / 255.0\n    input_mask -= 1\n    return input_image, input_mask","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.083888Z","iopub.execute_input":"2021-11-28T06:00:36.084222Z","iopub.status.idle":"2021-11-28T06:00:36.089156Z","shell.execute_reply.started":"2021-11-28T06:00:36.084183Z","shell.execute_reply":"2021-11-28T06:00:36.088249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_image(input_image1, input_mask1):\n    input_image = tf.image.resize(input_image1, (512, 512))\n    input_mask = tf.image.resize(input_mask1, (512, 512))\n\n    input_image, input_mask = normalize(input_image, input_mask)\n\n    return input_image, input_mask","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.090628Z","iopub.execute_input":"2021-11-28T06:00:36.090890Z","iopub.status.idle":"2021-11-28T06:00:36.098725Z","shell.execute_reply.started":"2021-11-28T06:00:36.090857Z","shell.execute_reply":"2021-11-28T06:00:36.097675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# constants\n\nDEBUG = False\n\nSEED = 123\nWIDTH, HEIGHT = 260, 352\nRESIZE_WIDTH, RESIZE_HEIGHT = 256, 256\nBATCH_SIZE = 32\nBUFFER_SIZE = 32\nVAL_SPLIT = 0.2\n\nAUTO = tf.data.AUTOTUNE\n\nEPOCHS = 20","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.100436Z","iopub.execute_input":"2021-11-28T06:00:36.100789Z","iopub.status.idle":"2021-11-28T06:00:36.107986Z","shell.execute_reply.started":"2021-11-28T06:00:36.100753Z","shell.execute_reply":"2021-11-28T06:00:36.107000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(image_list, mask_list, test_size=VAL_SPLIT, random_state=SEED)\nprint(X_train[0:4])\nprint(y_train[0:4])","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.109589Z","iopub.execute_input":"2021-11-28T06:00:36.109902Z","iopub.status.idle":"2021-11-28T06:00:36.122697Z","shell.execute_reply.started":"2021-11-28T06:00:36.109869Z","shell.execute_reply":"2021-11-28T06:00:36.121913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train_ds = tf.data.Dataset.list_files(X_train, shuffle=False)\nX_test_ds = tf.data.Dataset.list_files(X_test, shuffle=False)\ny_train_ds = tf.data.Dataset.list_files(y_train, shuffle=False)\ny_test_ds = tf.data.Dataset.list_files(y_test, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.123724Z","iopub.execute_input":"2021-11-28T06:00:36.126537Z","iopub.status.idle":"2021-11-28T06:00:36.168503Z","shell.execute_reply.started":"2021-11-28T06:00:36.126511Z","shell.execute_reply":"2021-11-28T06:00:36.167867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train_filenames = tf.constant(X_train)\nX_test_filenames = tf.constant(X_test)\ny_train_filenames = tf.constant(y_train)\ny_test_filenames = tf.constant(y_test)\nprint(X_train_filenames)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.169444Z","iopub.execute_input":"2021-11-28T06:00:36.169679Z","iopub.status.idle":"2021-11-28T06:00:36.176703Z","shell.execute_reply.started":"2021-11-28T06:00:36.169647Z","shell.execute_reply":"2021-11-28T06:00:36.175798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"###### tempimg = imageio.imread(X_train[1])\ntempmask = cv2.imread(y_train[1],cv2.IMREAD_GRAYSCALE)\ntempimg = cv2.imread(X_train[1])\nprint(tempmask.shape)\nprint(tempimg.shape)\ntempmask = cv2.resize(tempmask,(RESIZE_WIDTH,RESIZE_WIDTH))\ntempimg = cv2.resize(tempimg,(RESIZE_WIDTH,RESIZE_WIDTH))\nprint(tempmask.shape)\nprint(tempimg.shape)\nfig, arr = plt.subplots(1, 2, figsize=(14, 10))\narr[0].imshow(tempimg)\narr[0].set_title('Image')\narr[1].imshow(tempmask)\narr[1].set_title('Segmentation')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.178253Z","iopub.execute_input":"2021-11-28T06:00:36.178544Z","iopub.status.idle":"2021-11-28T06:00:36.629410Z","shell.execute_reply.started":"2021-11-28T06:00:36.178499Z","shell.execute_reply":"2021-11-28T06:00:36.628535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_generator(X,y):\n    \n    for image_id in X:\n        image = cv2.imread(image_id) \n                \n        image = cv2.resize(image, (RESIZE_HEIGHT, RESIZE_WIDTH))\n        \n        image = image.astype(np.float32)\n    for image_id in y:\n        mask = cv2.imread(image_id,cv2.IMREAD_GRAYSCALE) \n        \n        \n        mask = cv2.resize(mask, (RESIZE_HEIGHT, RESIZE_HEIGHT))\n        mask = mask.reshape((*mask.shape, 1))\n        mask = mask.astype(np.int32)\n    yield image, mask","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.630908Z","iopub.execute_input":"2021-11-28T06:00:36.631445Z","iopub.status.idle":"2021-11-28T06:00:36.638743Z","shell.execute_reply.started":"2021-11-28T06:00:36.631406Z","shell.execute_reply":"2021-11-28T06:00:36.638059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# use the generator to get training and validation sets\ntrain_ds = tf.data.Dataset.from_generator(\n    lambda : train_generator(X_train,y_train), \n    output_types=(tf.float32, tf.int32),\n    output_shapes=((RESIZE_HEIGHT, RESIZE_WIDTH,3), (RESIZE_HEIGHT, RESIZE_WIDTH,1)))\n\nvalid_ds = tf.data.Dataset.from_generator(\n    lambda : train_generator(X_test,y_test), \n    output_types=(tf.float32, tf.int32),\n    output_shapes=((RESIZE_HEIGHT, RESIZE_WIDTH,3), (RESIZE_HEIGHT, RESIZE_WIDTH,1)))","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.640065Z","iopub.execute_input":"2021-11-28T06:00:36.640535Z","iopub.status.idle":"2021-11-28T06:00:36.699591Z","shell.execute_reply.started":"2021-11-28T06:00:36.640500Z","shell.execute_reply":"2021-11-28T06:00:36.698957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The following class performs a simple augmentation by randomly-flipping an image. Go to the Image augmentation tutorial to learn more.","metadata":{}},{"cell_type":"code","source":"class Augment(tf.keras.layers.Layer):\n    def __init__(self, seed=SEED):\n        super().__init__()\n    # both use the same seed, so they'll make the same random changes.\n        self.augment_inputs = tf.keras.layers.RandomFlip(mode=\"horizontal\", seed=seed)\n        self.augment_labels = tf.keras.layers.RandomFlip(mode=\"horizontal\", seed=seed)\n\n    def call(self, inputs, labels):\n        inputs = self.augment_inputs(inputs)\n        labels = self.augment_labels(labels)\n        return inputs, labels","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.701647Z","iopub.execute_input":"2021-11-28T06:00:36.702369Z","iopub.status.idle":"2021-11-28T06:00:36.708946Z","shell.execute_reply.started":"2021-11-28T06:00:36.702331Z","shell.execute_reply":"2021-11-28T06:00:36.708277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# \"build the input pipeline, applying the augmentation after batching the inputs\"\n\ntrain_ds = (\n    train_ds\n    .shuffle(BUFFER_SIZE)\n    .batch(BATCH_SIZE)\n    .repeat()\n    .map(Augment())\n    .prefetch(AUTO))\n\nvalid_ds = (\n    valid_ds\n    .batch(BATCH_SIZE)\n    .repeat()\n    .prefetch(AUTO))","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.710365Z","iopub.execute_input":"2021-11-28T06:00:36.710621Z","iopub.status.idle":"2021-11-28T06:00:36.848956Z","shell.execute_reply.started":"2021-11-28T06:00:36.710587Z","shell.execute_reply":"2021-11-28T06:00:36.848306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds.take(2)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.850634Z","iopub.execute_input":"2021-11-28T06:00:36.851372Z","iopub.status.idle":"2021-11-28T06:00:36.857575Z","shell.execute_reply.started":"2021-11-28T06:00:36.851335Z","shell.execute_reply":"2021-11-28T06:00:36.856854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Visualize an image example and its corresponding mask from the dataset.","metadata":{}},{"cell_type":"code","source":"def display(display_list):\n    plt.figure(figsize=(20, 20))\n\n    title = ['Input Image', 'True Mask','Predicted Mask']\n\n    for i in range(len(display_list)):\n        plt.subplot(1, len(display_list), i+1)\n        plt.title(title[i])\n        try:\n            plt.imshow(tf.keras.utils.array_to_img(display_list[i]))\n        except:\n            plt.imshow(display_list[i])\n        plt.axis('off')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.859073Z","iopub.execute_input":"2021-11-28T06:00:36.859564Z","iopub.status.idle":"2021-11-28T06:00:36.866726Z","shell.execute_reply.started":"2021-11-28T06:00:36.859528Z","shell.execute_reply":"2021-11-28T06:00:36.866094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for images, masks in train_ds.take(2):\n    sample_image, sample_mask = images[0], masks[0]\n    print(sample_image.shape)\n    print(sample_mask.shape)\n    display([sample_image, sample_mask])","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:00:36.868406Z","iopub.execute_input":"2021-11-28T06:00:36.869112Z","iopub.status.idle":"2021-11-28T06:01:21.544508Z","shell.execute_reply.started":"2021-11-28T06:00:36.869076Z","shell.execute_reply":"2021-11-28T06:01:21.542925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras import backend as K\nfrom keras.losses import binary_crossentropy\nimport tensorflow as tf\n\ndef dice_coef(y_true, y_pred, smooth=1):\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = K.sum(y_true_f * y_pred_f)\n    return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n\ndef iou_coef(y_true, y_pred, smooth=1):\n    intersection = K.sum(K.abs(y_true * y_pred), axis=[1,2,3])\n    union = K.sum(y_true,[1,2,3])+K.sum(y_pred,[1,2,3])-intersection\n    iou = K.mean((intersection + smooth) / (union + smooth), axis=0)\n    return iou\n\ndef dice_loss(y_true, y_pred):\n    smooth = 1.\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = y_true_f * y_pred_f\n    score = (2. * K.sum(intersection) + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n    return 1. - score\n\ndef bce_dice_loss(y_true, y_pred):\n    return binary_crossentropy(tf.cast(y_true, tf.float32), y_pred) + 0.5 * dice_loss(tf.cast(y_true, tf.float32), y_pred)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:01:21.546661Z","iopub.execute_input":"2021-11-28T06:01:21.547220Z","iopub.status.idle":"2021-11-28T06:01:21.558346Z","shell.execute_reply.started":"2021-11-28T06:01:21.547179Z","shell.execute_reply":"2021-11-28T06:01:21.557535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ../input/segmentation-models-library-python/\n!mkdir -p /tmp/pip/cache/\n!cp ../input/segmentation-models-library-python/segmentation_models-1.0.1.xyz /tmp/pip/cache/segmentation_models-1.0.1.tar.gz\n!cp ../input/segmentation-models-library-python/segmentation_models-1.0.1-py3-none-any.whl /tmp/pip/cache/","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:15:44.577464Z","iopub.execute_input":"2021-11-28T06:15:44.577809Z","iopub.status.idle":"2021-11-28T06:15:47.349006Z","shell.execute_reply.started":"2021-11-28T06:15:44.577769Z","shell.execute_reply":"2021-11-28T06:15:47.348097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install segmentation_models --no-index --find-links /tmp/pip/cache/ ","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:16:55.770295Z","iopub.execute_input":"2021-11-28T06:16:55.771060Z","iopub.status.idle":"2021-11-28T06:16:57.292452Z","shell.execute_reply.started":"2021-11-28T06:16:55.771001Z","shell.execute_reply":"2021-11-28T06:16:57.291592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip download segmentation_models","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:18:07.329042Z","iopub.execute_input":"2021-11-28T06:18:07.329447Z","iopub.status.idle":"2021-11-28T06:18:19.285838Z","shell.execute_reply.started":"2021-11-28T06:18:07.329405Z","shell.execute_reply":"2021-11-28T06:18:19.285019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import segmentation_models as sm\nsm.set_framework('tf.keras')\nsm.framework()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.261274Z","iopub.execute_input":"2021-11-28T06:02:30.262071Z","iopub.status.idle":"2021-11-28T06:02:30.561779Z","shell.execute_reply.started":"2021-11-28T06:02:30.262017Z","shell.execute_reply":"2021-11-28T06:02:30.560791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BACKBONE = 'resnet34'\npreprocess_input = sm.get_preprocessing(BACKBONE)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.562858Z","iopub.status.idle":"2021-11-28T06:02:30.564373Z","shell.execute_reply.started":"2021-11-28T06:02:30.564122Z","shell.execute_reply":"2021-11-28T06:02:30.564148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = preprocess_input(train_ds)\nvalid_ds = preprocess_input(valid_ds)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.565760Z","iopub.status.idle":"2021-11-28T06:02:30.566415Z","shell.execute_reply.started":"2021-11-28T06:02:30.566180Z","shell.execute_reply":"2021-11-28T06:02:30.566205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from segmentation_models import Unet\nfrom segmentation_models.utils import set_trainable\n\n'''\nbase_model = Unet('efficientnetb3',input_shape=(256, 256, 3), classes=3, activation='sigmoid',encoder_weights='imagenet',encoder_freeze = True)\ninp = Input(shape=(256, 256, 3))\nl1 = base_model(inp)\nout = Conv2D(1, (1, 1))(l1) # map N channels data to 3 channels\nmodel = Model(inp, out, name=base_model.name)\nmodel.compile(optimizer='adam', loss=bce_dice_loss,metrics=[dice_coef,iou_coef,'accuracy']) #bce_dice_loss binary_crossentropy\nmodel.summary()\n'''","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.567695Z","iopub.status.idle":"2021-11-28T06:02:30.568348Z","shell.execute_reply.started":"2021-11-28T06:02:30.568107Z","shell.execute_reply":"2021-11-28T06:02:30.568132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# try out the model to check what it predicts before training\n'''\ndef create_mask(pred_mask):\n    pred_mask = tf.where(pred_mask > 0.5,1,0)\n    return pred_mask\n\n\ndef show_predictions(dataset=None, num=1):\n    if dataset:\n        for image, mask in dataset.take(num):\n            pred_mask = model.predict(image)\n            pred_mask = pred_mask.reshape((256,256,1))\n            display([image[0], mask[0], pred_mask])\n    else:\n        display([sample_image, sample_mask,\n                 create_mask(model.predict(sample_image[tf.newaxis, ...])[0])])\n\n        \nshow_predictions(train_ds)\n'''","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.569612Z","iopub.status.idle":"2021-11-28T06:02:30.570265Z","shell.execute_reply.started":"2021-11-28T06:02:30.570013Z","shell.execute_reply":"2021-11-28T06:02:30.570051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nfrom keras.callbacks import Callback, ModelCheckpoint\ncheckpoint = ModelCheckpoint(\n    'model1.h5', \n    monitor='val_loss', \n    verbose=0, \n    save_best_only=True, \n    save_weights_only=False,\n    mode='auto'\n)\n\nhistory = model.fit(\n    train_ds,\n    validation_data=valid_ds,\n    steps_per_epoch=60,\n    validation_steps=10,\n    callbacks=[checkpoint],\n    use_multiprocessing=False,\n    workers=4,\n    epochs=10,\n    verbose = 1\n)\nhist_df = pd.DataFrame(history.history)\nhist_df.to_csv('history.csv')\n# PLOT TRAINING\nplt.figure(figsize=(15,5))\nplt.plot(range(history.epoch[-1]+1),history.history['val_iou_coef'],label='Val_iou_coef')\nplt.plot(range(history.epoch[-1]+1),history.history['iou_coef'],label='Trn_iou_coef')\nplt.title('IOU'); plt.xlabel('Epoch'); plt.ylabel('iou_coef');plt.legend(); \nplt.show()\n\n# PLOT TRAINING\nplt.figure(figsize=(15,5))\nplt.plot(range(history.epoch[-1]+1),history.history['val_iou_coef'],label='Val_iou_coef')\nplt.plot(range(history.epoch[-1]+1),history.history['iou_coef'],label='Trn_iou_coef')\nplt.title('IOU'); plt.xlabel('Epoch'); plt.ylabel('iou_coef');plt.legend(); \nplt.show()\n\nmodel.save('./model.h5')\n'''","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.571569Z","iopub.status.idle":"2021-11-28T06:02:30.572216Z","shell.execute_reply.started":"2021-11-28T06:02:30.571966Z","shell.execute_reply":"2021-11-28T06:02:30.571990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loaded_model = load_model('../input/k/pasanjayaweera/cell-segmentation/model.h5', compile = False)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.573471Z","iopub.status.idle":"2021-11-28T06:02:30.574134Z","shell.execute_reply.started":"2021-11-28T06:02:30.573881Z","shell.execute_reply":"2021-11-28T06:02:30.573904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model.save('./model.h5')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.575378Z","iopub.status.idle":"2021-11-28T06:02:30.576031Z","shell.execute_reply.started":"2021-11-28T06:02:30.575793Z","shell.execute_reply":"2021-11-28T06:02:30.575817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_img = cv2.imread('../input/sartoriuscellinstancesegmentationmaskpng/TrainImage2x2/0030fd0e6378_3.png')\ntrue_mask = cv2.imread('../input/sartoriuscellinstancesegmentationmaskpng/TrainMask2x2/0030fd0e6378_3_mask.png')\ntest_img = cv2.resize(test_img,(256,256))\ntrue_mask = cv2.resize(true_mask,(256,256))\ntest_img1 = np.expand_dims(test_img,axis = 0)\npred_mask = loaded_model.predict(test_img1)\npred_mask = pred_mask.reshape((256,256,1))\ndisplay([test_img, true_mask, pred_mask])","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.577306Z","iopub.status.idle":"2021-11-28T06:02:30.577951Z","shell.execute_reply.started":"2021-11-28T06:02:30.577714Z","shell.execute_reply":"2021-11-28T06:02:30.577738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Prediction and submission","metadata":{}},{"cell_type":"code","source":"test_path = '../input/sartorius-cell-instance-segmentation/test/'\ntest_ids = [  os.path.join(test_path, each)  for each in os.listdir(test_path) if each.endswith('.png')]\ndef test_generator(image_ids):\n    for image_id in image_ids:\n        image = cv2.imread(image_id) \n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)        \n        image = cv2.resize(image, (RESIZE_HEIGHT, RESIZE_WIDTH))\n        image = image.astype(np.float32)\n        yield image\n        \n# test dataset from test data generator \ntest_ds = tf.data.Dataset.from_generator(\n    lambda : test_generator(test_ids), \n    output_types=(tf.float32),\n    output_shapes=((RESIZE_HEIGHT, RESIZE_WIDTH, 3)) )\n# test image ids and predictions\ntest_predictions = make_predictions(dataset=test_ds, num=len(test_ids), keras_model=loaded_model)\n","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.579214Z","iopub.status.idle":"2021-11-28T06:02:30.579860Z","shell.execute_reply.started":"2021-11-28T06:02:30.579622Z","shell.execute_reply":"2021-11-28T06:02:30.579647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# encode predections in the RL format\ntest_predictions = [rle_encode(mask) for mask in test_predictions] \n#print(test_predictions)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.581107Z","iopub.status.idle":"2021-11-28T06:02:30.581743Z","shell.execute_reply.started":"2021-11-28T06:02:30.581506Z","shell.execute_reply":"2021-11-28T06:02:30.581530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# transform full image paths to ids \nfrom pathlib import Path\ntest_ids = [Path(ID).stem for ID in test_ids]","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.582967Z","iopub.status.idle":"2021-11-28T06:02:30.583619Z","shell.execute_reply.started":"2021-11-28T06:02:30.583371Z","shell.execute_reply":"2021-11-28T06:02:30.583395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generate submission data frame \nsubmisssion = pd.DataFrame.from_dict({'id': test_ids, 'predicted': test_predictions} )\nsubmisssion = submisssion.sort_values( ['id'], ascending=True )\nprint(submisssion.head(), 'n')\ncsv_output = os.path.join('./', 'submission.csv') \nsubmisssion.to_csv(csv_output, index=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T06:02:30.584874Z","iopub.status.idle":"2021-11-28T06:02:30.585534Z","shell.execute_reply.started":"2021-11-28T06:02:30.585287Z","shell.execute_reply":"2021-11-28T06:02:30.585311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}