{"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":"## Functions to load and read input data","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-20T08:59:51.279456Z","iopub.execute_input":"2022-01-20T08:59:51.279777Z","iopub.status.idle":"2022-01-20T08:59:51.310555Z","shell.execute_reply.started":"2022-01-20T08:59:51.279686Z","shell.execute_reply":"2022-01-20T08:59:51.309758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#importng all the required libraries\nimport tensorflow as tf\nfrom zipfile import ZipFile \nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport os","metadata":{"execution":{"iopub.status.busy":"2022-01-20T08:59:58.276743Z","iopub.execute_input":"2022-01-20T08:59:58.277347Z","iopub.status.idle":"2022-01-20T09:00:03.436887Z","shell.execute_reply.started":"2022-01-20T08:59:58.277304Z","shell.execute_reply":"2022-01-20T09:00:03.436101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#extracting all the contents of zipped file which contains all the train images\ntrain_zip = \"/kaggle/input/carvana-image-masking-challenge/train.zip\"#address of the input file \nwith ZipFile(train_zip, 'r') as zip_: # reading everything in the train folder and extrcting it in output directory\n    zip_.extractall('/kaggle/working')","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:03.438252Z","iopub.execute_input":"2022-01-20T09:00:03.439630Z","iopub.status.idle":"2022-01-20T09:00:13.595676Z","shell.execute_reply.started":"2022-01-20T09:00:03.439588Z","shell.execute_reply":"2022-01-20T09:00:13.594937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#extracting all the contents of zipped file which contains all the masks of train images\ntrain_mask_zip = \"/kaggle/input/carvana-image-masking-challenge/train_masks.zip\"\nwith ZipFile(train_mask_zip, 'r') as zip_: \n    zip_.extractall('/kaggle/working')","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:13.597399Z","iopub.execute_input":"2022-01-20T09:00:13.597642Z","iopub.status.idle":"2022-01-20T09:00:14.422295Z","shell.execute_reply.started":"2022-01-20T09:00:13.597608Z","shell.execute_reply":"2022-01-20T09:00:14.421556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train set:  \", len(os.listdir(\"/kaggle/working/train\")))#length of folder extracted above in output\nprint(\"Train masks:\", len(os.listdir(\"/kaggle/working/train_masks\")))#length of folder extracted above in output","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.423402Z","iopub.execute_input":"2022-01-20T09:00:14.425361Z","iopub.status.idle":"2022-01-20T09:00:14.436997Z","shell.execute_reply.started":"2022-01-20T09:00:14.425329Z","shell.execute_reply":"2022-01-20T09:00:14.435925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"car_ids = []\npaths = []\nfor dirname, _, filenames in os.walk('/kaggle/working/train'):\n    for filename in filenames:#images in train folder\n        path = os.path.join(dirname, filename)    \n        paths.append(path)#images address\n        \n        car_id = filename.split(\".\")[0]\n        car_ids.append(car_id) #id of train images\n\nd = {\"id\": car_ids, \"car_path\": paths}\ndf = pd.DataFrame(data = d)\ndf = df.set_index('id') # df containing path to each training image and image unique name as index\ndf","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.439450Z","iopub.execute_input":"2022-01-20T09:00:14.439730Z","iopub.status.idle":"2022-01-20T09:00:14.487780Z","shell.execute_reply.started":"2022-01-20T09:00:14.439683Z","shell.execute_reply":"2022-01-20T09:00:14.486970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"car_ids = []\nmask_path = []\nfor dirname, _, filenames in os.walk('/kaggle/working/train_masks'):\n    for filename in filenames: #contents of train_mask folder\n        path = os.path.join(dirname, filename)\n        mask_path.append(path)  #\n        \n        car_id = filename.split(\".\")[0]\n        car_id = car_id.split(\"_mask\")[0]\n        car_ids.append(car_id)\n\n        \nd = {\"id\": car_ids,\"mask_path\": mask_path}\nmask_df = pd.DataFrame(data = d)\nmask_df = mask_df.set_index('id') #containg path to masks of train data and unique id if images as index \nmask_df","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.489236Z","iopub.execute_input":"2022-01-20T09:00:14.489534Z","iopub.status.idle":"2022-01-20T09:00:14.525943Z","shell.execute_reply.started":"2022-01-20T09:00:14.489496Z","shell.execute_reply":"2022-01-20T09:00:14.524501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_df[\"mask_path\"][0]","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.527851Z","iopub.execute_input":"2022-01-20T09:00:14.528190Z","iopub.status.idle":"2022-01-20T09:00:14.537875Z","shell.execute_reply.started":"2022-01-20T09:00:14.528149Z","shell.execute_reply":"2022-01-20T09:00:14.536824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"mask_path\"] = mask_df[\"mask_path\"]#putting image path and mask path in a single dataframe\ndf","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.539517Z","iopub.execute_input":"2022-01-20T09:00:14.539873Z","iopub.status.idle":"2022-01-20T09:00:14.556229Z","shell.execute_reply.started":"2022-01-20T09:00:14.539835Z","shell.execute_reply":"2022-01-20T09:00:14.555338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## functions for preprocessing of data to make it ready for training models","metadata":{}},{"cell_type":"code","source":"img_size = [64,64]\n\ndef data_augmentation(car_img, mask_img):# few data augmentation methods\n\n    if tf.random.uniform(()) > 0.5:#generatin a random condition wih random number between 0 and 1 \n        car_img = tf.image.flip_left_right(car_img)#flipping image from left to right\n        mask_img = tf.image.flip_left_right(mask_img)#flipping image masks from left to right\n\n    return car_img, mask_img\n\ndef preprocessing(car_path, mask_path):\n    car_img = tf.io.read_file(car_path) #reading train image path\n    car_img = tf.image.decode_jpeg(car_img, channels=3) #coverting from scalar string tensor to  3d uint8\n    car_img = tf.image.resize(car_img, img_size) #resizing it ti use it more conviniently \n    car_img = tf.cast(car_img, tf.float32) / 255.0 # normalizing the pixel values between 0 to 1\n    \n    mask_img = tf.io.read_file(mask_path)#reading mask path\n    mask_img = tf.image.decode_jpeg(mask_img, channels=3)\n    mask_img = tf.image.resize(mask_img, img_size)\n    mask_img = mask_img[:,:,:1]  #taking use of only one channel  \n    mask_img = tf.math.sign(mask_img)\n    \n    \n    return car_img, mask_img\ndef create_dataset(df, train = False):\n    if not train:\n        ds = tf.data.Dataset.from_tensor_slices((df[\"car_path\"].values, df[\"mask_path\"].values))#taking path as object\n        ds = ds.map(preprocessing, tf.data.AUTOTUNE) #mapping masks to preproessing function\n    else:\n        ds = tf.data.Dataset.from_tensor_slices((df[\"car_path\"].values, df[\"mask_path\"].values))\n        ds = ds.map(preprocessing, tf.data.AUTOTUNE) # mapping images to preprocessing function\n        ds = ds.map(data_augmentation, tf.data.AUTOTUNE)# mapping images to data_augmemtation function\n\n    return ds","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.557984Z","iopub.execute_input":"2022-01-20T09:00:14.558654Z","iopub.status.idle":"2022-01-20T09:00:14.572580Z","shell.execute_reply.started":"2022-01-20T09:00:14.558566Z","shell.execute_reply":"2022-01-20T09:00:14.571767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.columns","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.574073Z","iopub.execute_input":"2022-01-20T09:00:14.574385Z","iopub.status.idle":"2022-01-20T09:00:14.587420Z","shell.execute_reply.started":"2022-01-20T09:00:14.574304Z","shell.execute_reply":"2022-01-20T09:00:14.586613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sh = plt.imread(df[\"mask_path\"][0]).shape # real shape of mask \nmask_h = sh[0]#real height of mask images\nmask_w = sh[1]#real width of mask images","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.590164Z","iopub.execute_input":"2022-01-20T09:00:14.590459Z","iopub.status.idle":"2022-01-20T09:00:14.634967Z","shell.execute_reply.started":"2022-01-20T09:00:14.590425Z","shell.execute_reply":"2022-01-20T09:00:14.634207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_h ","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:44:20.091514Z","iopub.execute_input":"2022-01-20T09:44:20.092012Z","iopub.status.idle":"2022-01-20T09:44:20.097922Z","shell.execute_reply.started":"2022-01-20T09:44:20.091972Z","shell.execute_reply":"2022-01-20T09:44:20.097190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, valid_df = train_test_split(df, random_state=42, test_size=.25)# splitting given labelled data into train and valid \ntrain = create_dataset(train_df, train = True)# train dataset\nvalid = create_dataset(valid_df)# valid dataset","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:14.636229Z","iopub.execute_input":"2022-01-20T09:00:14.636488Z","iopub.status.idle":"2022-01-20T09:00:17.462766Z","shell.execute_reply.started":"2022-01-20T09:00:14.636454Z","shell.execute_reply":"2022-01-20T09:00:17.462085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_LENGTH = len(train_df)#length if train dataset\nBATCH_SIZE = 16 # batch size to train images \nBUFFER_SIZE = 1000 #","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:17.464962Z","iopub.execute_input":"2022-01-20T09:00:17.465468Z","iopub.status.idle":"2022-01-20T09:00:17.469908Z","shell.execute_reply.started":"2022-01-20T09:00:17.465428Z","shell.execute_reply":"2022-01-20T09:00:17.469292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = train.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat() # shuffing and batching records\ntrain_dataset = train_dataset.prefetch(buffer_size=tf.data.AUTOTUNE) #fetching data to train\nvalid_dataset = valid.batch(BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:17.471157Z","iopub.execute_input":"2022-01-20T09:00:17.471581Z","iopub.status.idle":"2022-01-20T09:00:17.488509Z","shell.execute_reply.started":"2022-01-20T09:00:17.471545Z","shell.execute_reply":"2022-01-20T09:00:17.487882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display(display_list): # function for visualizing  images\n    plt.figure(figsize=(10, 10)) #size of plot\n\n    title = ['Input Image', 'True Mask', 'Predicted Mask'] #possible images\n\n    for i in range(len(display_list)): \n        plt.subplot(1, len(display_list), i+1) #image, true_mask, predicted_mask\n        plt.title(title[i])\n        plt.imshow(tf.keras.preprocessing.image.array_to_img(display_list[i])) #function to show images\n        plt.axis('off')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:17.489496Z","iopub.execute_input":"2022-01-20T09:00:17.489721Z","iopub.status.idle":"2022-01-20T09:00:17.499159Z","shell.execute_reply.started":"2022-01-20T09:00:17.489689Z","shell.execute_reply":"2022-01-20T09:00:17.498336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(5):\n   for image, mask in train.take(i): #taking i records\n        sample_image, sample_mask = image, mask\n        print(sample_image.shape)\n        display([sample_image, sample_mask]) #visualizing using above function","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:17.500845Z","iopub.execute_input":"2022-01-20T09:00:17.501131Z","iopub.status.idle":"2022-01-20T09:00:21.935103Z","shell.execute_reply.started":"2022-01-20T09:00:17.501093Z","shell.execute_reply":"2022-01-20T09:00:21.934343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## creating model","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import Input\nfrom tensorflow.keras.layers import Conv2D\nfrom tensorflow.keras.layers import MaxPooling2D\nfrom tensorflow.keras.layers import Dropout \nfrom tensorflow.keras.layers import BatchNormalization\nfrom tensorflow.keras.layers import Conv2DTranspose\nfrom tensorflow.keras.layers import concatenate\nfrom tensorflow.keras.losses import binary_crossentropy\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:21.936656Z","iopub.execute_input":"2022-01-20T09:00:21.936913Z","iopub.status.idle":"2022-01-20T09:00:21.952297Z","shell.execute_reply.started":"2022-01-20T09:00:21.936877Z","shell.execute_reply":"2022-01-20T09:00:21.951480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"UNet model is particularly good at image segmentation and we are going to make it from scratch.\nwe have to subpart it in two parts. Encoder which will be used for downsampling and decoder will be used for upsampling.","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"The encoder block follows a pattern of using convolution layer two times on the input data and then use maxpooling layer to decrease parameters and computational cost.\nWe can use batch normalization in between layers to regularize their input ","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"\ndef EncoderMiniBlock(inputs, n_filters=32, dropout_prob=0.3, max_pooling=True):\n    \"\"\"\n    This block uses multiple convolution layers, max pool, relu activation to create an architecture for learning. \n    Dropout can be added for regularization to prevent overfitting. \n    The block returns the activation values for next layer along with a skip connection which will be used in the decoder\n    \"\"\"\n    # Add 2 Conv Layers with relu activation and HeNormal initialization using TensorFlow \n    # Proper initialization prevents from the problem of exploding and vanishing gradients \n    # 'Same' padding will pad the input to conv layer such that the output has the same height and width (hence, is not reduced in size) \n    conv = Conv2D(n_filters, \n                  3,   # Kernel size   \n                  activation='relu',\n                  padding='same',\n                  kernel_initializer='HeNormal')(inputs)\n    conv = Conv2D(n_filters, \n                  3,   # Kernel size\n                  activation='relu',\n                  padding='same',\n                  kernel_initializer='HeNormal')(conv)\n    \n    # Batch Normalization will normalize the output of the last layer based on the batch's mean and standard deviation\n    conv = BatchNormalization()(conv, training=False)\n\n    # In case of overfitting, dropout will regularize the loss and gradient computation to shrink the influence of weights on output\n    if dropout_prob > 0:     \n        conv = tf.keras.layers.Dropout(dropout_prob)(conv)\n\n    # Pooling reduces the size of the image while keeping the number of channels same\n    # Pooling has been kept as optional as the last encoder layer does not use pooling (hence, makes the encoder block flexible to use)\n    # Below, Max pooling considers the maximum of the input slice for output computation and uses stride of 2 to traverse across input image\n    if max_pooling:\n        next_layer = tf.keras.layers.MaxPooling2D(pool_size = (2,2))(conv)    \n    else:\n        next_layer = conv\n\n    # skip connection (without max pooling) will be input to the decoder layer to prevent information loss during transpose convolutions      \n    skip_connection = conv\n    \n    return next_layer, skip_connection\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:21.956641Z","iopub.execute_input":"2022-01-20T09:00:21.956878Z","iopub.status.idle":"2022-01-20T09:00:21.966480Z","shell.execute_reply.started":"2022-01-20T09:00:21.956850Z","shell.execute_reply":"2022-01-20T09:00:21.965774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Using decoder block to upsample images by using trans convolution on the provided input and merging it with corresponding downsampled layer then applying convolution two times.  ","metadata":{}},{"cell_type":"code","source":"def DecoderMiniBlock(prev_layer_input, skip_layer_input, n_filters=32):\n    \"\"\"\n    Decoder Block first uses transpose convolution to upscale the image to a bigger size and then,\n    merges the result with skip layer results from encoder block\n    Adding 2 convolutions with 'same' padding helps further increase the depth of the network for better predictions\n    The function returns the decoded layer output\n    \"\"\"\n    # Start with a transpose convolution layer to first increase the size of the image\n    up = Conv2DTranspose(\n                 n_filters,\n                 (3,3),    # Kernel size\n                 strides=(2,2),\n                 padding='same')(prev_layer_input)\n\n    # Merge the skip connection from previous block to prevent information loss\n    merge = concatenate([up, skip_layer_input], axis=3)\n    \n    # Add 2 Conv Layers with relu activation and HeNormal initialization for further processing\n    # The parameters for the function are similar to encoder\n    conv = Conv2D(n_filters, \n                 3,     # Kernel size\n                 activation='relu',\n                 padding='same',\n                 kernel_initializer='HeNormal')(merge)\n    conv = Conv2D(n_filters,\n                 3,   # Kernel size\n                 activation='relu',\n                 padding='same',\n                 kernel_initializer='HeNormal')(conv)\n    return conv","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:21.968075Z","iopub.execute_input":"2022-01-20T09:00:21.968364Z","iopub.status.idle":"2022-01-20T09:00:21.977354Z","shell.execute_reply.started":"2022-01-20T09:00:21.968310Z","shell.execute_reply":"2022-01-20T09:00:21.976615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"now that we have coded basic blocks, we need to compile unet, that is appropriate for our dataset","metadata":{}},{"cell_type":"code","source":"#3.3 - Compile U-Net Blocks\ndef UNetCompiled(input_size=(128, 128, 3), n_filters=16, n_classes=1):\n    inputs = Input(input_size)\n    \n    # Encoder includes multiple convolutional mini blocks with different maxpooling, dropout and filter parameters\n    # Observe that the filters are increasing as we go deeper into the network which will increasse the # channels of the image \n    cblock1 = EncoderMiniBlock(inputs, n_filters,dropout_prob=0, max_pooling=True)\n    cblock2 = EncoderMiniBlock(cblock1[0],n_filters*2,dropout_prob=0, max_pooling=True)\n    cblock3 = EncoderMiniBlock(cblock2[0], n_filters*4,dropout_prob=0, max_pooling=True)\n    cblock4 = EncoderMiniBlock(cblock3[0], n_filters*8,dropout_prob=0.3, max_pooling=True)\n    cblock5 = EncoderMiniBlock(cblock4[0], n_filters*16, dropout_prob=0.3, max_pooling=False) \n    \n    # Decoder includes multiple mini blocks with decreasing number of filters\n    # Observe the skip connections from the encoder are given as input to the decoder\n    # Recall the 2nd output of encoder block was skip connection, hence cblockn[1] is used\n    ublock6 = DecoderMiniBlock(cblock5[0], cblock4[1],  n_filters * 8)\n    ublock7 = DecoderMiniBlock(ublock6, cblock3[1],  n_filters * 4)\n    ublock8 = DecoderMiniBlock(ublock7, cblock2[1],  n_filters * 2)\n    ublock9 = DecoderMiniBlock(ublock8, cblock1[1],  n_filters)\n \n    # Complete the model with 1 3x3 convolution layer (Same as the prev Conv Layers)\n    # Followed by a 1x1 Conv layer to get the image to the desired size. \n    # Observe the number of channels will be equal to number of output classes\n    conv9 = Conv2D(n_filters,\n                 3,\n                 activation='relu',\n                 padding='same',\n                 kernel_initializer='he_normal')(ublock9)\n\n    conv10 = Conv2D(n_classes, 1, padding='same')(conv9)\n    \n    # Define the model\n    model = tf.keras.Model(inputs=inputs, outputs=conv10)\n\n    return model\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:21.980262Z","iopub.execute_input":"2022-01-20T09:00:21.980499Z","iopub.status.idle":"2022-01-20T09:00:21.990794Z","shell.execute_reply.started":"2022-01-20T09:00:21.980474Z","shell.execute_reply":"2022-01-20T09:00:21.989757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#compiling unet model\nunet = UNetCompiled(input_size=(64,64,3), n_filters=16, n_classes=1)\n","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:21.992375Z","iopub.execute_input":"2022-01-20T09:00:21.992958Z","iopub.status.idle":"2022-01-20T09:00:22.272119Z","shell.execute_reply.started":"2022-01-20T09:00:21.992894Z","shell.execute_reply":"2022-01-20T09:00:22.271415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.losses import binary_crossentropy\nimport keras.backend as K\n\n#metric and loss function to be used for training model\ndef dice_coeff(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 = K.sum(y_true_f * y_pred_f)\n    score = (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n    return score\n\n\ndef dice_loss(y_true, y_pred):\n    loss = 1 - dice_coeff(y_true, y_pred)\n    return loss\n\n\ndef bce_dice_loss(y_true, y_pred):\n    loss = binary_crossentropy(y_true, y_pred) + dice_loss(y_true, y_pred)\n    return loss","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:24.074483Z","iopub.execute_input":"2022-01-20T09:00:24.075096Z","iopub.status.idle":"2022-01-20T09:00:24.084644Z","shell.execute_reply.started":"2022-01-20T09:00:24.075050Z","shell.execute_reply":"2022-01-20T09:00:24.083990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unet.compile(optimizer=tf.keras.optimizers.Adam(), \n             loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:24.476542Z","iopub.execute_input":"2022-01-20T09:00:24.477095Z","iopub.status.idle":"2022-01-20T09:00:24.492260Z","shell.execute_reply.started":"2022-01-20T09:00:24.477057Z","shell.execute_reply":"2022-01-20T09:00:24.491508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH = TRAIN_LENGTH // BATCH_SIZE","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:24.826149Z","iopub.execute_input":"2022-01-20T09:00:24.826816Z","iopub.status.idle":"2022-01-20T09:00:24.830470Z","shell.execute_reply.started":"2022-01-20T09:00:24.826777Z","shell.execute_reply":"2022-01-20T09:00:24.829333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#callbacks to apply when training the model\n#early stopping if performance does not improve within given patience parameter\n#model checkpoint for saving weights of the model which las performed better \n# reducing learning rate in order to find the optimal solution \nfrom keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:25.056070Z","iopub.execute_input":"2022-01-20T09:00:25.056595Z","iopub.status.idle":"2022-01-20T09:00:25.060638Z","shell.execute_reply.started":"2022-01-20T09:00:25.056556Z","shell.execute_reply":"2022-01-20T09:00:25.059596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"callbacks = [\n    EarlyStopping(patience=10, verbose=1),\n    ReduceLROnPlateau(factor=0.1, patience=5, min_lr=0.00001, verbose=1),\n    ModelCheckpoint('model-tgs-salt.h5', verbose=1, save_best_only=True, save_weights_only=True)\n]","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:25.275725Z","iopub.execute_input":"2022-01-20T09:00:25.275960Z","iopub.status.idle":"2022-01-20T09:00:25.281966Z","shell.execute_reply.started":"2022-01-20T09:00:25.275932Z","shell.execute_reply":"2022-01-20T09:00:25.280954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hist = unet.fit(train_dataset, batch_size=16, epochs=15,steps_per_epoch=STEPS_PER_EPOCH,callbacks = callbacks, validation_data=valid_dataset)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:00:25.526401Z","iopub.execute_input":"2022-01-20T09:00:25.526844Z","iopub.status.idle":"2022-01-20T09:09:49.046334Z","shell.execute_reply.started":"2022-01-20T09:00:25.526809Z","shell.execute_reply":"2022-01-20T09:09:49.045570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#loading the weight of model which last performed  best\nunet.load_weights(\"./model-tgs-salt.h5\")","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:49.048423Z","iopub.execute_input":"2022-01-20T09:09:49.048756Z","iopub.status.idle":"2022-01-20T09:09:49.121834Z","shell.execute_reply.started":"2022-01-20T09:09:49.048718Z","shell.execute_reply":"2022-01-20T09:09:49.121110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#delete train_df,valid_df, train, valid, df, mask_df to free up memory \nimport gc\n#del train_df\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:49.123248Z","iopub.execute_input":"2022-01-20T09:09:49.123522Z","iopub.status.idle":"2022-01-20T09:09:49.312003Z","shell.execute_reply.started":"2022-01-20T09:09:49.123475Z","shell.execute_reply":"2022-01-20T09:09:49.311066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del mask_df\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:49.314518Z","iopub.execute_input":"2022-01-20T09:09:49.315269Z","iopub.status.idle":"2022-01-20T09:09:49.494794Z","shell.execute_reply.started":"2022-01-20T09:09:49.315236Z","shell.execute_reply":"2022-01-20T09:09:49.493931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del df\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:49.496058Z","iopub.execute_input":"2022-01-20T09:09:49.496941Z","iopub.status.idle":"2022-01-20T09:09:49.755982Z","shell.execute_reply.started":"2022-01-20T09:09:49.496895Z","shell.execute_reply":"2022-01-20T09:09:49.754758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del train\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:49.757408Z","iopub.execute_input":"2022-01-20T09:09:49.757840Z","iopub.status.idle":"2022-01-20T09:09:49.989732Z","shell.execute_reply.started":"2022-01-20T09:09:49.757797Z","shell.execute_reply":"2022-01-20T09:09:49.988618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del valid\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:49.991530Z","iopub.execute_input":"2022-01-20T09:09:49.994783Z","iopub.status.idle":"2022-01-20T09:09:50.199245Z","shell.execute_reply.started":"2022-01-20T09:09:49.994735Z","shell.execute_reply":"2022-01-20T09:09:50.198550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del valid_df\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:50.200482Z","iopub.execute_input":"2022-01-20T09:09:50.201109Z","iopub.status.idle":"2022-01-20T09:09:50.382156Z","shell.execute_reply.started":"2022-01-20T09:09:50.201067Z","shell.execute_reply":"2022-01-20T09:09:50.381425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def vis_compare(dataset=valid_dataset,num_case=1):\n       \n    for sample in dataset.take(1):\n        image, label = sample[0].numpy(), sample[1].numpy()\n        print(image.shape)\n        print(label.shape)\n    preds=unet.predict(image)#predicting mask of valid dataset \n    preds = np.squeeze(preds, axis =-1)\n    print(preds.shape)\n    if num_case>1:\n        cases=[j for j in np.random.choice(image.shape[0],size=num_case,replace=False)]   #choosing random images\n        for i in cases:\n            truth=(image[i],label[i])\n            pred=(image[i],preds[i])\n            print(f\"case_number_{i}\")\n            fig, arr = plt.subplots(1, 3, figsize=(15, 15))\n            arr[0].imshow(image[i])\n            arr[0].set_title('Processed Image')\n            arr[1].imshow(label[i])\n            arr[1].set_title('Actual Masked Image ')\n            arr[2].imshow(preds[i])\n            arr[2].set_title('Predicted Masked Image ')\n    else:\n        truth=(image[0],label[0])\n        pred=(image[0],preds[0])\n        display([image[0],label[0],preds[0]])\n            \n    \n    \n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:50.383611Z","iopub.execute_input":"2022-01-20T09:09:50.383854Z","iopub.status.idle":"2022-01-20T09:09:50.394540Z","shell.execute_reply.started":"2022-01-20T09:09:50.383820Z","shell.execute_reply":"2022-01-20T09:09:50.393832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vis_compare(dataset=valid_dataset,num_case=2)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:50.397321Z","iopub.execute_input":"2022-01-20T09:09:50.397763Z","iopub.status.idle":"2022-01-20T09:09:51.836797Z","shell.execute_reply.started":"2022-01-20T09:09:50.397727Z","shell.execute_reply":"2022-01-20T09:09:51.836112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#for test data\ntest_zip = \"/kaggle/input/carvana-image-masking-challenge/test.zip\"#path for test data\nwith ZipFile(test_zip, 'r') as zip_: \n    zip_.extractall('/kaggle/working')\n    ","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:09:51.838003Z","iopub.execute_input":"2022-01-20T09:09:51.840083Z","iopub.status.idle":"2022-01-20T09:12:43.078766Z","shell.execute_reply.started":"2022-01-20T09:09:51.840042Z","shell.execute_reply":"2022-01-20T09:12:43.078018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"car_ids = []\npaths = []\nfor dirname, _, filenames in os.walk('/kaggle/working/test'):\n    for filename in filenames:\n        path = os.path.join(dirname, filename)    \n        paths.append(path)\n        \n        car_id = filename.split(\".\")[0]\n        car_ids.append(car_id)\n\nd = {\"id\": car_ids, \"car_path\": paths}\ndf = pd.DataFrame(data = d)\ndf = df.set_index('id')\ndf","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:12:43.081319Z","iopub.execute_input":"2022-01-20T09:12:43.081726Z","iopub.status.idle":"2022-01-20T09:12:43.466933Z","shell.execute_reply.started":"2022-01-20T09:12:43.081689Z","shell.execute_reply":"2022-01-20T09:12:43.466268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_size = [64,64]\n\n\ndef preprocessing(car_path): #preprocessing test data as did to train data\n    car_img = tf.io.read_file(car_path) \n    car_img = tf.image.decode_jpeg(car_img, channels=3)\n    car_img = tf.image.resize(car_img, img_size)\n    car_img = tf.cast(car_img, tf.float32) / 255.0\n    return car_img\ndef create_dataset(df, train = False): #dataset for input of model\n    if not train:\n        ds = tf.data.Dataset.from_tensor_slices((df[\"car_path\"].values))\n        ds = ds.map(preprocessing, tf.data.AUTOTUNE)\n\n    return ds\ntest = create_dataset(df)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:12:43.468229Z","iopub.execute_input":"2022-01-20T09:12:43.468485Z","iopub.status.idle":"2022-01-20T09:12:43.580866Z","shell.execute_reply.started":"2022-01-20T09:12:43.468451Z","shell.execute_reply":"2022-01-20T09:12:43.579886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 16\ntest_dataset = test.batch(BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:12:43.581977Z","iopub.execute_input":"2022-01-20T09:12:43.582219Z","iopub.status.idle":"2022-01-20T09:12:43.587724Z","shell.execute_reply.started":"2022-01-20T09:12:43.582186Z","shell.execute_reply":"2022-01-20T09:12:43.587037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(df)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:12:43.589054Z","iopub.execute_input":"2022-01-20T09:12:43.589453Z","iopub.status.idle":"2022-01-20T09:12:43.605192Z","shell.execute_reply.started":"2022-01-20T09:12:43.589417Z","shell.execute_reply":"2022-01-20T09:12:43.602150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#visualizing test images\nfor i in range(5):\n   for image  in test.take(i):\n        print(image.shape)\n        print(i)\n        sample_image= image\n        display([sample_image])","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:12:43.606658Z","iopub.execute_input":"2022-01-20T09:12:43.607116Z","iopub.status.idle":"2022-01-20T09:12:46.829828Z","shell.execute_reply.started":"2022-01-20T09:12:43.607077Z","shell.execute_reply":"2022-01-20T09:12:46.829123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = unet.predict(test_dataset)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:12:46.832318Z","iopub.execute_input":"2022-01-20T09:12:46.832598Z","iopub.status.idle":"2022-01-20T09:22:04.336072Z","shell.execute_reply.started":"2022-01-20T09:12:46.832562Z","shell.execute_reply":"2022-01-20T09:22:04.334409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" preds.shape","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:22:04.338525Z","iopub.execute_input":"2022-01-20T09:22:04.338783Z","iopub.status.idle":"2022-01-20T09:22:04.346559Z","shell.execute_reply.started":"2022-01-20T09:22:04.338747Z","shell.execute_reply":"2022-01-20T09:22:04.345671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:23:06.688822Z","iopub.execute_input":"2022-01-20T09:23:06.689099Z","iopub.status.idle":"2022-01-20T09:23:07.028210Z","shell.execute_reply.started":"2022-01-20T09:23:06.689068Z","shell.execute_reply":"2022-01-20T09:23:07.027469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" def run_length_encode(mask): #function to change the predicted masks into wanted submission type according to instructions  \n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    inds = mask.flatten()#making it scalar\n    runs = np.where(inds[1:] != inds[:-1])[0] + 2\n    runs[1::2] = runs[1::2] - runs[:-1:2]\n    rle = ' '.join([str(r) for r in runs])\n    return rle\n\n\nrles = []   \n\n#preds_o=preds.max(axis=3)\n\npreds = np.squeeze(preds, axis=3)\nfor pred in preds:\n    prob = cv2.resize(pred, (mask_w, mask_h))\n    mask = prob > 0.5\n    rle = run_length_encode(mask)\n    rles.append(rle)\n\nprint(\"Generating submission file...\")\n","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:33:48.864661Z","iopub.execute_input":"2022-01-20T09:33:48.864917Z","iopub.status.idle":"2022-01-20T09:44:20.089736Z","shell.execute_reply.started":"2022-01-20T09:33:48.864886Z","shell.execute_reply":"2022-01-20T09:44:20.088936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(rles)","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:44:56.090900Z","iopub.execute_input":"2022-01-20T09:44:56.091157Z","iopub.status.idle":"2022-01-20T09:44:56.096244Z","shell.execute_reply.started":"2022-01-20T09:44:56.091126Z","shell.execute_reply":"2022-01-20T09:44:56.095339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfs = pd.DataFrame({'img': df.index.values + \".jpg\", 'rle_mask': rles})#creating dataframe of image id and predicted masks as columns \n","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:58:09.493359Z","iopub.execute_input":"2022-01-20T09:58:09.493916Z","iopub.status.idle":"2022-01-20T09:58:09.532101Z","shell.execute_reply.started":"2022-01-20T09:58:09.493872Z","shell.execute_reply":"2022-01-20T09:58:09.531182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfs.to_csv('submission_6.csv.gz', index=False, compression ='gzip' )#converting to compressed csv file ","metadata":{"execution":{"iopub.status.busy":"2022-01-20T09:58:09.936040Z","iopub.execute_input":"2022-01-20T09:58:09.936306Z","iopub.status.idle":"2022-01-20T10:00:57.645855Z","shell.execute_reply.started":"2022-01-20T09:58:09.936257Z","shell.execute_reply":"2022-01-20T10:00:57.645078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv(\"./submission_6.csv.gz\")","metadata":{"execution":{"iopub.status.busy":"2022-01-20T10:02:35.967483Z","iopub.execute_input":"2022-01-20T10:02:35.968308Z","iopub.status.idle":"2022-01-20T10:02:47.740895Z","shell.execute_reply.started":"2022-01-20T10:02:35.968250Z","shell.execute_reply":"2022-01-20T10:02:47.740135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}