{"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)\nfrom zipfile import ZipFile\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\n#  Extract data\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        file_path = os.path.join(dirname, filename)\n        os.makedirs('/kaggle/working/'+filename[:-4])\n        \n        with ZipFile(file_path, 'r') as zip:\n            print(f'Extracting all the files in: {filename}')\n            zip.extractall('/kaggle/working/'+filename[:-4])\n        \n\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-03-02T00:41:24.401229Z","iopub.execute_input":"2022-03-02T00:41:24.40186Z","iopub.status.idle":"2022-03-02T00:41:35.518467Z","shell.execute_reply.started":"2022-03-02T00:41:24.401824Z","shell.execute_reply":"2022-03-02T00:41:35.517698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:40:59.746626Z","iopub.status.idle":"2022-03-02T00:40:59.747233Z","shell.execute_reply.started":"2022-03-02T00:40:59.746983Z","shell.execute_reply":"2022-03-02T00:40:59.747008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport random\nimport numpy as np\n \nfrom tqdm import tqdm \n\nfrom skimage.io import imread, imshow\nfrom skimage.transform import resize\nfrom skimage.color import label2rgb, rgb2gray\nfrom sklearn.model_selection import train_test_split\n\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nfrom tensorflow.math import reduce_sum, reduce_mean, round\n\n# Constants\nseed = 42\nnp.random.seed = seed\n\nIMG_WIDTH = 512\nIMG_HEIGHT = 512\nIMG_CHANNELS = 3\n\nTRAIN_PATH = 'stage1_train/'\nTEST_PATH = 'stage1_test/'\n","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:41:35.519986Z","iopub.execute_input":"2022-03-02T00:41:35.520254Z","iopub.status.idle":"2022-03-02T00:41:35.529333Z","shell.execute_reply.started":"2022-03-02T00:41:35.52022Z","shell.execute_reply":"2022-03-02T00:41:35.528507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls stage1_train/00071198d059ba7f5914a526d124d28e6d010c92466da21d4a04cd5413362552/images","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:40:59.750149Z","iopub.status.idle":"2022-03-02T00:40:59.75073Z","shell.execute_reply.started":"2022-03-02T00:40:59.750489Z","shell.execute_reply":"2022-03-02T00:40:59.750513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def list_images(folder, extension=\".png\"):\n    image_paths = []\n    for root, dir, files in os.walk(folder):\n      for file in files:\n        if file.endswith(extension):\n            image_paths.append(os.path.join(root, file))\n    return image_paths","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:41:35.530876Z","iopub.execute_input":"2022-03-02T00:41:35.531209Z","iopub.status.idle":"2022-03-02T00:41:35.537057Z","shell.execute_reply.started":"2022-03-02T00:41:35.531174Z","shell.execute_reply":"2022-03-02T00:41:35.536211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ids = next(os.walk(TRAIN_PATH))[1]\ntest_ids = next(os.walk(TEST_PATH))[1]\n\nX_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.float)\nY_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, 1), dtype=np.bool)\n\n# Resizing training images and masks\nfor n, id_ in tqdm(enumerate(train_ids), total=len(train_ids)):   \n    path = TRAIN_PATH + id_\n    img = imread(path + '/images/' + id_ + '.png')[:,:,:IMG_CHANNELS]  \n    img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant')\n    X_train[n] = img  \n    mask = np.zeros((IMG_HEIGHT, IMG_WIDTH, 1), dtype=np.bool)\n    for mask_file in next(os.walk(path + '/masks/'))[2]:\n        mask_ = imread(path + '/masks/' + mask_file)\n        mask_ = np.expand_dims(resize(mask_, (IMG_HEIGHT, IMG_WIDTH), mode='constant'), axis=-1)\n        mask = np.maximum(mask, mask_)  \n            \n    Y_train[n] = mask   \n\n# Resizing test images\nX_test = np.zeros((len(test_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.float)\nsizes_test = []\nfor n, id_ in tqdm(enumerate(test_ids), total=len(test_ids)):\n    path = TEST_PATH + id_\n    img = imread(path + '/images/' + id_ + '.png')[:,:,:IMG_CHANNELS]\n    sizes_test.append([img.shape[0], img.shape[1]])\n    img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant')\n    X_test[n] = img\n\n    ","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:41:37.108454Z","iopub.execute_input":"2022-03-02T00:41:37.108728Z","iopub.status.idle":"2022-03-02T00:52:17.821877Z","shell.execute_reply.started":"2022-03-02T00:41:37.108697Z","shell.execute_reply":"2022-03-02T00:52:17.82112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize a random image in train set with mask\n# i = random.randint(0, len(train_ids))\n# print(i)\ni = 450\n\nfig, axes = plt.subplots(nrows=1, ncols=3, figsize=(25,25), sharex=True, sharey=True)\n\naxes[0].set_title('Original')\naxes[0].imshow(X_train[i])\n# axes[0].set_axis_off()\n\naxes[1].set_title('Mask')\naxes[1].imshow(np.squeeze(Y_train[i]))\n# axes[1].set_axis_off()\n\ngray_scaled_image = rgb2gray(X_train[i])\ngray_scaled_mask = rgb2gray(np.squeeze(Y_train[i]))\n\nlabeled_image = label2rgb(gray_scaled_mask, image=gray_scaled_image, bg_label=0, colors=['red'])\naxes[2].set_title('Labeled')\naxes[2].imshow(labeled_image, vmin=0, vmax=1)\n","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:52:17.826825Z","iopub.execute_input":"2022-03-02T00:52:17.829098Z","iopub.status.idle":"2022-03-02T00:52:18.620211Z","shell.execute_reply.started":"2022-03-02T00:52:17.829041Z","shell.execute_reply":"2022-03-02T00:52:18.619575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train Validation split\nX_train, X_test, y_train, y_test = train_test_split(X_train, Y_train, test_size=0.20, random_state=42)\nX_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.20, random_state=42)\n\nprint(f'Train image set shape: {X_train.shape}')\nprint(f'Validation image set shape: {X_val.shape}')\nprint(f'Test image set shape: {X_test.shape}')\nprint(f'Train mask set shape: {y_train.shape}')\nprint(f'Validation mask set shape: {y_val.shape}')\nprint(f'Test mask set shape: {y_test.shape}')","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:52:18.621215Z","iopub.execute_input":"2022-03-02T00:52:18.621437Z","iopub.status.idle":"2022-03-02T00:52:22.296805Z","shell.execute_reply.started":"2022-03-02T00:52:18.621408Z","shell.execute_reply":"2022-03-02T00:52:22.295338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.layers import Input, Lambda, Conv2D, Dropout, BatchNormalization, MaxPooling2D, Conv2DTranspose, concatenate\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, TensorBoard\n\nclass UNET:\n  def __init__(self, img_width, img_hieght, img_channels, num_filters, num_classes):\n      self.img_width = img_width\n      self.img_hieght = img_hieght\n      self.img_channels = img_channels\n      self.num_filters = num_filters\n      self.num_classes = num_classes\n\n  def __get_double_convos(self, step_input, num_filter, step_name, dropout=0.2):\n    step_output = Conv2D(num_filter, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same', name=step_name+'_layer1')(step_input)\n    step_output = Dropout(dropout, name=step_name+'_dropout')(step_output)\n    skip_connecton = Conv2D(num_filter, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same', name=step_name+'_layer2')(step_output)\n    return skip_connecton\n\n\n  def get_model(self):\n    skip_connections = []\n    inputs = Input((self.img_width, self.img_hieght, self.img_channels), name='input_layer')\n    step_input = inputs\n\n    # Contraction path\n    for index, num_filter in enumerate(self.num_filters):\n      step_name = 'down_step'+str(index)\n      skip_connecton = self.__get_double_convos(step_input, num_filter, step_name)\n      step_input = MaxPooling2D((2, 2), name=step_name+'_maxpool')(skip_connecton)\n      skip_connections.append(skip_connecton)\n\n    # Bottom step\n    bottom_num_filter = self.num_filters[-1]*2\n    bottom_step_output = self.__get_double_convos(step_input, bottom_num_filter, 'bottomstep')\n\n    skip_connections.reverse()\n    step_input = bottom_step_output\n\n    # Expansive path\n    for index, num_filter in enumerate(reversed(self.num_filters)):\n      step_name = 'up_step'+str(index)\n      up_sample = Conv2DTranspose(num_filter, (2, 2), strides=(2, 2), padding='same', name=step_name+'upsample')(step_input)\n      step_input = concatenate([up_sample, skip_connections[index]], name=step_name+'concatinate')\n      step_input = self.__get_double_convos(step_input, num_filter, step_name)\n\n    outputs = Conv2D(self.num_classes, (1, 1), activation='sigmoid', name='final_output')(step_input)\n\n    model = Model(inputs=[inputs], outputs=[outputs], name='UNET_from_scratch')\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:52:22.299041Z","iopub.execute_input":"2022-03-02T00:52:22.299315Z","iopub.status.idle":"2022-03-02T00:52:23.340556Z","shell.execute_reply.started":"2022-03-02T00:52:22.299278Z","shell.execute_reply":"2022-03-02T00:52:23.339804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unet = UNET(IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS, [16, 32, 64, 128], 1)\nmodel = unet.get_model()\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n# model.summary()\n\n#Model checkpoint\ncheckpointer = ModelCheckpoint('model_for_nuclei.h5', verbose=1, save_best_only=True)\n\ncallbacks = [\n    EarlyStopping(patience=10, monitor='val_loss'),\n    TensorBoard(log_dir='logs'),\n    checkpointer\n]\n\nresults = model.fit(X_train, y_train, validation_data=(X_val, y_val), batch_size=32, epochs=100, callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:52:23.341715Z","iopub.execute_input":"2022-03-02T00:52:23.341978Z","iopub.status.idle":"2022-03-02T01:01:38.249669Z","shell.execute_reply.started":"2022-03-02T00:52:23.341944Z","shell.execute_reply":"2022-03-02T01:01:38.248985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(X_test, y_test, batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T01:01:38.251277Z","iopub.execute_input":"2022-03-02T01:01:38.251674Z","iopub.status.idle":"2022-03-02T01:01:55.872055Z","shell.execute_reply.started":"2022-03-02T01:01:38.251638Z","shell.execute_reply":"2022-03-02T01:01:55.871419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model.predict(X_test)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T01:01:55.873373Z","iopub.execute_input":"2022-03-02T01:01:55.873623Z","iopub.status.idle":"2022-03-02T01:01:57.831487Z","shell.execute_reply.started":"2022-03-02T01:01:55.87359Z","shell.execute_reply":"2022-03-02T01:01:57.830657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dice = binary_dice_coef(y_test, y_pred)\nprint(dice)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T01:01:57.832836Z","iopub.execute_input":"2022-03-02T01:01:57.833143Z","iopub.status.idle":"2022-03-02T01:01:57.906528Z","shell.execute_reply.started":"2022-03-02T01:01:57.833108Z","shell.execute_reply":"2022-03-02T01:01:57.90559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_history_graphs(results)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T01:01:57.90758Z","iopub.status.idle":"2022-03-02T01:01:57.909451Z","shell.execute_reply.started":"2022-03-02T01:01:57.909162Z","shell.execute_reply":"2022-03-02T01:01:57.909205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def dice_coef(y_true, y_pred, smooth=1):\n#     intersection = K.sum(y_true * y_pred, axis=[1,2,3])\n#     union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])\n#     return K.mean( (2. * intersection + smooth) / (union + smooth), axis=0)","metadata":{"execution":{"iopub.status.busy":"2022-02-11T05:40:16.776629Z","iopub.execute_input":"2022-02-11T05:40:16.777082Z","iopub.status.idle":"2022-02-11T05:40:16.785462Z","shell.execute_reply.started":"2022-02-11T05:40:16.777048Z","shell.execute_reply":"2022-02-11T05:40:16.784839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def binary_dice_coef(y_true, y_pred, smooth=1e-17):\n#     y_pred = tf.squeeze(y_pred)\n    y_true = tf.cast(y_true, dtype=tf.float32)\n    y_pred = tf.cast(y_pred, dtype=tf.float32)\n\n    intersection = reduce_sum(y_true * y_pred)\n    absolute_sum = reduce_sum(y_true) + reduce_sum(y_pred)\n\n    dice = ( 2 * intersection + smooth ) / ( absolute_sum + smooth )\n\n    return dice\n\n\ndef binary_dice_coef_loss(y_true, y_pred):\n    return 1-binary_dice_coef(y_true, y_pred)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:00:06.67836Z","iopub.execute_input":"2022-03-02T00:00:06.678617Z","iopub.status.idle":"2022-03-02T00:00:06.689446Z","shell.execute_reply.started":"2022-03-02T00:00:06.678582Z","shell.execute_reply":"2022-03-02T00:00:06.687862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training on Dice Coef","metadata":{}},{"cell_type":"code","source":"unet = UNET(IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS, [16, 32, 64, 128], 1)\nmodel_dice = unet.get_model()\nmodel_dice.compile(optimizer='adam', loss=binary_dice_coef_loss, metrics=[binary_dice_coef, 'accuracy'])\n# model.summary()\n\n#Model Training\ncheckpointer = ModelCheckpoint('model_for_nuclei_dice.h5', verbose=1, save_best_only=True)\n\ncallbacks = [\n    EarlyStopping(patience=10, monitor='val_loss'),\n    TensorBoard(log_dir='logs'),\n    checkpointer\n]\n\nresults = model_dice.fit(X_train, y_train, validation_data=(X_val, y_val), batch_size=16, epochs=100, callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:25:34.417314Z","iopub.execute_input":"2022-03-02T00:25:34.417737Z","iopub.status.idle":"2022-03-02T00:34:03.674937Z","shell.execute_reply.started":"2022-03-02T00:25:34.4177Z","shell.execute_reply":"2022-03-02T00:34:03.674178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_dice.evaluate(X_test, y_test, batch_size=16)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:34:03.676957Z","iopub.execute_input":"2022-03-02T00:34:03.677498Z","iopub.status.idle":"2022-03-02T00:35:03.355324Z","shell.execute_reply.started":"2022-03-02T00:34:03.677458Z","shell.execute_reply":"2022-03-02T00:35:03.354646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = model_dice.predict(X_test)\nbinary_dice_coef(y_test, y_pred)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:35:03.356524Z","iopub.execute_input":"2022-03-02T00:35:03.356861Z","iopub.status.idle":"2022-03-02T00:35:05.970362Z","shell.execute_reply.started":"2022-03-02T00:35:03.35681Z","shell.execute_reply":"2022-03-02T00:35:05.969687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_history_graphs(results):\n    # summarize history for accuracy\n    plt.plot(results.history['accuracy'])\n    plt.plot(results.history['val_accuracy'])\n    plt.title('model accuracy')\n    plt.ylabel('accuracy')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()\n\n    # summarize history for loss\n    plt.plot(results.history['loss'])\n    plt.plot(results.history['val_loss'])\n    plt.title('model loss')\n    plt.ylabel('loss')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:41:08.752982Z","iopub.execute_input":"2022-03-02T00:41:08.753312Z","iopub.status.idle":"2022-03-02T00:41:08.761997Z","shell.execute_reply.started":"2022-03-02T00:41:08.753277Z","shell.execute_reply":"2022-03-02T00:41:08.760918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_history_graphs(results)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:35:05.980277Z","iopub.execute_input":"2022-03-02T00:35:05.980729Z","iopub.status.idle":"2022-03-02T00:35:06.518574Z","shell.execute_reply.started":"2022-03-02T00:35:05.980689Z","shell.execute_reply":"2022-03-02T00:35:06.517888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}