{"cells":[{"metadata":{"trusted":true,"_uuid":"b1ac5a04323ef2252902e91408926e90bdd545aa"},"cell_type":"code","source":"import os,sys,random,warnings\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\n\nfrom tqdm import tqdm\nfrom itertools import chain\n\nfrom skimage.morphology import label\nfrom skimage.transform import resize\nfrom skimage.io import imread,imshow,imread_collection,concatenate_images\n\nfrom keras.models import Sequential,Input,Model,load_model\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.utils.vis_utils import plot_model\nfrom IPython.display import SVG\nfrom keras.layers import Input\nfrom keras.layers import Dropout,Lambda,Conv2D,Conv2DTranspose,MaxPooling2D,concatenate,SeparableConv2D\nfrom keras.layers import Dense,Flatten,Dropout,Concatenate,GlobalAveragePooling2D\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.optimizers import Adam,SGD\nfrom keras.utils.vis_utils import plot_model\nfrom keras.callbacks import ModelCheckpoint,EarlyStopping,TensorBoard,CSVLogger,ReduceLROnPlateau,LearningRateScheduler\nfrom keras import backend as K","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1ea13a9e337f1f7a2c695d8aef48157abfe9d2e3"},"cell_type":"code","source":"def run_length_encoding(x):\n    dots = np.where(x.T.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return run_lengths\n\ndef prob_to_rles(x, cutoff=0.5):\n    lab_img = label(x > cutoff)\n    for i in range(1, lab_img.max() + 1):\n        yield run_length_encoding(lab_img == i)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8e08fb996024ae0140494fa0128fe200a2916784"},"cell_type":"code","source":"def show_final_history(history):\n    fig, ax = plt.subplots(1, 2, figsize=(15,5))\n    ax[0].set_title('loss')\n    ax[0].plot(history.epoch, history.history[\"loss\"], label=\"Train loss\")\n    ax[0].plot(history.epoch, history.history[\"val_loss\"], label=\"Validation loss\")\n    ax[1].set_title('iou')\n    ax[1].plot(history.epoch, history.history[\"iou\"], label=\"Train iou\")\n    ax[1].plot(history.epoch, history.history[\"val_iou\"], label=\"Validation iou\")\n    ax[0].legend()\n    ax[1].legend()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"79593bcf6d804b289860ec1e8d2ed82972b37e74"},"cell_type":"code","source":"def iou(y_true, y_pred):\n    prec = []\n    for t in np.arange(0.5, 1.0, 0.05):\n        y_pred_ = tf.to_int32(y_pred > t)\n        score, up_opt = tf.metrics.mean_iou(y_true, y_pred_, 2)\n        K.get_session().run(tf.local_variables_initializer())\n        with tf.control_dependencies([up_opt]):\n            score = tf.identity(score)\n        prec.append(score)\n    return K.mean(K.stack(prec), axis=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"26554f45926c8220a822125573f625eec8a33ef8"},"cell_type":"code","source":"IMG_WIDTH = 128\nIMG_HEIGHT = 128\nIMG_CHANNELS = 3\ntrain_path = '../input/stage1_train/'\ntest_path = '../input/stage1_test/'\ntrain_ids = next(os.walk(train_path))[1]\ntest_ids = next(os.walk(test_path))[1]\nwarnings.filterwarnings('ignore', category=UserWarning, module='skimage')\nopt = SGD(lr=1e-4,momentum=0.95)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a54f6ce556c6630a3f7154823ff3d7c612fca1ba"},"cell_type":"code","source":"X_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nY_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, 1), dtype=np.bool)\nprint('Extract and Transform training images and masks')\nsys.stdout.flush()\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', preserve_range=True)\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', \n                                      preserve_range=True), axis=-1)\n        mask = np.maximum(mask, mask_)\n    Y_train[n] = mask\n\n# Get and resize test images\nX_test = np.zeros((len(test_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nsizes_test = []\nprint('Extracting and Transforming test images')\nsys.stdout.flush()\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', preserve_range=True)\n    X_test[n] = img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"23a6c14c597c8020f21ba91eee7918d7c2eef982"},"cell_type":"code","source":"inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))\ns = Lambda(lambda x: x / 255) (inputs)\n\nc1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (s)\nc1 = Dropout(0.1) (c1)\nc1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c1)\np1 = MaxPooling2D((2, 2)) (c1)\n\nc2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p1)\nc2 = Dropout(0.1) (c2)\nc2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c2)\np2 = MaxPooling2D((2, 2)) (c2)\n\nc3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p2)\nc3 = Dropout(0.2) (c3)\nc3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c3)\np3 = MaxPooling2D((2, 2)) (c3)\n\nc4 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p3)\nc4 = Dropout(0.2) (c4)\nc4 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c4)\np4 = MaxPooling2D(pool_size=(2, 2)) (c4)\n\nc5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p4)\nc5 = Dropout(0.3) (c5)\nc5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c5)\n\nu6 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same') (c5)\nu6 = concatenate([u6, c4])\nc6 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u6)\nc6 = Dropout(0.2) (c6)\nc6 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c6)\n\nu7 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (c6)\nu7 = concatenate([u7, c3])\nc7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u7)\nc7 = Dropout(0.2) (c7)\nc7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c7)\n\nu8 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c7)\nu8 = concatenate([u8, c2])\nc8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u8)\nc8 = Dropout(0.1) (c8)\nc8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c8)\n\nu9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (c8)\nu9 = concatenate([u9, c1], axis=3)\nc9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u9)\nc9 = Dropout(0.1) (c9)\nc9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c9)\n\noutputs = Conv2D(1, (1, 1), activation='sigmoid') (c9)\n\nmodel = Model(inputs=[inputs], outputs=[outputs])\nmodel.summary()\n\nSVG(model_to_dot(model).create(prog='dot', format='svg'))\nplot_model(model, to_file='model_plot.png', show_shapes=True, show_layer_names=True, expand_nested=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4d9d886f0c6e7aef1a13aa3e62ee4200567266af"},"cell_type":"code","source":"checkpoint = ModelCheckpoint(\n    './base.model',\n    monitor='val_loss',\n    verbose=1,\n    save_best_only=True,\n    mode='min',\n    save_weights_only=False,\n    period=1\n)\nearlystop = EarlyStopping(\n    monitor='val_loss',\n    min_delta=0.001,\n    patience=80,\n    verbose=1,\n    mode='auto'\n)\ntensorboard = TensorBoard(\n    log_dir = './logs',\n    histogram_freq=0,\n    batch_size=16,\n    write_graph=True,\n    write_grads=True,\n    write_images=False,\n)\n\ncsvlogger = CSVLogger(\n    filename= \"training_csv.log\",\n    separator = \",\",\n    append = False\n)\n\n#lrsched = LearningRateScheduler(step_decay,verbose=1)\n\nreduce = ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.3,\n    patience=5,\n    verbose=1, \n    mode='auto',\n    cooldown=1 \n)\n\ncallbacks = [checkpoint,tensorboard,csvlogger,reduce,earlystop]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4f87d4472434889ec4745449b5036b414d93e015","scrolled":true},"cell_type":"code","source":"opt1 = Adam(lr=3e-4)\nmodel.compile(optimizer=opt1, loss='binary_crossentropy', metrics=[iou])\n\nhistory = model.fit(X_train, Y_train, validation_split=0.1, batch_size=8, epochs=200, \n                    callbacks=callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"39ff389c598d53178206d2181324061bbb36a559"},"cell_type":"code","source":"show_final_history(history)\nprint(\"Validation Loss: \" + str(history.history['val_loss'][-1:]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bd60981719b711c46871eea1b2e3300f432170eb"},"cell_type":"code","source":"model = load_model('./base.model', custom_objects={'iou': iou})\npreds_train = model.predict(X_train[:int(X_train.shape[0]*0.9)], verbose=1)\npreds_val = model.predict(X_train[int(X_train.shape[0]*0.9):], verbose=1)\npreds_test = model.predict(X_test, verbose=1)\n\n# Threshold predictions\npreds_train_t = (preds_train > 0.5).astype(np.uint8)\npreds_val_t = (preds_val > 0.5).astype(np.uint8)\npreds_test_t = (preds_test > 0.5).astype(np.uint8)\n\n# Create list of upsampled test masks\npreds_test_upsampled = []\nfor i in range(len(preds_test)):\n    preds_test_upsampled.append(resize(np.squeeze(preds_test[i]),(sizes_test[i][0], sizes_test[i][1]), mode='constant', preserve_range=True))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4598653979a98627bd5093f30222c63b11ce8c2c"},"cell_type":"code","source":"ix = random.randint(0, len(preds_train_t))\nimshow(X_train[ix])\nplt.show()\nimshow(np.squeeze(Y_train[ix]))\nplt.show()\nimshow(np.squeeze(preds_train_t[ix]))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"97265d5b67d67e46bb91a8c125c906211b504835"},"cell_type":"code","source":"new_test_ids = []\nrles = []\nfor n, id_ in enumerate(test_ids):\n    rle = list(prob_to_rles(preds_test_upsampled[n]))\n    rles.extend(rle)\n    new_test_ids.extend([id_] * len(rle))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7dd461bcb2bab1f70e409b1c7e1a3cbb13cd975b"},"cell_type":"code","source":"sub = pd.DataFrame()\nsub['ImageId'] = new_test_ids\nsub['EncodedPixels'] = pd.Series(rles).apply(lambda x: ' '.join(str(y) for y in x))\nsub.to_csv('data_bowl_segmentation.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b776be0591c26744a911380451c7badb8133bc25"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}