{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# 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-07-27T15:35:29.566082Z","iopub.execute_input":"2022-07-27T15:35:29.566641Z","iopub.status.idle":"2022-07-27T15:35:29.758853Z","shell.execute_reply.started":"2022-07-27T15:35:29.566540Z","shell.execute_reply":"2022-07-27T15:35:29.757470Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image \nimport os \nimport numpy as np \nimport matplotlib.pyplot as plt \nimport pandas as pd \nimport tensorflow as tf \n","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:36.579190Z","iopub.execute_input":"2022-07-27T15:35:36.579664Z","iopub.status.idle":"2022-07-27T15:35:43.200888Z","shell.execute_reply.started":"2022-07-27T15:35:36.579624Z","shell.execute_reply":"2022-07-27T15:35:43.199182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = pd.read_csv('../input/hubmap-organ-segmentation/train.csv')\ntest_data = pd.read_csv('../input/hubmap-organ-segmentation/test.csv')","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:43.203725Z","iopub.execute_input":"2022-07-27T15:35:43.204779Z","iopub.status.idle":"2022-07-27T15:35:43.588212Z","shell.execute_reply.started":"2022-07-27T15:35:43.204725Z","shell.execute_reply":"2022-07-27T15:35:43.587243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_data.img_width.unique())\nprint(train_data.img_height.unique())\n","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:43.589397Z","iopub.execute_input":"2022-07-27T15:35:43.590358Z","iopub.status.idle":"2022-07-27T15:35:43.605434Z","shell.execute_reply.started":"2022-07-27T15:35:43.590319Z","shell.execute_reply":"2022-07-27T15:35:43.603846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images = tf.data.Dataset.list_files('../input/hubmap-organ-segmentation/train_images/*.tiff')","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:45.464925Z","iopub.execute_input":"2022-07-27T15:35:45.466012Z","iopub.status.idle":"2022-07-27T15:35:45.514636Z","shell.execute_reply.started":"2022-07-27T15:35:45.465953Z","shell.execute_reply":"2022-07-27T15:35:45.513229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rle_arr= np.array(train_data.rle) ","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:48.265712Z","iopub.execute_input":"2022-07-27T15:35:48.266535Z","iopub.status.idle":"2022-07-27T15:35:48.272313Z","shell.execute_reply.started":"2022-07-27T15:35:48.266480Z","shell.execute_reply":"2022-07-27T15:35:48.271417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_rle = tf.data.Dataset.from_tensor_slices(rle_arr)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:50.027094Z","iopub.execute_input":"2022-07-27T15:35:50.027529Z","iopub.status.idle":"2022-07-27T15:35:50.046228Z","shell.execute_reply.started":"2022-07-27T15:35:50.027490Z","shell.execute_reply":"2022-07-27T15:35:50.045293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = tf.data.Dataset.zip((train_images , train_rle))","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:55.110504Z","iopub.execute_input":"2022-07-27T15:35:55.110952Z","iopub.status.idle":"2022-07-27T15:35:55.117579Z","shell.execute_reply.started":"2022-07-27T15:35:55.110914Z","shell.execute_reply":"2022-07-27T15:35:55.116748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def interpret_rle(rle , width , target_size ):\n    rle_arr= np.array(rle.split() , dtype = int)\n    start = rle_arr[::2] \n    steps = rle_arr[1::2] \n    end = start + steps\n    width , width = width\n    img = np.zeros(shape = (width * width ))\n    for st , en in zip(start ,end) : \n        img[st : en] = 1 \n        \n    img = Image.fromarray(img.reshape(width, width))\n    \n    img = img.resize((target_size, target_size))\n    img = np.array(img).astype(float)\n    #rescale label\n    img = np.round((img - img.min())/(img.max() - img.min()))\n    \n    return img.T","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:35:59.789354Z","iopub.execute_input":"2022-07-27T15:35:59.789795Z","iopub.status.idle":"2022-07-27T15:35:59.800841Z","shell.execute_reply.started":"2022-07-27T15:35:59.789758Z","shell.execute_reply":"2022-07-27T15:35:59.799269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def preprocess(train_image_path , rle) : \n    train_img = Image.open(train_image_path.numpy()) \n    mask_img = interpret_rle(rle.numpy() , train_img.size  , 128 )\n    mask_img = np.expand_dims(mask_img , -1)\n    train_img = train_img.resize((128 , 128 )) \n    train_img = np.array(train_img )\n    train_img = train_img / 255. \n    mask_img = mask_img / 255. \n    return train_img , mask_img ","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:00.991322Z","iopub.execute_input":"2022-07-27T15:36:00.991756Z","iopub.status.idle":"2022-07-27T15:36:00.999117Z","shell.execute_reply.started":"2022-07-27T15:36:00.991715Z","shell.execute_reply":"2022-07-27T15:36:00.997737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Augment(tf.keras.layers.Layer) : \n    def __init__(self , seed = 42) : \n        super().__init__()\n        self.flip_inputs = tf.keras.layers.RandomFlip(mode=\"horizontal_and_vertical\", seed=seed)\n        self.flip_labels = tf.keras.layers.RandomFlip(mode=\"horizontal_and_vertical\", seed=seed)\n        self.rotate_inputs = tf.keras.layers.RandomRotation(.2 , seed=seed)\n        self.rotate_labels = tf.keras.layers.RandomRotation(.2 , seed = seed)\n    def call(self , inputs , labels)  :\n        X = self.flip_inputs(inputs)\n        y = self.flip_labels(labels)\n        X = self.rotate_inputs(X)\n        y = self.rotate_labels(y)\n        return X  , y \n        ","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:03.195030Z","iopub.execute_input":"2022-07-27T15:36:03.195502Z","iopub.status.idle":"2022-07-27T15:36:03.597943Z","shell.execute_reply.started":"2022-07-27T15:36:03.195459Z","shell.execute_reply":"2022-07-27T15:36:03.596910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = dataset.map(lambda x , y : tf.py_function(preprocess, [x , y], [tf.float32 , tf.float32]))","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:07.806547Z","iopub.execute_input":"2022-07-27T15:36:07.807601Z","iopub.status.idle":"2022-07-27T15:36:07.867880Z","shell.execute_reply.started":"2022-07-27T15:36:07.807546Z","shell.execute_reply":"2022-07-27T15:36:07.866879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = dataset.cache().shuffle(200).batch(4).map(Augment()).prefetch(2)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:25.689833Z","iopub.execute_input":"2022-07-27T15:36:25.690330Z","iopub.status.idle":"2022-07-27T15:36:26.427835Z","shell.execute_reply.started":"2022-07-27T15:36:25.690284Z","shell.execute_reply":"2022-07-27T15:36:26.426526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = dataset.take(34)\nval_dataset  = dataset.skip(34)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:28.478586Z","iopub.execute_input":"2022-07-27T15:36:28.479587Z","iopub.status.idle":"2022-07-27T15:36:28.485386Z","shell.execute_reply.started":"2022-07-27T15:36:28.479547Z","shell.execute_reply":"2022-07-27T15:36:28.484000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = tf.keras.applications.MobileNetV2(input_shape=[128, 128, 3], include_top=False)\n\n# Use the activations of these layers\nlayer_names = [\n    'block_1_expand_relu',   # 64x64\n    'block_3_expand_relu',   # 32x32\n    'block_6_expand_relu',   # 16x16\n    'block_13_expand_relu',  # 8x8\n    'block_16_project',      # 4x4\n]\nbase_model_outputs = [base_model.get_layer(name).output for name in layer_names]\n\n# Create the feature extraction model\ndown_stack = tf.keras.Model(inputs=base_model.input, outputs=base_model_outputs)\n\ndown_stack.trainable = False","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:31.356750Z","iopub.execute_input":"2022-07-27T15:36:31.357222Z","iopub.status.idle":"2022-07-27T15:36:32.719698Z","shell.execute_reply.started":"2022-07-27T15:36:31.357180Z","shell.execute_reply":"2022-07-27T15:36:32.718580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class conv_block(tf.keras.Model) : \n    def __init__(self , n_filters) :\n        super(conv_block , self).__init__()\n        self.conv_1 = tf.keras.layers.Conv2D(n_filters , (3,3) , padding='same' , activation ='relu')\n        self.conv_2 = tf.keras.layers.Conv2D(n_filters , (3,3) , padding='same' , activation ='relu')\n        self.pooling = tf.keras.layers.MaxPooling2D((2,2)) \n    def call(self , inputs , max_pooling = True ): \n        X = self.conv_1(inputs) \n        X_2 = self.conv_2(X)\n        if max_pooling : \n            pool = self.pooling(X_2)\n            return  pool , X_2 # we return X_2 to use it as connection skip to the decoder\n        else : \n            return X_2","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:32.786612Z","iopub.execute_input":"2022-07-27T15:36:32.787785Z","iopub.status.idle":"2022-07-27T15:36:32.797232Z","shell.execute_reply.started":"2022-07-27T15:36:32.787733Z","shell.execute_reply":"2022-07-27T15:36:32.796042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class conv_transpose_block(tf.keras.Model): \n    def __init__(self , n_filters) : \n        super(conv_transpose_block , self).__init__()\n        self.conv_t1 = tf.keras.layers.Conv2DTranspose(n_filters , (3,3) , strides=(2,2) , activation='relu' , padding ='same')\n        self.concat = tf.keras.layers.Concatenate()\n        self.conv_block = conv_block(n_filters)\n    def call(self, inputs ) : \n        previous_out , skip_connection = inputs \n        X = self.conv_t1(previous_out)\n        X = self.concat([X , skip_connection])\n        X = self.conv_block(X, max_pooling =False)\n        return X","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:33.422512Z","iopub.execute_input":"2022-07-27T15:36:33.422924Z","iopub.status.idle":"2022-07-27T15:36:33.431436Z","shell.execute_reply.started":"2022-07-27T15:36:33.422892Z","shell.execute_reply":"2022-07-27T15:36:33.430424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"up_sample = [\n    conv_transpose_block(512) , \n    conv_transpose_block(256) , \n    conv_transpose_block(128) , \n    conv_transpose_block(64)\n    \n]","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:34.410338Z","iopub.execute_input":"2022-07-27T15:36:34.411470Z","iopub.status.idle":"2022-07-27T15:36:34.459215Z","shell.execute_reply.started":"2022-07-27T15:36:34.411425Z","shell.execute_reply":"2022-07-27T15:36:34.458233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def unet_model(output_channels:int):\n    inputs = tf.keras.layers.Input(shape=[128, 128, 3])\n\n  # Downsampling through the model\n    skips = down_stack(inputs)\n    x = skips[-1]\n    skips = reversed(skips[:-1])\n    \n    \n  # Upsampling and establishing the skip connections\n    for up, skip in zip(up_sample, skips):\n        x = up((x , skip))\n        \n  # This is the last layer of the model\n    last = tf.keras.layers.Conv2DTranspose(\n      filters=output_channels, kernel_size=3, strides=2,\n      padding='same')  #64x64 -> 128x128\n\n    x = last(x)\n\n    return tf.keras.Model(inputs=inputs, outputs=x)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:36.228396Z","iopub.execute_input":"2022-07-27T15:36:36.228885Z","iopub.status.idle":"2022-07-27T15:36:36.237594Z","shell.execute_reply.started":"2022-07-27T15:36:36.228843Z","shell.execute_reply":"2022-07-27T15:36:36.236687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = unet_model(output_channels=1)\nmodel.compile(optimizer='adam',\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:38.683338Z","iopub.execute_input":"2022-07-27T15:36:38.684124Z","iopub.status.idle":"2022-07-27T15:36:39.490494Z","shell.execute_reply.started":"2022-07-27T15:36:38.684083Z","shell.execute_reply":"2022-07-27T15:36:39.489403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 20\n\nmodel_history = model.fit(train_dataset, epochs=EPOCHS,\n                          validation_data=val_dataset)","metadata":{"execution":{"iopub.status.busy":"2022-07-27T15:36:40.963077Z","iopub.execute_input":"2022-07-27T15:36:40.963497Z","iopub.status.idle":"2022-07-27T15:40:40.807712Z","shell.execute_reply.started":"2022-07-27T15:36:40.963465Z","shell.execute_reply":"2022-07-27T15:40:40.794193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}