{"cells":[{"metadata":{"_cell_guid":"","_uuid":"","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Import the dataset\nimport pandas as pd\nsub = pd.read_csv(\"../input/understanding_cloud_organization/sample_submission.csv\")\ntrain = pd.read_csv(\"../input/understanding_cloud_organization/train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Run-length decoder\ndef rle_decode(mask_rle: str = '', shape: tuple = (1400, 2100)):\n    '''\n    Decode rle encoded mask.\n    \n    :param mask_rle: run-length as string formatted (start length)\n    :param shape: (height, width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\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.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape, order='F')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Initial inspection of the dataset:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Understanding the dataset\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom matplotlib import patches\n# read the csv file using read_csv function of pandas\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Dataset size:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"import os\npath = '../input/understanding_cloud_organization'\nos.listdir(path)\nn_train = len(os.listdir(f'{path}/train_images'))\nn_test = len(os.listdir(f'{path}/test_images'))\nprint(f'There are {n_train} images in train dataset')\nprint(f'There are {n_test} images in test dataset')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# How many classes:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"classes = pd.DataFrame(train['Image_Label'].str.split('_',1).tolist(),\n                                   columns = ['img_name','class'])\nprint('There are ' + str(classes['class'].nunique()) + ' classes')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data distribution:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Number of images per class\nfor class_ in classes['class'].unique():\n    nr_imgs = sum([off_class for off_class, no_data in zip(train['Image_Label'].str.endswith(str(class_)), train['EncodedPixels'].isna()) if off_class == True and no_data == False])\n    print(\"Number of images of class \" + str(class_) + \": \" + str(nr_imgs))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Images of each class:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"import numpy as np\n# Images known to contain the classes\nfish_imgs = ['0011165', '002be4f', '0031ae9', '00dec6a']\nflower_imgs = ['0011165', '002be4f', '0031ae9', '00dec6a']\ngravel_imgs = ['00a0954', '00b81e1', '00cedfa', '00dec6a']\nsugar_imgs = ['00a0954', '00b81e1', '00cedfa', '00dec6a']\n\ncolumns = 4\nrows = 4\nfig, ax = plt.subplots(rows, columns, figsize=(18, 13))\nax[0, 0].set_title('Fish', fontsize=20)\nax[0, 1].set_title('Flower', fontsize=20)\nax[0, 2].set_title('Gravel', fontsize=20)\nax[0, 3].set_title('Sugar', fontsize=20)\nfor i in range(len(fish_imgs)):\n    fish_img = plt.imread(f\"{path}/train_images/{fish_imgs[i]}.jpg\")\n    ax[i, 0].imshow(fish_img)\n    image_label = f'{fish_imgs[i]}.jpg_Fish'\n    mask_rle = train.loc[train['Image_Label'] == image_label, 'EncodedPixels'].values[0]\n    mask = rle_decode(mask_rle)\n    ax[i, 0].imshow(mask, alpha=0.5, cmap='gray')\n    \n    flower_img = plt.imread(f\"{path}/train_images/{flower_imgs[i]}.jpg\")\n    ax[i, 1].imshow(flower_img)\n    image_label = f'{flower_imgs[i]}.jpg_Flower'\n    mask_rle = train.loc[train['Image_Label'] == image_label, 'EncodedPixels'].values[0]\n    mask = rle_decode(mask_rle)\n    ax[i, 1].imshow(mask, alpha=0.5, cmap='gray')\n    \n    gravel_img = plt.imread(f\"{path}/train_images/{gravel_imgs[i]}.jpg\")\n    ax[i, 2].imshow(gravel_img)\n    image_label = f'{gravel_imgs[i]}.jpg_Gravel'\n    mask_rle = train.loc[train['Image_Label'] == image_label, 'EncodedPixels'].values[0]\n    mask = rle_decode(mask_rle)\n    ax[i, 2].imshow(mask, alpha=0.5, cmap='gray')\n    \n    sugar_img = plt.imread(f\"{path}/train_images/{sugar_imgs[i]}.jpg\")\n    ax[i, 3].imshow(sugar_img)\n    image_label = f'{sugar_imgs[i]}.jpg_Sugar'\n    mask_rle = train.loc[train['Image_Label'] == image_label, 'EncodedPixels'].values[0]\n    mask = rle_decode(mask_rle)\n    ax[i, 3].imshow(mask, alpha=0.5, cmap='gray')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Based on \"Satellite Clouds: U-Net with ResNet Encoder\" by xhlulu"},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"!pip install segmentation-models --quiet\n!pip install tensorflow\nimport tensorflow as tf\nprint(tf.__version__)\nimport os\nimport json\n\nimport albumentations as albu\nimport cv2\nimport keras\nfrom keras import backend as K\nfrom keras.models import Model\nfrom keras.layers import Input\nfrom keras.layers import Cropping2D\nfrom keras.layers import BatchNormalization\nfrom keras.layers import Activation\nfrom keras.layers import Dropout\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.optimizers import Adam, Nadam\nfrom keras.callbacks import Callback, ModelCheckpoint\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nfrom sklearn.model_selection import train_test_split\nimport segmentation_models as sm","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Pre-process the dataset:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Read training data\ntrain_df = pd.read_csv('../input/understanding_cloud_organization/train.csv')\n# Split Image_Label into Image(ImageId) and Label(ClassId)\ntrain_df['ImageId'] = train_df['Image_Label'].apply(lambda x: x.split('_')[0])\ntrain_df['ClassId'] = train_df['Image_Label'].apply(lambda x: x.split('_')[1])\n# Determine if an Image_Label contains a mask or not\ntrain_df['hasMask'] = ~ train_df['EncodedPixels'].isna()\n\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"# Determine number of masks pr. image\nmask_count_df = train_df.groupby('ImageId').agg(np.sum).reset_index()\nmask_count_df.sort_values('hasMask', ascending=False, inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"sub_df = pd.read_csv('../input/understanding_cloud_organization/sample_submission.csv')\nsub_df['ImageId'] = sub_df['Image_Label'].apply(lambda x: x.split('_')[0])\ntest_imgs = pd.DataFrame(sub_df['ImageId'].unique(), columns=['ImageId'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"train_imgs = pd.DataFrame(train_df['ImageId'].unique(), columns=['ImageId'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Utility Functions:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Utility functions\ndef np_resize(img, input_shape):\n    \"\"\"\n    Reshape a numpy array, which is input_shape=(height, width), \n    as opposed to input_shape=(width, height) for cv2\n    \"\"\"\n    height, width = input_shape\n    return cv2.resize(img, (width, height))\n    \ndef mask2rle(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels= img.T.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 rle2mask(rle, input_shape):\n    width, height = input_shape[:2]\n    \n    mask= np.zeros( width*height ).astype(np.uint8)\n    \n    array = np.asarray([int(x) for x in rle.split()])\n    starts = array[0::2]\n    lengths = array[1::2]\n\n    current_position = 0\n    for index, start in enumerate(starts):\n        mask[int(start):int(start+lengths[index])] = 1\n        current_position += lengths[index]\n        \n    return mask.reshape(height, width).T\n\ndef build_masks(rles, input_shape, reshape=None):\n    depth = len(rles)\n    if reshape is None:\n        masks = np.zeros((*input_shape, depth))\n    else:\n        masks = np.zeros((*reshape, depth))\n    \n    for i, rle in enumerate(rles):\n        if type(rle) is str:\n            if reshape is None:\n                masks[:, :, i] = rle2mask(rle, input_shape)\n            else:\n                mask = rle2mask(rle, input_shape)\n                reshaped_mask = np_resize(mask, reshape)\n                masks[:, :, i] = reshaped_mask\n    \n    return masks\n\ndef build_rles(masks, reshape=None):\n    width, height, depth = masks.shape\n    \n    rles = []\n    \n    for i in range(depth):\n        mask = masks[:, :, i]\n        \n        if reshape:\n            mask = mask.astype(np.float32)\n            mask = np_resize(mask, reshape).astype(np.int64)\n        \n        rle = mask2rle(mask)\n        rles.append(rle)\n        \n    return rles","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loss Function:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def 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 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(y_true, y_pred) + dice_loss(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Generator:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"class DataGenerator(keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, list_IDs, df, target_df=None, mode='fit',\n                 base_path=\"../input/understanding_cloud_organization/train_images\",\n                 batch_size=32, dim=(1400, 2100), n_channels=3, reshape=None,\n                 augment=False, n_classes=4, random_state=2019, shuffle=True, normalize=False, mean=(0.25664523, 0.27471591, 0.32296003), std=(0.24326022, 0.23920952, 0.23920952)):\n#(array([0.32296003]), array([0.27471591]), array([0.25664523]))\n#(array([0.23920952]), array([0.23920952]), array([0.24326022]))\n        self.dim = dim\n        self.batch_size = batch_size\n        self.df = df\n        self.mode = mode\n        self.base_path = base_path\n        self.target_df = target_df\n        self.list_IDs = list_IDs\n        self.reshape = reshape\n        self.n_channels = n_channels\n        self.augment = augment\n        self.n_classes = n_classes\n        self.shuffle = shuffle\n        self.random_state = random_state\n        self.normalize = normalize\n        self.mean = mean\n        self.std = std\n        \n        self.on_epoch_end()\n        np.random.seed(self.random_state)\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        return int(np.floor(len(self.list_IDs) / self.batch_size))\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        # Generate indexes of the batch\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n\n        # Find list of IDs\n        list_IDs_batch = [self.list_IDs[k] for k in indexes]\n        \n        X = self.__generate_X(list_IDs_batch)\n        \n        if self.mode == 'fit':\n            y = self.__generate_y(list_IDs_batch)\n            \n            if self.augment:\n                X, y = self.__augment_batch(X, y)\n                \n            if self.normalize:\n                X, y = self.__normalize_batch(X, y)\n            \n            return X, y\n        \n        elif self.mode == 'predict':\n            #X = self.__normalize_batch_predict(X)\n            return X\n\n        else:\n            raise AttributeError('The mode parameter should be set to \"fit\" or \"predict\".')\n            \n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange(len(self.list_IDs))\n        if self.shuffle == True:\n            np.random.seed(self.random_state)\n            np.random.shuffle(self.indexes)\n    \n    def __generate_X(self, list_IDs_batch):\n        'Generates data containing batch_size samples'\n        # Initialization\n        if self.reshape is None:\n            X = np.empty((self.batch_size, *self.dim, self.n_channels))\n        else:\n            X = np.empty((self.batch_size, *self.reshape, self.n_channels))\n        \n        # Generate data\n        for i, ID in enumerate(list_IDs_batch):\n            im_name = self.df['ImageId'].iloc[ID]\n            img_path = f\"{self.base_path}/{im_name}\"\n            img = self.__load_rgb(img_path)\n            \n            if self.reshape is not None:\n                img = np_resize(img, self.reshape)\n            \n            # Store samples\n            X[i,] = img\n\n        return X\n    \n    def __generate_y(self, list_IDs_batch):\n        if self.reshape is None:\n            y = np.empty((self.batch_size, *self.dim, self.n_classes), dtype=int)\n        else:\n            y = np.empty((self.batch_size, *self.reshape, self.n_classes), dtype=int)\n        \n        for i, ID in enumerate(list_IDs_batch):\n            im_name = self.df['ImageId'].iloc[ID]\n            image_df = self.target_df[self.target_df['ImageId'] == im_name]\n            \n            rles = image_df['EncodedPixels'].values\n            \n            if self.reshape is not None:\n                masks = build_masks(rles, input_shape=self.dim, reshape=self.reshape)\n            else:\n                masks = build_masks(rles, input_shape=self.dim)\n            \n            y[i, ] = masks\n\n        return y\n\n    def __load_grayscale(self, img_path):\n        img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)\n        img = img.astype(np.float32) / 255.\n        img = np.expand_dims(img, axis=-1)\n\n        return img\n    \n    def __load_rgb(self, img_path):\n        img = cv2.imread(img_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = img.astype(np.float32) / 255.\n\n        return img\n    \n    def __random_transform(self, img, masks):\n        composition = albu.Compose([\n            albu.HorizontalFlip(),\n            albu.VerticalFlip(),\n            albu.ShiftScaleRotate(rotate_limit=45, shift_limit=0.15, scale_limit=0.15),\n            #albu.RandomSizedCrop(min_max_height=(192,288), height=320, width=480, w2h_ratio=0.666, interpolation=1, always_apply=False, p=0.5),\n            #albu.CoarseDropout(max_holes=4, max_height=32, max_width=48, min_holes=2, min_height=16, min_width=24, fill_value=0, always_apply=False, p=0.5),\n            #albu.Normalize(mean=self.mean, std=self.std, max_pixel_value=255.0, always_apply=False, p=1.0)\n        ])\n        \n        composed = composition(image=img, mask=masks)\n        aug_img = composed['image']\n        aug_masks = composed['mask']\n        \n        return aug_img, aug_masks\n    \n    def __normalize(self, img, masks):\n        composition = albu.Compose([\n            albu.Normalize(mean=self.mean, std=self.std, max_pixel_value=255.0, always_apply=False, p=1.0)\n        ])\n        \n        composed = composition(image=img, mask=masks)\n        aug_img = composed['image']\n        aug_masks = composed['mask']\n        \n        return aug_img, aug_masks\n    \n    def __normalize_predict(self, img):\n        composition = albu.Compose([\n            albu.Normalize(mean=self.mean, std=self.std, max_pixel_value=255.0, always_apply=False, p=1.0)\n        ])\n        \n        composed = composition(image=img)\n        aug_img = composed['image']\n        \n        return aug_img\n    \n    def __augment_batch(self, img_batch, masks_batch):\n        for i in range(img_batch.shape[0]):\n            img_batch[i, ], masks_batch[i, ] = self.__random_transform(\n                img_batch[i, ], masks_batch[i, ])\n        \n        return img_batch, masks_batch\n    \n    def __normalize_batch(self, img_batch, masks_batch):\n        for i in range(img_batch.shape[0]):\n            img_batch[i, ], masks_batch[i, ] = self.__normalize(\n                img_batch[i, ], masks_batch[i, ])\n\n        return img_batch, masks_batch\n    \n    def __normalize_batch_predict(self, img_batch):\n        for i in range(img_batch.shape[0]):\n            img_batch[i, ] = self.__normalize_predict(\n                img_batch[i, ])\n\n        return img_batch\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Vanilla U-Net model:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def vanilla_unet(input_shape):\n    \"\"\"\n    Unet vanilla\n    \"\"\"\n    inputs = Input(input_shape)\n\n    c1 = Conv2D(8, (3, 3), activation='elu', padding='same') (inputs)\n    c1 = Conv2D(8, (3, 3), activation='elu', padding='same') (c1)\n    p1 = MaxPooling2D((2, 2), padding='same') (c1)\n\n    c2 = Conv2D(16, (3, 3), activation='elu', padding='same') (p1)\n    c2 = Conv2D(16, (3, 3), activation='elu', padding='same') (c2)\n    p2 = MaxPooling2D((2, 2), padding='same') (c2)\n\n    c3 = Conv2D(32, (3, 3), activation='elu', padding='same') (p2)\n    c3 = Conv2D(32, (3, 3), activation='elu', padding='same') (c3)\n    p3 = MaxPooling2D((2, 2), padding='same') (c3)\n\n    c4 = Conv2D(64, (3, 3), activation='elu', padding='same') (p3)\n    c4 = Conv2D(64, (3, 3), activation='elu', padding='same') (c4)\n    p4 = MaxPooling2D((2, 2), padding='same') (c4)\n\n    c5 = Conv2D(64, (3, 3), activation='elu', padding='same') (p4)\n    c5 = Conv2D(64, (3, 3), activation='elu', padding='same') (c5)\n    p5 = MaxPooling2D((2, 2), padding='same') (c5)\n\n    c55 = Conv2D(128, (3, 3), activation='elu', padding='same') (p5)\n    c55 = Conv2D(128, (3, 3), activation='elu', padding='same') (c55)\n\n    u6 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (c55)\n    u6 = concatenate([u6, c5])\n    c6 = Conv2D(64, (3, 3), activation='elu', padding='same') (u6)\n    c6 = Conv2D(64, (3, 3), activation='elu', padding='same') (c6)\n\n    u71 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c6)\n    u71 = concatenate([u71, c4])\n    c71 = Conv2D(32, (3, 3), activation='elu', padding='same') (u71)\n    c61 = Conv2D(32, (3, 3), activation='elu', padding='same') (c71)\n\n    u7 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c61)\n    u7 = concatenate([u7, c3])\n    c7 = Conv2D(32, (3, 3), activation='elu', padding='same') (u7)\n    c7 = Conv2D(32, (3, 3), activation='elu', padding='same') (c7)\n\n    u8 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (c7)\n    u8 = concatenate([u8, c2])\n    c8 = Conv2D(16, (3, 3), activation='elu', padding='same') (u8)\n    c8 = Conv2D(16, (3, 3), activation='elu', padding='same') (c8)\n\n    u9 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (c8)\n    u9 = concatenate([u9, c1], axis=3)\n    c9 = Conv2D(8, (3, 3), activation='elu', padding='same') (u9)\n    c9 = Conv2D(8, (3, 3), activation='elu', padding='same') (c9)\n\n    outputs = Conv2D(4, (1, 1), activation='sigmoid') (c9)\n\n    model = Model(inputs=[inputs], outputs=[outputs])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Vanilla U-Net model w/ batch normalization:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def unet_bn(input_shape):\n    \"\"\"\n    Unet with batch normalization\n    \"\"\"\n    inputs = Input(input_shape)\n\n    c1 = Conv2D(8, (3, 3), activation=None, padding='same') (inputs)\n    c1 = Conv2D(8, (3, 3), activation=None, padding='same') (c1)\n    bn1 = BatchNormalization()(c1)\n    a1 = Activation('elu')(bn1)\n    p1 = MaxPooling2D((2, 2), padding='same') (a1)\n\n    c2 = Conv2D(16, (3, 3), activation=None, padding='same') (p1)\n    c2 = Conv2D(16, (3, 3), activation=None, padding='same') (c2)\n    bn2 = BatchNormalization()(c2)\n    a2 = Activation('elu')(bn2)\n    p2 = MaxPooling2D((2, 2), padding='same') (a2)\n\n    c3 = Conv2D(32, (3, 3), activation=None, padding='same') (p2)\n    c3 = Conv2D(32, (3, 3), activation=None, padding='same') (c3)\n    bn3 = BatchNormalization()(c3)\n    a3 = Activation('elu')(bn3)\n    p3 = MaxPooling2D((2, 2), padding='same') (a3)\n\n    c4 = Conv2D(64, (3, 3), activation=None, padding='same') (p3)\n    c4 = Conv2D(64, (3, 3), activation=None, padding='same') (c4)\n    bn4 = BatchNormalization()(c4)\n    a4 = Activation('elu')(bn4)\n    p4 = MaxPooling2D((2, 2), padding='same') (a4)\n\n    c5 = Conv2D(64, (3, 3), activation=None, padding='same') (p4)\n    c5 = Conv2D(64, (3, 3), activation=None, padding='same') (c5)\n    bn5 = BatchNormalization()(c5)\n    a5 = Activation('elu')(bn5)\n    p5 = MaxPooling2D((2, 2), padding='same') (a5)\n\n    c55 = Conv2D(128, (3, 3), activation=None, padding='same') (p5)\n    c55 = Conv2D(128, (3, 3), activation=None, padding='same') (c55)\n    bn55 = BatchNormalization()(c55)\n    a55 = Activation('elu')(bn55)\n\n    u6 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (a55)\n    u6 = concatenate([u6, a5])\n    c6 = Conv2D(64, (3, 3), activation=None, padding='same') (u6)\n    c6 = Conv2D(64, (3, 3), activation=None, padding='same') (c6)\n    bn6 = BatchNormalization()(c6)\n    a6 = Activation('elu')(bn6)\n\n    u71 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (a6)\n    u71 = concatenate([u71, a4])\n    c71 = Conv2D(32, (3, 3), activation=None, padding='same') (u71)\n    c61 = Conv2D(32, (3, 3), activation=None, padding='same') (c71)\n    bn61 = BatchNormalization()(c61)\n    a61 = Activation('elu')(bn61)\n\n    u7 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (a61)\n    u7 = concatenate([u7, a3])\n    c7 = Conv2D(32, (3, 3), activation=None, padding='same') (u7)\n    c7 = Conv2D(32, (3, 3), activation=None, padding='same') (c7)\n    bn7 = BatchNormalization()(c7)\n    a7 = Activation('elu')(bn7)\n\n    u8 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (a7)\n    u8 = concatenate([u8, a2])\n    c8 = Conv2D(16, (3, 3), activation=None, padding='same') (u8)\n    c8 = Conv2D(16, (3, 3), activation=None, padding='same') (c8)\n    bn8 = BatchNormalization()(c8)\n    a8 = Activation('elu')(bn8)\n    \n    u9 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (a8)\n    u9 = concatenate([u9, a1], axis=3)\n    c9 = Conv2D(8, (3, 3), activation=None, padding='same') (u9)\n    c9 = Conv2D(8, (3, 3), activation=None, padding='same') (c9)\n    bn9 = BatchNormalization()(c9)\n    a9 = Activation('elu')(bn9)\n\n    outputs = Conv2D(4, (1, 1), activation='sigmoid') (a9)\n\n    model = Model(inputs=[inputs], outputs=[outputs])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# U-Net model w/ batch normalization & dropout:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def vanilla_unet_bnd(input_shape):\n    \"\"\"\n    Unet with batch normalization and dropout\n    \"\"\"\n    inputs = Input(input_shape)\n\n    c1 = Conv2D(8, (3, 3), activation=None, padding='same') (inputs)\n    d1 = Dropout(0.5)(c1)\n    c1 = Conv2D(8, (3, 3), activation=None, padding='same') (d1)\n    d1 = Dropout(0.5)(c1)\n    bn1 = BatchNormalization()(d1)\n    a1 = Activation('elu')(bn1)\n    p1 = MaxPooling2D((2, 2), padding='same') (a1)\n\n    c2 = Conv2D(16, (3, 3), activation=None, padding='same') (p1)\n    d2 = Dropout(0.5)(c2)\n    c2 = Conv2D(16, (3, 3), activation=None, padding='same') (d2)\n    d2 = Dropout(0.5)(c2)\n    bn2 = BatchNormalization()(d2)\n    a2 = Activation('elu')(bn2)\n    p2 = MaxPooling2D((2, 2), padding='same') (a2)\n\n    c3 = Conv2D(32, (3, 3), activation=None, padding='same') (p2)\n    d3 = Dropout(0.5)(c3)\n    c3 = Conv2D(32, (3, 3), activation=None, padding='same') (d3)\n    d3 = Dropout(0.5)(c3)\n    bn3 = BatchNormalization()(d3)\n    a3 = Activation('elu')(bn3)\n    p3 = MaxPooling2D((2, 2), padding='same') (a3)\n\n    c4 = Conv2D(64, (3, 3), activation=None, padding='same') (p3)\n    d4 = Dropout(0.5)(c4)\n    c4 = Conv2D(64, (3, 3), activation=None, padding='same') (d4)\n    d4 = Dropout(0.5)(c4)\n    bn4 = BatchNormalization()(d4)\n    a4 = Activation('elu')(bn4)\n    p4 = MaxPooling2D((2, 2), padding='same') (a4)\n\n    c5 = Conv2D(64, (3, 3), activation=None, padding='same') (p4)\n    d5 = Dropout(0.5)(c5)\n    c5 = Conv2D(64, (3, 3), activation=None, padding='same') (d5)\n    d5 = Dropout(0.5)(c5)\n    bn5 = BatchNormalization()(d5)\n    a5 = Activation('elu')(bn5)\n    p5 = MaxPooling2D((2, 2), padding='same') (a5)\n\n    c55 = Conv2D(128, (3, 3), activation=None, padding='same') (p5)\n    d55 = Dropout(0.5)(c55)\n    c55 = Conv2D(128, (3, 3), activation=None, padding='same') (d55)\n    d55 = Dropout(0.5)(c55)\n    bn55 = BatchNormalization()(d55)\n    a55 = Activation('elu')(bn55)\n\n    u6 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (a55)\n    u6 = concatenate([u6, a5])\n    c6 = Conv2D(64, (3, 3), activation=None, padding='same') (u6)\n    d6 = Dropout(0.5)(c6)\n    c6 = Conv2D(64, (3, 3), activation=None, padding='same') (d6)\n    d6 = Dropout(0.5)(c6)\n    bn6 = BatchNormalization()(d6)\n    a6 = Activation('elu')(bn6)\n\n    u71 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (a6)\n    u71 = concatenate([u71, a4])\n    c71 = Conv2D(32, (3, 3), activation=None, padding='same') (u71)\n    d71 = Dropout(0.5)(c71)\n    c61 = Conv2D(32, (3, 3), activation=None, padding='same') (d71)\n    d61 = Dropout(0.5)(c61)\n    bn61 = BatchNormalization()(d61)\n    a61 = Activation('elu')(bn61)\n\n    u7 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (a61)\n    u7 = concatenate([u7, a3])\n    c7 = Conv2D(32, (3, 3), activation=None, padding='same') (u7)\n    d7 = Dropout(0.5)(c7)\n    c7 = Conv2D(32, (3, 3), activation=None, padding='same') (d7)\n    d7 = Dropout(0.5)(c7)\n    bn7 = BatchNormalization()(d7)\n    a7 = Activation('elu')(bn7)\n\n    u8 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (a7)\n    u8 = concatenate([u8, a2])\n    c8 = Conv2D(16, (3, 3), activation=None, padding='same') (u8)\n    d8 = Dropout(0.5)(c8)\n    c8 = Conv2D(16, (3, 3), activation=None, padding='same') (d8)\n    d8 = Dropout(0.5)(c8)\n    bn8 = BatchNormalization()(d8)\n    a8 = Activation('elu')(bn8)\n    \n    u9 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (a8)\n    u9 = concatenate([u9, a1], axis=3)\n    c9 = Conv2D(8, (3, 3), activation=None, padding='same') (u9)\n    d9 = Dropout(0.5)(c9)\n    c9 = Conv2D(8, (3, 3), activation=None, padding='same') (d9)\n    d9 = Dropout(0.5)(c9)\n    bn9 = BatchNormalization()(d9)\n    a9 = Activation('elu')(bn9)\n\n    outputs = Conv2D(4, (1, 1), activation='sigmoid') (a9)\n\n    model = Model(inputs=[inputs], outputs=[outputs])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# U-Net model w/ batch normalization & dropout revised: "},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def unet_bnd_r(input_shape):\n    \"\"\"\n    Unet with batch normalization and dropout (revised)\n    \"\"\"\n    inputs = Input(input_shape)\n\n    c1 = Conv2D(8, (3, 3), activation=None, padding='same') (inputs)\n    c1 = Conv2D(8, (3, 3), activation=None, padding='same') (c1)\n    bn1 = BatchNormalization()(c1)\n    a1 = Activation('elu')(bn1)\n    p1 = MaxPooling2D((2, 2), padding='same') (a1)\n    d1 = Dropout(0.25)(p1)\n\n    c2 = Conv2D(16, (3, 3), activation=None, padding='same') (d1)\n    c2 = Conv2D(16, (3, 3), activation=None, padding='same') (c2)\n    bn2 = BatchNormalization()(c2)\n    a2 = Activation('elu')(bn2)\n    p2 = MaxPooling2D((2, 2), padding='same') (a2)\n    d2 = Dropout(0.25)(p2)\n\n    c3 = Conv2D(32, (3, 3), activation=None, padding='same') (d2)\n    c3 = Conv2D(32, (3, 3), activation=None, padding='same') (c3)\n    bn3 = BatchNormalization()(c3)\n    a3 = Activation('elu')(bn3)\n    p3 = MaxPooling2D((2, 2), padding='same') (a3)\n    d3 = Dropout(0.25)(p3)\n\n    c4 = Conv2D(64, (3, 3), activation=None, padding='same') (d3)\n    c4 = Conv2D(64, (3, 3), activation=None, padding='same') (c4)\n    bn4 = BatchNormalization()(c4)\n    a4 = Activation('elu')(bn4)\n    p4 = MaxPooling2D((2, 2), padding='same') (a4)\n    d4 = Dropout(0.25)(p4)\n\n    c5 = Conv2D(64, (3, 3), activation=None, padding='same') (d4)\n    c5 = Conv2D(64, (3, 3), activation=None, padding='same') (c5)\n    bn5 = BatchNormalization()(c5)\n    a5 = Activation('elu')(bn5)\n    p5 = MaxPooling2D((2, 2), padding='same') (a5)\n    d5 = Dropout(0.25)(p5)\n\n    c55 = Conv2D(128, (3, 3), activation=None, padding='same') (d5)\n    c55 = Conv2D(128, (3, 3), activation=None, padding='same') (c55)\n    bn55 = BatchNormalization()(c55)\n    a55 = Activation('elu')(bn55)\n    d55 = Dropout(0.25)(a55)\n\n    u6 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (d55)\n    u6 = concatenate([u6, a5])\n    d6 = Dropout(0.25)(u6)\n    c6 = Conv2D(64, (3, 3), activation=None, padding='same') (d6)\n    c6 = Conv2D(64, (3, 3), activation=None, padding='same') (c6)\n    bn6 = BatchNormalization()(c6)\n    a6 = Activation('elu')(bn6)\n\n    u71 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (a6)\n    u71 = concatenate([u71, a4])\n    d71 = Dropout(0.25)(u71)\n    c71 = Conv2D(32, (3, 3), activation=None, padding='same') (d71)\n    c61 = Conv2D(32, (3, 3), activation=None, padding='same') (c71)\n    bn61 = BatchNormalization()(c61)\n    a61 = Activation('elu')(bn61)\n\n    u7 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (a61)\n    u7 = concatenate([u7, a3])\n    d7 = Dropout(0.25)(u7)\n    c7 = Conv2D(32, (3, 3), activation=None, padding='same') (d7)\n    c7 = Conv2D(32, (3, 3), activation=None, padding='same') (c7)\n    bn7 = BatchNormalization()(c7)\n    a7 = Activation('elu')(bn7)\n\n    u8 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (a7)\n    u8 = concatenate([u8, a2])\n    d8 = Dropout(0.25)(u8)\n    c8 = Conv2D(16, (3, 3), activation=None, padding='same') (d8)\n    c8 = Conv2D(16, (3, 3), activation=None, padding='same') (c8)\n    bn8 = BatchNormalization()(c8)\n    a8 = Activation('elu')(bn8)\n    \n    u9 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (a8)\n    u9 = concatenate([u9, a1], axis=3)\n    d9 = Dropout(0.25)(u9)\n    c9 = Conv2D(8, (3, 3), activation=None, padding='same') (d9)\n    c9 = Conv2D(8, (3, 3), activation=None, padding='same') (c9)\n    bn9 = BatchNormalization()(c9)\n    a9 = Activation('elu')(bn9)\n\n    outputs = Conv2D(4, (1, 1), activation='sigmoid') (a9)\n\n    model = Model(inputs=[inputs], outputs=[outputs])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# U-Net model w/ batch normalization & ReLU:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def unet_bn_relu(input_shape):\n    \"\"\"\n    Unet with batch normalization and ReLu\n    \"\"\"\n    inputs = Input(input_shape)\n\n    c1 = Conv2D(8, (3, 3), activation='relu', padding='same') (inputs)\n    c1 = Conv2D(8, (3, 3), activation='relu', padding='same') (c1)\n    bn1 = BatchNormalization()(c1)\n    p1 = MaxPooling2D((2, 2), padding='same') (bn1)\n\n    c2 = Conv2D(16, (3, 3), activation='relu', padding='same') (p1)\n    c2 = Conv2D(16, (3, 3), activation='relu', padding='same') (c2)\n    bn2 = BatchNormalization()(c2)\n    p2 = MaxPooling2D((2, 2), padding='same') (bn2)\n\n    c3 = Conv2D(32, (3, 3), activation='relu', padding='same') (p2)\n    c3 = Conv2D(32, (3, 3), activation='relu', padding='same') (c3)\n    bn3 = BatchNormalization()(c3)\n    p3 = MaxPooling2D((2, 2), padding='same') (bn3)\n\n    c4 = Conv2D(64, (3, 3), activation='relu', padding='same') (p3)\n    c4 = Conv2D(64, (3, 3), activation='relu', padding='same') (c4)\n    bn4 = BatchNormalization()(c4)\n    p4 = MaxPooling2D((2, 2), padding='same') (bn4)\n\n    c5 = Conv2D(64, (3, 3), activation='relu', padding='same') (p4)\n    c5 = Conv2D(64, (3, 3), activation='relu', padding='same') (c5)\n    bn5 = BatchNormalization()(c5)\n    p5 = MaxPooling2D((2, 2), padding='same') (bn5)\n\n    c55 = Conv2D(128, (3, 3), activation='relu', padding='same') (p5)\n    c55 = Conv2D(128, (3, 3), activation='relu', padding='same') (c55)\n    bn55 = BatchNormalization()(c55)\n\n    u6 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (bn55)\n    u6 = concatenate([u6, bn5])\n    c6 = Conv2D(64, (3, 3), activation='relu', padding='same') (u6)\n    c6 = Conv2D(64, (3, 3), activation='relu', padding='same') (c6)\n    bn6 = BatchNormalization()(c6)\n\n    u71 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (bn6)\n    u71 = concatenate([u71, bn4])\n    c71 = Conv2D(32, (3, 3), activation='relu', padding='same') (u71)\n    c61 = Conv2D(32, (3, 3), activation='relu', padding='same') (c71)\n    bn61 = BatchNormalization()(c61)\n\n    u7 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (bn61)\n    u7 = concatenate([u7, bn3])\n    c7 = Conv2D(32, (3, 3), activation='relu', padding='same') (u7)\n    c7 = Conv2D(32, (3, 3), activation='relu', padding='same') (c7)\n    bn7 = BatchNormalization()(c7)\n\n    u8 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (bn7)\n    u8 = concatenate([u8, bn2])\n    c8 = Conv2D(16, (3, 3), activation='relu', padding='same') (u8)\n    c8 = Conv2D(16, (3, 3), activation='relu', padding='same') (c8)\n    bn8 = BatchNormalization()(c8)\n    \n    u9 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (bn8)\n    u9 = concatenate([u9, bn1], axis=3)\n    c9 = Conv2D(8, (3, 3), activation='relu', padding='same') (u9)\n    c9 = Conv2D(8, (3, 3), activation='relu', padding='same') (c9)\n\n    outputs = Conv2D(4, (1, 1), activation='sigmoid') (c9)\n\n    model = Model(inputs=[inputs], outputs=[outputs])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# U-Net model w/ batch normalization & ReLU & 1-deeper:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def unet_bn_relu_deeper(input_shape):\n    \"\"\"\n    Unet with batch normalization and ReLu\n    \"\"\"\n    inputs = Input(input_shape)\n\n    c1 = Conv2D(8, (3, 3), activation='relu', padding='same') (inputs)\n    c1 = Conv2D(8, (3, 3), activation='relu', padding='same') (c1)\n    bn1 = BatchNormalization()(c1)\n    p1 = MaxPooling2D((2, 2), padding='same') (bn1)\n\n    c2 = Conv2D(16, (3, 3), activation='relu', padding='same') (p1)\n    c2 = Conv2D(16, (3, 3), activation='relu', padding='same') (c2)\n    bn2 = BatchNormalization()(c2)\n    p2 = MaxPooling2D((2, 2), padding='same') (bn2)\n\n    c3 = Conv2D(32, (3, 3), activation='relu', padding='same') (p2)\n    c3 = Conv2D(32, (3, 3), activation='relu', padding='same') (c3)\n    bn3 = BatchNormalization()(c3)\n    p3 = MaxPooling2D((2, 2), padding='same') (bn3)\n\n    c4 = Conv2D(64, (3, 3), activation='relu', padding='same') (p3)\n    c4 = Conv2D(64, (3, 3), activation='relu', padding='same') (c4)\n    bn4 = BatchNormalization()(c4)\n    p4 = MaxPooling2D((2, 2), padding='same') (bn4)\n\n    c5 = Conv2D(64, (3, 3), activation='relu', padding='same') (p4)\n    c5 = Conv2D(64, (3, 3), activation='relu', padding='same') (c5)\n    bn5 = BatchNormalization()(c5)\n    p5 = MaxPooling2D((2, 2), padding='same') (bn5)\n\n    c6 = Conv2D(128, (3, 3), activation='relu', padding='same') (p5)\n    c6 = Conv2D(128, (3, 3), activation='relu', padding='same') (c6)\n    bn6 = BatchNormalization()(c6)\n    p6 = MaxPooling2D((2, 2), padding='same') (bn6)\n    \n    c66 = Conv2D(256, (3, 3), activation='relu', padding='same') (p6)\n    c66 = Conv2D(256, (3, 3), activation='relu', padding='same') (c66)\n    bn66 = BatchNormalization()(c66)\n\n    u7 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same') (bn66)\n    u7 = Cropping2D(cropping=((0, 0), (0, 1)))(u7)\n    u7 = concatenate([u7, bn6])\n    c7 = Conv2D(128, (3, 3), activation='relu', padding='same') (u7)\n    c7 = Conv2D(128, (3, 3), activation='relu', padding='same') (c7)\n    bn7 = BatchNormalization()(c7)\n    \n    u8 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (bn7)\n    u8 = concatenate([u8, bn5])\n    c8 = Conv2D(64, (3, 3), activation='relu', padding='same') (u8)\n    c8 = Conv2D(64, (3, 3), activation='relu', padding='same') (c8)\n    bn8 = BatchNormalization()(c8)\n\n    u91 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (bn8)\n    u91 = concatenate([u91, bn4])\n    c91 = Conv2D(32, (3, 3), activation='relu', padding='same') (u91)\n    c91 = Conv2D(32, (3, 3), activation='relu', padding='same') (c91)\n    bn91 = BatchNormalization()(c91)\n\n    u9 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (bn91)\n    u9 = concatenate([u9, bn3])\n    c9 = Conv2D(32, (3, 3), activation='relu', padding='same') (u9)\n    c9 = Conv2D(32, (3, 3), activation='relu', padding='same') (c9)\n    bn9 = BatchNormalization()(c9)\n\n    u10 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (bn9)\n    u10 = concatenate([u10, bn2])\n    c10 = Conv2D(16, (3, 3), activation='relu', padding='same') (u10)\n    c10 = Conv2D(16, (3, 3), activation='relu', padding='same') (c10)\n    bn10 = BatchNormalization()(c10)\n    \n    u11 = Conv2DTranspose(8, (2, 2), strides=(2, 2), padding='same') (bn10)\n    u11 = concatenate([u11, bn1], axis=3)\n    c11 = Conv2D(8, (3, 3), activation='relu', padding='same') (u11)\n    c11 = Conv2D(8, (3, 3), activation='relu', padding='same') (c11)\n\n    outputs = Conv2D(4, (1, 1), activation='sigmoid') (c11)\n\n    model = Model(inputs=[inputs], outputs=[outputs])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training:"},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"train_idx, val_idx = train_test_split(\n    mask_count_df.index, random_state=2019, test_size=0.2\n)\ntraining = False\nif training:\n    data_path = \"../input/understanding_cloud_organization/\"\n    train_csv_path = os.path.join(data_path,'train.csv')\n    train_image_path = os.path.join(data_path,'train_images')\n    df = pd.read_csv(train_csv_path)\n    # drop the rows where at least one element is missing. \n    df.dropna(inplace=True)\n\n    #  split Image_Label in Image_id and Label\n    df['Image'] = df['Image_Label'].apply(lambda x: x.split('_')[0])\n    df['Label'] = df['Image_Label'].apply(lambda x: x.split('_')[1])\n\n    # drop Image_Label column\n    df.drop(columns='Image_Label', inplace=True)\n    mean_b = 0\n    mean_g = 0\n    mean_r = 0\n    std_b = 0\n    std_g = 0\n    std_r = 0\n    nr_imgs = 0\n    for i, train_id in enumerate(train_idx):\n        image_path = os.path.join(train_image_path, df['Image'].iloc[train_id])\n        img = cv2.imread(image_path)\n        mean, std = cv2.meanStdDev(img)\n        mean_b += mean[0]\n        mean_g += mean[1]\n        mean_r += mean[2]\n        std_b += std[1]\n        std_g += std[1]\n        std_r += std[2]\n        nr_imgs += 1\n\n    mean = ((mean_r[0]/nr_imgs)/255, (mean_g[0]/nr_imgs)/255, (mean_b[0]/nr_imgs)/255)\n    std = ((std_r[0]/nr_imgs)/255, (std_g[0]/nr_imgs)/255, (std_b[0]/nr_imgs)/255)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"BATCH_SIZE = 32\nif training:\n    train_generator = DataGenerator(\n        train_idx, \n        df=mask_count_df,\n        target_df=train_df,\n        batch_size=BATCH_SIZE,\n        reshape=(320, 480),\n        augment=True,\n        n_channels=3,\n        n_classes=4,\n        normalize=False,\n        mean=mean,\n        std=std\n    )\n\n    val_generator = DataGenerator(\n        val_idx, \n        df=mask_count_df,\n        target_df=train_df,\n        batch_size=BATCH_SIZE, \n        reshape=(320, 480),\n        augment=False,\n        n_channels=3,\n        n_classes=4,\n        normalize=False,\n        mean=mean,\n        std=std\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":false,"_kg_hide-output":true},"cell_type":"code","source":"if training:\n    model = unet_bn_relu(input_shape=(320, 480, 3))\n    model.compile(optimizer=Nadam(lr=0.0002), loss=bce_dice_loss, metrics=[dice_coef])\n    model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if training:\n    checkpoint = ModelCheckpoint('model_unet_bn_relu.h5', save_best_only=True)\n\n    history = model.fit_generator(\n        train_generator,\n        validation_data=val_generator,\n        callbacks=[checkpoint],\n        epochs=20\n    )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Evaluation:"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"if training:\n    with open('history.json', 'w') as f:\n        json.dump(str(history.history), f)\n\n    history_df = pd.DataFrame(history.history)\n    history_df[['loss', 'val_loss']].plot()\n    history_df[['dice_coef', 'val_dice_coef']].plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"if training:\n    print(history_df.to_string())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"def calc_dice_one_class(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 dice_coef_class1(y_true, y_pred, smooth=1):\n    y_true_1 = y_true[:,:,:,0]\n    y_pred_1 = y_pred[:,:,:,0]\n    calc_dice_one_class(y_true_1, y_pred_1)\n    return calc_dice_one_class(y_true_1, y_pred_1)\n\ndef dice_coef_class2(y_true, y_pred, smooth=1):\n    y_true_2 = y_true[:,:,:,1]\n    y_pred_2 = y_pred[:,:,:,1]\n    calc_dice_one_class(y_true_2, y_pred_2)\n    return calc_dice_one_class(y_true_2, y_pred_2)\n\ndef dice_coef_class3(y_true, y_pred, smooth=1):\n    y_true_3 = y_true[:,:,:,2]\n    y_pred_3 = y_pred[:,:,:,2]\n    calc_dice_one_class(y_true_3, y_pred_3)\n    return calc_dice_one_class(y_true_3, y_pred_3)\n\ndef dice_coef_class4(y_true, y_pred, smooth=1):\n    y_true_4 = y_true[:,:,:,3]\n    y_pred_4 = y_pred[:,:,:,3]\n    calc_dice_one_class(y_true_4, y_pred_4)\n    return calc_dice_one_class(y_true_4, y_pred_4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"model = unet_bn_relu(input_shape=(320, 480, 3))\nif training:\n    model.load_weights(\"model_unet_bn_relu.h5\")\nelse:\n    # Load pretrained model\n    model.load_weights(\"../input/premodel/model_unet_bn_relu_pretrain.h5\")\n\n    \n# Dice meteric for each class\nmodel.compile(optimizer=Nadam(lr=0.0002), loss=bce_dice_loss, metrics=[dice_coef_class1, dice_coef_class2, dice_coef_class3, dice_coef_class4, dice_coef])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"val_df = pd.DataFrame(val_idx)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"val_df = mask_count_df.iloc[val_idx]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Dice for each class"},{"metadata":{"_kg_hide-output":true,"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"Fish_df = []\nFlower_df = []\nSugar_df = []\nGravel_df = []\nAll_class_df = []\nfor i in enumerate(val_idx):\n    img = mask_count_df.iloc[i[1]]['ImageId']\n    sample_generator = DataGenerator(\n        [i[1]], \n        df=mask_count_df,\n        target_df=train_df,\n        batch_size=1, \n        reshape=(320, 480),\n        augment=False,\n        n_channels=3,\n        n_classes=4,\n        normalize=False,\n    )\n\n    score = model.evaluate(sample_generator)\n    Fish_df.append([score[1], img, 'Fish'])\n    Flower_df.append([score[2], img, 'Flower'])\n    Gravel_df.append([score[3], img, 'Gravel'])\n    Sugar_df.append([score[4], img, 'Sugar'])\n    All_class_df.append([score[5], img, 'All'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"Fish_df = pd.DataFrame(Fish_df) \nFlower_df = pd.DataFrame(Flower_df) \nSugar_df = pd.DataFrame(Sugar_df) \nGravel_df = pd.DataFrame(Gravel_df) \nAll_class_df = pd.DataFrame(All_class_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"Fish_mean_score = np.asarray(Fish_df.iloc[:,0]).mean()\nFlower_mean_score = np.asarray(Flower_df.iloc[:,0]).mean()\nSugar_mean_score = np.asarray(Sugar_df.iloc[:,0]).mean()\nGravel_mean_score = np.asarray(Gravel_df.iloc[:,0]).mean()\nClass_comp_mean_score = np.asarray(pd.concat([Fish_df.iloc[:,0], Flower_df.iloc[:,0], Sugar_df.iloc[:,0], Gravel_df.iloc[:,0]]).mean())\nAll_class_mean_score = np.asarray(All_class_df.iloc[:,0]).mean()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"print(f'Fish mean score: {Fish_mean_score}')\nprint(f'Flower mean score: {Flower_mean_score}')\nprint(f'Sugar mean score: {Sugar_mean_score}')\nprint(f'Gravel mean score: {Gravel_mean_score}')\nprint(f'Classes combined mean score: {Class_comp_mean_score}')\nprint(f'All class mean score: {All_class_mean_score}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"frames = [Fish_df, Flower_df, Sugar_df, Gravel_df]\n\nval_total_df = pd.concat(frames)\nval_total_df.columns = ['Score', 'img', 'Type']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"All_class_df.columns = ['Score', 'img', 'Type']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Images with largest and smallest Dice coeff"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"val_largest_df = All_class_df.nlargest(5, 'Score')\nval_smallest_df = All_class_df.nsmallest(5, 'Score')\nprint('Largest')\nprint(val_largest_df)\nprint('\\nSmallest')\nprint(val_smallest_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Display images, predicetions and GT for largest Dice"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"columns = 4\nrows = 5\nfig, ax = plt.subplots(rows, columns, figsize=(18, 13))\nax[0, 0].set_title('Fish', fontsize=20)\nax[0, 1].set_title('Flower', fontsize=20)\nax[0, 2].set_title('Gravel', fontsize=20)\nax[0, 3].set_title('Sugar', fontsize=20)\nj = 0\nfor i, row in val_largest_df.iterrows():\n    idx = val_idx[i]\n    img_name = row['img']\n    img = plt.imread(f\"{path}/train_images/{img_name}\")\n    ax[j, 0].imshow(img)\n    ax[j, 1].imshow(img)\n    ax[j, 2].imshow(img)\n    ax[j, 3].imshow(img)\n    \n    \n    label = row['Type']\n    for k in range(4):\n        if k == 0:\n            label = 'Fish'\n        elif k == 1:\n            label = 'Flower'\n        elif k == 2:\n            label = 'Gravel'\n        elif k == 3:\n            label = 'Sugar'\n        image_label = f'{img_name}_{label}'\n        true_mask_rle = train.loc[train['Image_Label'] == image_label, 'EncodedPixels'].values[0]\n        if true_mask_rle != true_mask_rle: \n            true_mask = np.zeros((1400, 2100))\n        else:\n            true_mask = rle_decode(true_mask_rle).astype('float32')  \n        ax[j, k].imshow(true_mask, alpha=0.5, cmap='gray')\n        \n    if label == 'Fish':\n        mask_idx = 0\n    elif label == 'Flower':\n        mask_idx = 1\n    elif label == 'Gravel':\n        mask_idx = 2\n    elif label == 'Sugar':\n        mask_idx = 3\n    sample_generator = DataGenerator(\n        [idx], \n        df=mask_count_df,\n        target_df=train_df,\n        batch_size=1, \n        reshape=(320, 480),\n        augment=False,\n        n_channels=3,\n        n_classes=4,\n        normalize=False,\n    )\n    mask = model.predict_generator(sample_generator)\n    for k in range(4):\n        pred_mask = mask[0,:,:,k]\n        pred_mask = np_resize(pred_mask, (1400, 2100))\n        ax[j, k].imshow(pred_mask, alpha=0.5, cmap='autumn')    \n    j += 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Display images, predicetions and GT for smallest Dice"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"columns = 4\nrows = 5\nfig, ax = plt.subplots(rows, columns, figsize=(18, 13))\nax[0, 0].set_title('Fish', fontsize=20)\nax[0, 1].set_title('Flower', fontsize=20)\nax[0, 2].set_title('Gravel', fontsize=20)\nax[0, 3].set_title('Sugar', fontsize=20)\nj = 0\nfor i, row in val_smallest_df.iterrows():\n    idx = val_idx[i]\n    img_name = row['img']\n    img = plt.imread(f\"{path}/train_images/{img_name}\")\n    ax[j, 0].imshow(img)\n    ax[j, 1].imshow(img)\n    ax[j, 2].imshow(img)\n    ax[j, 3].imshow(img)\n    \n    \n    label = row['Type']\n    for k in range(4):\n        if k == 0:\n            label = 'Fish'\n        elif k == 1:\n            label = 'Flower'\n        elif k == 2:\n            label = 'Gravel'\n        elif k == 3:\n            label = 'Sugar'\n        image_label = f'{img_name}_{label}'\n        true_mask_rle = train.loc[train['Image_Label'] == image_label, 'EncodedPixels'].values[0]\n        if true_mask_rle != true_mask_rle: \n            true_mask = np.zeros((1400, 2100))\n        else:\n            true_mask = rle_decode(true_mask_rle).astype('float32')  \n        ax[j, k].imshow(true_mask, alpha=0.5, cmap='gray')\n        \n    if label == 'Fish':\n        mask_idx = 0\n    elif label == 'Flower':\n        mask_idx = 1\n    elif label == 'Gravel':\n        mask_idx = 2\n    elif label == 'Sugar':\n        mask_idx = 3\n    sample_generator = DataGenerator(\n        [idx], \n        df=mask_count_df,\n        target_df=train_df,\n        batch_size=1, \n        reshape=(320, 480),\n        augment=False,\n        n_channels=3,\n        n_classes=4,\n        normalize=False,\n    )\n    mask = model.predict_generator(sample_generator)\n    for k in range(4):\n        pred_mask = mask[0,:,:,k]\n        pred_mask = np_resize(pred_mask, (1400, 2100))\n        ax[j, k].imshow(pred_mask, alpha=0.5, cmap='autumn')    \n    j += 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"if not training:\n    model.load_weights(\"../input/premodel/model_unet_bn_relu_pretrain.h5\")\nelse:\n    model.load_weights(\"model_unet_bn_relu.h5\")\n    \ntest_df = []\n\nfor i in range(0, test_imgs.shape[0], 500):\n    batch_idx = list(\n        range(i, min(test_imgs.shape[0], i + 500))\n    )\n\n    test_generator = DataGenerator(\n        batch_idx,\n        df=test_imgs,\n        shuffle=False,\n        mode='predict',\n        dim=(350, 525),\n        reshape=(320, 480),\n        n_channels=3,\n        base_path='../input/understanding_cloud_organization/test_images',\n        target_df=sub_df,\n        batch_size=1,\n        n_classes=4\n    )\n\n    batch_pred_masks = model.predict_generator(\n        test_generator, \n        workers=1,\n        verbose=1\n    )\n\n    for j, b in enumerate(batch_idx):\n        filename = test_imgs['ImageId'].iloc[b]\n        image_df = sub_df[sub_df['ImageId'] == filename].copy()\n\n        pred_masks = batch_pred_masks[j, ].round().astype(int)\n        pred_rles = build_rles(pred_masks, reshape=(350, 525))\n\n        image_df['EncodedPixels'] = pred_rles\n        test_df.append(image_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.concat(test_df)\ntest_df.drop(columns='ImageId', inplace=True)\ntest_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}