{"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\n\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\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-02-11T08:42:05.511898Z","iopub.execute_input":"2022-02-11T08:42:05.512734Z","iopub.status.idle":"2022-02-11T08:42:05.535534Z","shell.execute_reply.started":"2022-02-11T08:42:05.512612Z","shell.execute_reply":"2022-02-11T08:42:05.53479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## This is a notebook to utilize kaggle GPU to train U-Net model. Main code can be found in my private github repo","metadata":{}},{"cell_type":"code","source":"pip install segmentation-models","metadata":{"execution":{"iopub.status.busy":"2022-02-11T08:42:05.537209Z","iopub.execute_input":"2022-02-11T08:42:05.537496Z","iopub.status.idle":"2022-02-11T08:42:15.276258Z","shell.execute_reply.started":"2022-02-11T08:42:05.53746Z","shell.execute_reply":"2022-02-11T08:42:15.275335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# importing libraries\nimport os\nimport numpy as np\nimport pandas as pd \nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport pickle\n%matplotlib inline\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import backend as K\nfrom keras.losses import binary_crossentropy\nimport segmentation_models as sm\nfrom segmentation_models.losses import binary_focal_loss, binary_crossentropy\nfrom segmentation_models.metrics import f1_score\nfrom skimage import exposure\nsm.set_framework('tf.keras')","metadata":{"execution":{"iopub.status.busy":"2022-02-11T08:42:15.277972Z","iopub.execute_input":"2022-02-11T08:42:15.278226Z","iopub.status.idle":"2022-02-11T08:42:21.359487Z","shell.execute_reply.started":"2022-02-11T08:42:15.27819Z","shell.execute_reply":"2022-02-11T08:42:21.35872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Declare constants","metadata":{}},{"cell_type":"code","source":"SEED = 2022\n\n# Path variables\nTRAIN_DF_PATH = '../input/train-dataframe/training_dataframe.csv'\nTRAIN_IMAGES_PATH = '../input/airbus-ship-detection/train_v2/'\n#TRAIN_MASKS_PATH = '../input/airbusmasks/masks_v2/'\nTRAIN_MASKS_PATH = '../input/airbusmasks-grayscale/masks_v2/'\nTEST_IMAGES_PATH = '../input/airbus-ship-detection/test_v2/'\n\n# Image config\nORIG_IMG_WIDTH = 768\nORIG_IMG_HEIGHT = 768\nIMG_WIDTH = 256\nIMG_HEIGHT = 256\nN_CHANNELS = 3\n\n# Model variables\nBATCH_SIZE = 10\nTRAIN_SAMPLES = 4000\nVALID_SAMPLES = 1000\n# sigmoid if binary, softmax if multiclass\nACTIVATION = \"sigmoid\"\nBACKBONE = \"mobilenetv2\" \nLEARNING_RATE = 0.0003","metadata":{"execution":{"iopub.status.busy":"2022-02-11T08:42:21.361612Z","iopub.execute_input":"2022-02-11T08:42:21.361815Z","iopub.status.idle":"2022-02-11T08:42:21.372152Z","shell.execute_reply.started":"2022-02-11T08:42:21.361791Z","shell.execute_reply":"2022-02-11T08:42:21.371005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Data loading and augmentation","metadata":{}},{"cell_type":"markdown","source":"Image preprocessing function","metadata":{}},{"cell_type":"code","source":"# def contrast_stretch(img):\n#     p1, p99 = np.percentile(img, (0.1, 99.9))\n#     img_rescale = exposure.rescale_intensity(img, in_range=(p1, p99))\n    \n#     return img_rescale","metadata":{"execution":{"iopub.status.busy":"2022-02-11T08:42:21.373101Z","iopub.execute_input":"2022-02-11T08:42:21.373289Z","iopub.status.idle":"2022-02-11T08:42:21.383877Z","shell.execute_reply.started":"2022-02-11T08:42:21.37326Z","shell.execute_reply":"2022-02-11T08:42:21.383067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load data from training_dataframe.csv\ntrain_df = pd.read_csv(TRAIN_DF_PATH)\n\n# we create two instances with arguments\nimage_gen_args = dict(rescale=1. / 255,\n                rotation_range=90,\n                horizontal_flip=True,\n                vertical_flip=True,\n                zoom_range=0.1,\n                validation_split=0.2\n                )\n#                 preprocessing_function=contrast_stretch\nimage_datagen = ImageDataGenerator(**image_gen_args)\n\nmask_gen_args = dict(rescale=1. / 255,\n                rotation_range=90,\n                horizontal_flip=True,\n                vertical_flip=True,\n                zoom_range=0.1,\n                validation_split=0.2\n                )\n\nmask_datagen = ImageDataGenerator(**mask_gen_args)\n\n\n# Create training data generators\ndef create_train_generator():\n    train_image_gen = image_datagen.flow_from_dataframe(dataframe=train_df,\n                                                        directory=TRAIN_IMAGES_PATH,\n                                                        x_col='ImageId',\n                                                        class_mode=None,\n                                                        target_size=(IMG_WIDTH, IMG_HEIGHT),\n                                                        batch_size=BATCH_SIZE,\n                                                        subset='training',\n                                                        shuffle=False,\n                                                        seed=SEED)\n\n    train_mask_gen = mask_datagen.flow_from_dataframe(dataframe=train_df,\n                                                      directory=TRAIN_MASKS_PATH,\n                                                      x_col='ImageId',\n                                                      class_mode=None,\n                                                      target_size=(IMG_WIDTH, IMG_HEIGHT),\n                                                      batch_size=BATCH_SIZE,\n                                                      subset='training',\n                                                      shuffle=False,\n                                                      color_mode='grayscale',\n                                                      seed=SEED)\n\n    train_generator = zip(train_image_gen, train_mask_gen)\n\n    return train_generator\n\n\n# Create validation data generators\ndef create_validation_generator():\n    valid_image_gen = image_datagen.flow_from_dataframe(dataframe=train_df,\n                                                        directory=TRAIN_IMAGES_PATH,\n                                                        x_col='ImageId',\n                                                        class_mode=None,\n                                                        target_size=(IMG_WIDTH, IMG_HEIGHT),\n                                                        batch_size=BATCH_SIZE,\n                                                        subset='validation',\n                                                        shuffle=False,\n                                                        seed=SEED)\n\n    valid_masks_gen = mask_datagen.flow_from_dataframe(dataframe=train_df,\n                                                        directory=TRAIN_MASKS_PATH,\n                                                        x_col='ImageId',\n                                                        class_mode=None,\n                                                        target_size=(IMG_WIDTH, IMG_HEIGHT),\n                                                        batch_size=BATCH_SIZE,\n                                                        subset='validation',\n                                                        color_mode='grayscale',\n                                                        shuffle=False,\n                                                        seed=SEED)\n\n    valid_generator = zip(valid_image_gen, valid_masks_gen)\n\n    return valid_generator\n\n\n# Create test data generators\ndef create_test_generator():\n    test_datagen = ImageDataGenerator(rescale=1. / 255)\n\n    test_generator = test_datagen.flow_from_directory(directory='../input/airbus-ship-detection/',\n                                                      classes=['test_v2'],\n                                                      batch_size=1, # 1\n                                                      seed=SEED,\n                                                      shuffle=True,\n                                                      target_size=(IMG_WIDTH, IMG_HEIGHT)\n                                                      )\n\n    return test_generator","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:48:24.076208Z","iopub.execute_input":"2022-02-11T10:48:24.076547Z","iopub.status.idle":"2022-02-11T10:48:24.100086Z","shell.execute_reply.started":"2022-02-11T10:48:24.076511Z","shell.execute_reply":"2022-02-11T10:48:24.099299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Utility functions","metadata":{}},{"cell_type":"code","source":"def rle_decode(mask_rle, shape=(ORIG_IMG_WIDTH, ORIG_IMG_HEIGHT)):\n    \"\"\"\n    mask_rle: run-length as string formatted (start length)\n    shape: (height,width) of array to return\n    Returns numpy array, 1 - mask, 0 - background\n    \"\"\"\n    # returns empty mask if row has no data\n    if not isinstance(mask_rle, str):\n        img = np.zeros(shape[0] * shape[1], dtype=np.uint8)\n        return img.reshape(shape).T\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).T","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:48:28.658806Z","iopub.execute_input":"2022-02-11T10:48:28.659064Z","iopub.status.idle":"2022-02-11T10:48:28.667534Z","shell.execute_reply.started":"2022-02-11T10:48:28.659037Z","shell.execute_reply":"2022-02-11T10:48:28.666696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Define metrics","metadata":{}},{"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_predict):\n    return (1-dice_coef(y_true, y_predict))\n","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:48:30.25211Z","iopub.execute_input":"2022-02-11T10:48:30.252388Z","iopub.status.idle":"2022-02-11T10:48:30.25819Z","shell.execute_reply.started":"2022-02-11T10:48:30.252357Z","shell.execute_reply":"2022-02-11T10:48:30.257196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### U-Net model","metadata":{}},{"cell_type":"code","source":"\ndef train_model():\n    train_gen = create_train_generator()\n    valid_gen = create_validation_generator()\n    model = sm.Unet(BACKBONE, \n                    input_shape=(IMG_WIDTH, IMG_HEIGHT, 3), \n                    classes=1, \n                    encoder_weights='imagenet', \n                    activation=ACTIVATION)\n\n    model.compile(optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE),\n                  loss=binary_crossentropy,\n                  metrics=[f1_score])\n\n    # keras.callbacks\n    callbacks = [\n        tf.keras.callbacks.ModelCheckpoint('best_mobnetv2.h5',\n                                           save_best_only=True,\n                                           monitor='val_f1-score',\n                                           mode='max'),\n        tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', \n                                             mode='min', \n                                             factor=0.2, \n                                             patience=2, \n                                             min_lr=0.000005, \n                                             verbose=1)\n    ]\n\n    train_step_size = TRAIN_SAMPLES // BATCH_SIZE\n    valid_step_size = VALID_SAMPLES // BATCH_SIZE\n\n    result = model.fit_generator(generator=train_gen,\n                                 validation_data=valid_gen,\n                                 validation_steps=valid_step_size,\n                                 epochs=30,\n                                 steps_per_epoch=train_step_size,\n                                 verbose=1,\n                                 callbacks=[callbacks])\n    \n    return result","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:48:31.26443Z","iopub.execute_input":"2022-02-11T10:48:31.265177Z","iopub.status.idle":"2022-02-11T10:48:31.274244Z","shell.execute_reply.started":"2022-02-11T10:48:31.265127Z","shell.execute_reply":"2022-02-11T10:48:31.273527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = train_model()","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:48:37.350219Z","iopub.execute_input":"2022-02-11T10:48:37.350699Z","iopub.status.idle":"2022-02-11T12:23:18.422088Z","shell.execute_reply.started":"2022-02-11T10:48:37.350663Z","shell.execute_reply":"2022-02-11T12:23:18.421325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Plot training and validation results","metadata":{}},{"cell_type":"code","source":"with open('trainHistoryDict', 'wb') as file_pi:\n    pickle.dump(model.history, file_pi)","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:19:37.258959Z","iopub.execute_input":"2022-02-11T10:19:37.260487Z","iopub.status.idle":"2022-02-11T10:19:37.265363Z","shell.execute_reply.started":"2022-02-11T10:19:37.260443Z","shell.execute_reply":"2022-02-11T10:19:37.264443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(model.history.keys())\n# summarize history for f1-score\nplt.plot(model.history['f1-score'])\nplt.plot(model.history['val_f1-score'])\nplt.title('model f1-score (dice score)')\nplt.ylabel('f1-score')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper left')\nplt.show()\n# summarize history for loss\nplt.plot(model.history['loss'])\nplt.plot(model.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper right')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-11T12:24:35.951161Z","iopub.execute_input":"2022-02-11T12:24:35.95177Z","iopub.status.idle":"2022-02-11T12:24:36.323809Z","shell.execute_reply.started":"2022-02-11T12:24:35.951729Z","shell.execute_reply":"2022-02-11T12:24:36.323147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_gen = create_validation_generator()\n","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:19:37.658012Z","iopub.execute_input":"2022-02-11T10:19:37.658533Z","iopub.status.idle":"2022-02-11T10:19:43.32213Z","shell.execute_reply.started":"2022-02-11T10:19:37.658493Z","shell.execute_reply":"2022-02-11T10:19:43.321389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss, metric = model.model.evaluate_generator(valid_gen, verbose=1, steps=200)","metadata":{"execution":{"iopub.status.busy":"2022-02-11T12:25:54.841896Z","iopub.execute_input":"2022-02-11T12:25:54.842381Z","iopub.status.idle":"2022-02-11T12:27:01.511439Z","shell.execute_reply.started":"2022-02-11T12:25:54.842343Z","shell.execute_reply":"2022-02-11T12:27:01.510708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_gen = create_test_generator()","metadata":{"execution":{"iopub.status.busy":"2022-02-11T10:42:20.425198Z","iopub.execute_input":"2022-02-11T10:42:20.425757Z","iopub.status.idle":"2022-02-11T10:42:24.827115Z","shell.execute_reply.started":"2022-02-11T10:42:20.425719Z","shell.execute_reply":"2022-02-11T10:42:24.82637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = model.model.predict_generator(test_gen, steps=1, verbose=1)\ntest = test > 0.5","metadata":{"execution":{"iopub.status.busy":"2022-02-11T12:25:41.401127Z","iopub.execute_input":"2022-02-11T12:25:41.401833Z","iopub.status.idle":"2022-02-11T12:25:41.5071Z","shell.execute_reply.started":"2022-02-11T12:25:41.401793Z","shell.execute_reply":"2022-02-11T12:25:41.506417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = np.squeeze(test, axis=0)","metadata":{"execution":{"iopub.status.busy":"2022-02-11T12:25:41.527701Z","iopub.execute_input":"2022-02-11T12:25:41.527929Z","iopub.status.idle":"2022-02-11T12:25:41.533274Z","shell.execute_reply.started":"2022-02-11T12:25:41.527902Z","shell.execute_reply":"2022-02-11T12:25:41.532479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure()\nplt.imshow(test) \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-11T12:25:41.671884Z","iopub.execute_input":"2022-02-11T12:25:41.672438Z","iopub.status.idle":"2022-02-11T12:25:41.842778Z","shell.execute_reply.started":"2022-02-11T12:25:41.672401Z","shell.execute_reply":"2022-02-11T12:25:41.842095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}