{"cells":[{"metadata":{"_uuid":"1629debb33bf38e7aec59f9352a8101a0bd9d627"},"cell_type":"markdown","source":"V18: bug fix (calculation of F2 score)"},{"metadata":{"_uuid":"1b0a8a3b377172743a038bab1a2b0037fded6dfc"},"cell_type":"markdown","source":"# load packages"},{"metadata":{"trusted":true,"_uuid":"d5fde42cea10ed321db48bdbf98c2ff5bb631624"},"cell_type":"code","source":"import os\nfrom skimage.data import imread\nfrom skimage.morphology import label\nimport pandas as pd\nimport numpy as np\nfrom keras.models import *\nfrom keras.layers import *\nfrom keras.optimizers import *\nimport random\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.model_selection import train_test_split\n\ninput_dir = '../input/'\ntrain_img_dir = '../input/train_v2/'\ntest_img_dir = '../input/test_v2/'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ca11fbb4762465b3f39fc57fe7b8ea03b8364239"},"cell_type":"markdown","source":"# load train_dataframe"},{"metadata":{"trusted":true,"_uuid":"a3c704fb07cdfcb1d8222c5c120ede71cfb40a9e"},"cell_type":"code","source":"train_df = pd.read_csv(input_dir+'train_ship_segmentations_v2.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a031f04ead0c80b2e89a66a2f02a2b69cb57e15e"},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e89c185d7cda1e9cf4aa994ccbff2d149301f315","scrolled":true},"cell_type":"code","source":"train_df.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0ab0c2f514ed221ce53a002d8d0dc2c5f7a5c4ea"},"cell_type":"markdown","source":"# remove bug images"},{"metadata":{"trusted":true,"_uuid":"09cd6e559b6b2579d2cea247d264965dc2b0b46f"},"cell_type":"code","source":"train_df = train_df[train_df['ImageId'] != '6384c3e78.jpg']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1ee28ad6f073ed0f4b94da72c63d83b8be4e2765"},"cell_type":"code","source":"train_df.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"29fba13e2f013f979474f7a442050377a6594594"},"cell_type":"markdown","source":"# remove 100000 non-ship images"},{"metadata":{"trusted":true,"_uuid":"2897043641266d32ece48820784acd7dd3fc1b53"},"cell_type":"code","source":"def area_isnull(x):\n    if x == x:\n        return 0\n    else:\n        return 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bebad7619e6669ba992059d5e5ce050618353991"},"cell_type":"code","source":"train_df['isnan'] = train_df['EncodedPixels'].apply(area_isnull)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1da4e42ed00a6672284ec11c35c01f12ae1cc2cc"},"cell_type":"code","source":"train_df['isnan'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2fcfdcc32083d84aa16349e2b8161b11589a5fff"},"cell_type":"code","source":"train_df = train_df.sort_values('isnan', ascending=False)\ntrain_df = train_df.iloc[100000:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b77a9e8ccde826913db1b59e9c4442c8e659f5de"},"cell_type":"code","source":"train_df['isnan'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7dd6933eff3da6c5cc252906ea0ba62a6a6dafde"},"cell_type":"markdown","source":"# calculate ship area and group by ImageId"},{"metadata":{"trusted":true,"_uuid":"ebf3be677dccbf2355796ddc36d296c7b63553d4"},"cell_type":"code","source":"def rle_to_mask(rle_list, SHAPE):\n    tmp_flat = np.zeros(SHAPE[0]*SHAPE[1])\n    if len(rle_list) == 1:\n        mask = np.reshape(tmp_flat, SHAPE).T\n    else:\n        strt = rle_list[::2]\n        length = rle_list[1::2]\n        for i,v in zip(strt,length):\n            tmp_flat[(int(i)-1):(int(i)-1)+int(v)] = 255\n        mask = np.reshape(tmp_flat, SHAPE).T\n    return mask","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1631abfa59f902f8ba0c8d8ac0bb569839343f73"},"cell_type":"code","source":"def calc_area_for_rle(rle_str):\n    rle_list = [int(x) if x.isdigit() else x for x in str(rle_str).split()]\n    if len(rle_list) == 1:\n        return 0\n    else:\n        area = np.sum(rle_list[1::2])\n        return area","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5ff2925d082443d18bc15d3db1926f51317c9d84","scrolled":true},"cell_type":"code","source":"train_df['area'] = train_df['EncodedPixels'].apply(calc_area_for_rle)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"96d22e772c1a8a15ce4c029bb81f1457084db3bc"},"cell_type":"markdown","source":"get small area of one ship; If estimated area of the ship is less than 10, it is corrected to 0."},{"metadata":{"trusted":true,"_uuid":"c58bd7fb393a46f3e8836ca5403176f35a5a580f"},"cell_type":"code","source":"train_df_isship = train_df[train_df['area'] > 0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"09220ce4808d0e3ad6ce5b8d06292e992851c080"},"cell_type":"code","source":"train_df_isship.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"78ac5414ae6ae2e09ff71611faff6b068091a849"},"cell_type":"code","source":"train_df_smallarea = train_df_isship['area'][train_df_isship['area'] < 10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4580043aab3643b8165ff84901aba7250f315f18"},"cell_type":"code","source":"train_df_smallarea.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d5193177a2be8d075c90515f1617bc0fa38c5476"},"cell_type":"code","source":"train_df_smallarea.shape[0]/train_df_isship.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a86a48c0004a661d0c2500df5d204372a64e14e3"},"cell_type":"code","source":"train_gp = train_df.groupby('ImageId').sum()\ntrain_gp = train_gp.reset_index()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"79d82936f70a65e5a8e74adf1506c91d6d9d519f"},"cell_type":"code","source":"train_gp.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"71f5b59a92997f5e8b41e833d2f06d32bdd6b076"},"cell_type":"markdown","source":"# set class of ship area"},{"metadata":{"trusted":true,"_uuid":"2a34c342c77899db2965053a86a17f814332075f"},"cell_type":"code","source":"def calc_class(area):\n    area = area / (768*768)\n    if area == 0:\n        return 0\n    elif area < 0.005:\n        return 1\n    elif area < 0.015:\n        return 2\n    elif area < 0.025:\n        return 3\n    elif area < 0.035:\n        return 4\n    elif area < 0.045:\n        return 5\n    else:\n        return 6","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"83978353dab607e852973f2d20f1aaf33b6a1a56"},"cell_type":"code","source":"train_gp['class'] = train_gp['area'].apply(calc_class)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e6b44bff8284f678684e808c816b9b317754cc3b"},"cell_type":"code","source":"train_gp['class'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f541afa0e92409130af76771cdb85e3fe4bcc80"},"cell_type":"markdown","source":"# split train-set and validation-set (stratified: area class)"},{"metadata":{"trusted":true,"_uuid":"50ab7af05bcb118ce15f6d21e5b954c95b01b6ec"},"cell_type":"code","source":"train, val = train_test_split(train_gp, test_size=0.01, stratify=train_gp['class'].tolist())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"041674775a2408dc377c3685804dd8ef68709c57"},"cell_type":"code","source":"train_isship_list = train['ImageId'][train['isnan']==0].tolist()\ntrain_isship_list = random.sample(train_isship_list, len(train_isship_list))\ntrain_nanship_list = train['ImageId'][train['isnan']==1].tolist()\ntrain_nanship_list = random.sample(train_nanship_list, len(train_nanship_list))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b9fab1f00b65d54cbb0be5e0ec761461eda35109"},"cell_type":"code","source":"len(train_isship_list),len(train_nanship_list)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"460b800e8115caed87dc6d261d86e530482abae3"},"cell_type":"markdown","source":"# create data generator\nMake the ratio of is-ship images and nan-ship images  equal"},{"metadata":{"trusted":true,"_uuid":"dbd3143b1cce5c089a5fcab70640aeb2f7f35917"},"cell_type":"code","source":"def mygenerator(isship_list, nanship_list, batch_size, cap_num):\n    train_img_names_nanship = isship_list[:cap_num]\n    train_img_names_isship = nanship_list[:cap_num]\n    k = 0\n    while True:\n        if k+batch_size//2 >= cap_num:\n            k = 0\n        batch_img_names_nan = train_img_names_nanship[k:k+batch_size//2]\n        batch_img_names_is = train_img_names_isship[k:k+batch_size//2]\n        batch_img = []\n        batch_mask = []\n        for name in batch_img_names_nan:\n            tmp_img = imread(train_img_dir + name)\n            batch_img.append(tmp_img)\n            mask_list = train_df['EncodedPixels'][train_df['ImageId'] == name].tolist()\n            one_mask = np.zeros((768, 768, 1))\n            for item in mask_list:\n                rle_list = str(item).split()\n                tmp_mask = rle_to_mask(rle_list, (768, 768))\n                one_mask[:,:,0] += tmp_mask\n            batch_mask.append(one_mask)\n        for name in batch_img_names_is:\n            tmp_img = imread(train_img_dir + name)\n            batch_img.append(tmp_img)\n            mask_list = train_df['EncodedPixels'][train_df['ImageId'] == name].tolist()\n            one_mask = np.zeros((768, 768, 1))\n            for item in mask_list:\n                rle_list = str(item).split()\n                tmp_mask = rle_to_mask(rle_list, (768, 768))\n                one_mask[:,:,0] += tmp_mask\n            batch_mask.append(one_mask)\n        img = np.stack(batch_img, axis=0)\n        mask = np.stack(batch_mask, axis=0)\n        img = img / 255.0\n        mask = mask / 255.0\n        k += batch_size//2\n        yield img, mask","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"480a5e01e3350f83127b181ed90217c4bec0c7f2"},"cell_type":"code","source":"BATCH_SIZE = 2\nCAP_NUM = min(len(train_isship_list),len(train_nanship_list))\ndatagen = mygenerator(train_isship_list, train_nanship_list, batch_size=BATCH_SIZE, cap_num=CAP_NUM)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"103ddaa8ffbfbf2a4c6a20e30e289b14519fa5bb"},"cell_type":"markdown","source":"# set model"},{"metadata":{"trusted":true,"_uuid":"4b6b9487a40d3442c47d39d22693255bf4a5722f"},"cell_type":"code","source":"inputs = Input(shape=(768,768,3))\nconv0 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)\nconv0 = BatchNormalization()(conv0)\nconv0 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv0)\nconv0 = BatchNormalization()(conv0)\n\ncomp0 = AveragePooling2D((6,6))(conv0)\nconv1 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(comp0)\nconv1 = BatchNormalization()(conv1)\nconv1 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)\nconv1 = BatchNormalization()(conv1)\nconv1 = Dropout(0.4)(conv1)\n\npool1 = MaxPooling2D(pool_size=(2,2))(conv1)\nconv2 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)\nconv2 = BatchNormalization()(conv2)\nconv2 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)\nconv2 = BatchNormalization()(conv2)\nconv2 = Dropout(0.4)(conv2)\n\npool2 = MaxPooling2D(pool_size=(2,2))(conv2)\nconv3 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool2)\nconv3 = BatchNormalization()(conv3)\nconv3 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)\nconv3 = BatchNormalization()(conv3)\nconv3 = Dropout(0.4)(conv3)\n\npool3 = MaxPooling2D(pool_size=(2,2))(conv3)\nconv4 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool3)\nconv4 = BatchNormalization()(conv4)\nconv4 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)\nconv4 = BatchNormalization()(conv4)\nconv4 = Dropout(0.4)(conv4)\n\npool4 = MaxPooling2D(pool_size=(2,2))(conv4)\nconv5 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool4)\nconv5 = BatchNormalization()(conv5)\nconv5 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)\nconv5 = BatchNormalization()(conv5)\n\nupcv6 = UpSampling2D(size=(2,2))(conv5)\nupcv6 = Conv2D(128, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv6)\nupcv6 = BatchNormalization()(upcv6)\nmrge6 = concatenate([conv4, upcv6], axis=3)\nconv6 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge6)\nconv6 = BatchNormalization()(conv6)\nconv6 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)\nconv6 = BatchNormalization()(conv6)\n\nupcv7 = UpSampling2D(size=(2,2))(conv6)\nupcv7 = Conv2D(64, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv7)\nupcv7 = BatchNormalization()(upcv7)\nmrge7 = concatenate([conv3, upcv7], axis=3)\nconv7 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge7)\nconv7 = BatchNormalization()(conv7)\nconv7 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv7)\nconv7 = BatchNormalization()(conv7)\n\nupcv8 = UpSampling2D(size=(2,2))(conv7)\nupcv8 = Conv2D(32, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv8)\nupcv8 = BatchNormalization()(upcv8)\nmrge8 = concatenate([conv2, upcv8], axis=3)\nconv8 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge8)\nconv8 = BatchNormalization()(conv8)\nconv8 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv8)\nconv8 = BatchNormalization()(conv8)\n\nupcv9 = UpSampling2D(size=(2,2))(conv8)\nupcv9 = Conv2D(16, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv9)\nupcv9 = BatchNormalization()(upcv9)\nmrge9 = concatenate([conv1, upcv9], axis=3)\nconv9 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge9)\nconv9 = BatchNormalization()(conv9)\nconv9 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv9)\nconv9 = BatchNormalization()(conv9)\n\ndcmp10 = UpSampling2D((6,6), interpolation='bilinear')(conv9)\nmrge10 = concatenate([dcmp10, conv0], axis=3)\nconv10 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge10)\nconv10 = BatchNormalization()(conv10)\nconv10 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv10)\nconv10 = BatchNormalization()(conv10)\nconv11 = Conv2D(1, 1, activation='sigmoid')(conv10)\n\nmodel = Model(inputs=inputs, outputs=conv11)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"72167df2bd5af4e2775b33606e0d50bf04b5aeee","scrolled":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b6e3ff01b8b1239816a99efe6bfcdee2d8ca11fb","scrolled":true},"cell_type":"code","source":"model.compile(optimizer = 'adam', loss = 'binary_crossentropy')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"21ad2aaaca671e22521b7fd6e92763367dacf954"},"cell_type":"markdown","source":"# training"},{"metadata":{"trusted":true,"_uuid":"89db399ff1ae9b94d54db1f077fb5ef488c718a7"},"cell_type":"code","source":"history = model.fit_generator(datagen, steps_per_epoch = 500, epochs = 50)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9995f4c4fa4f109e3f1a549a08a51264f3012572"},"cell_type":"markdown","source":"# calculate F2 score for validation set"},{"metadata":{"_uuid":"68cfaff71251405f626de610723c87332a442d91"},"cell_type":"markdown","source":"- set  function of caluculating  score"},{"metadata":{"trusted":true,"_uuid":"042baa7e5568598511b37fcc1ffbd839d916524e"},"cell_type":"code","source":"def calc_IoU(A, B):\n    AorB = np.logical_or(A,B).astype('int')\n    AandB = np.logical_and(A,B).astype('int')\n    IoU = AandB.sum() / AorB.sum()\n    return IoU","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"155186fcb13c9998d4c141e71c8f10bdfa6c147d"},"cell_type":"code","source":"def calc_IoU_vector(A, B):\n    score_vector = []\n    IoU = calc_IoU(A, B)\n    for threshold in np.arange(0.5,1,0.05):\n        score = int(IoU > threshold)\n        score_vector.append(score)\n    return score_vector","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f56502efebd409b2eb34f2ccba96e07a6c6c7e6f"},"cell_type":"code","source":"def calc_IoU_tensor(masks_true, masks_pred):\n    true_mask_num = masks_true.shape[0]\n    pred_mask_num = masks_pred.shape[0]\n    score_tensor = np.zeros((true_mask_num, pred_mask_num, 10))\n    for true_i in range(true_mask_num):\n        for pred_i in range(pred_mask_num):\n            true_mask = masks_true[true_i]\n            pred_mask = masks_pred[pred_i]\n            score_vector = calc_IoU_vector(true_mask, pred_mask)\n            score_tensor[true_i,pred_i,:] = score_vector\n    return score_tensor","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ec3b1975edaaebef7d2e73ff484a41a1f3eec397"},"cell_type":"code","source":"def calc_F2_per_one_threshold(score_matrix):\n    tp = np.sum( score_matrix.sum(axis=1) > 0  )\n    fn = np.sum( score_matrix.sum(axis=1) == 0 )\n    fp = np.sum( score_matrix.sum(axis=0) == 0 )\n    F2 = (5*tp) / ((5*tp) + fp + (4*fn))\n    return F2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4f9843b83986ac9abf159aa3972e5aa69aebb37c"},"cell_type":"code","source":"def calc_score_one_image(mask_true, mask_pred):\n    mask_true = mask_true.reshape(768,768)\n    mask_pred = mask_pred.reshape(768,768)\n    if mask_true.sum() == 0 and mask_pred.sum() == 0:\n        score = 1\n    elif mask_true.sum() == 0 and mask_pred.sum() != 0:\n        score = 0\n    elif mask_true.sum() != 0 and mask_pred.sum() == 0:\n        score = 0\n    else:\n        mask_label_true = label(mask_true)\n        mask_label_pred = label(mask_pred)\n        c_true = np.max(mask_label_true)\n        c_pred = np.max(mask_label_pred)\n        tmp = []\n        for k in range(c_true):\n            tmp.append(mask_label_true == k+1)\n        masks_true = np.stack(tmp, axis=0)\n        tmp = []\n        for k in range(c_pred):\n            tmp.append(mask_label_pred == k+1)\n        masks_pred = np.stack(tmp, axis=0)\n        score_tensor = calc_IoU_tensor(masks_true, masks_pred)\n        F2_t = []\n        for i in range(10):\n            F2 = calc_F2_per_one_threshold(score_tensor[:,:,i])\n            F2_t.append(F2)\n        score = np.mean(F2_t)\n    return score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a36dac77afe53bfe329dbbe305767643f9a1e57f"},"cell_type":"code","source":"def calc_score_all_image(batch_mask_true, batch_mask_pred, threshold=0.5):\n    num = batch_mask_true.shape[0]\n    tmp = batch_mask_pred > threshold\n    batch_mask_pred = tmp.astype('int')\n    scores = list()\n    for i in range(num):\n        score = calc_score_one_image(batch_mask_true[i], batch_mask_pred[i])\n        scores.append(score)\n    return np.mean(scores)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fda7b099099d639a512a111d4431c58c3f1a4788"},"cell_type":"markdown","source":"- set validation data"},{"metadata":{"trusted":true,"_uuid":"993e4b6ef00a7c99af0e8a1c3c42122ff3cf832a"},"cell_type":"code","source":"val_list = val['ImageId'].tolist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ac0b96a55b1c3f3407d66768473ddeef878489be"},"cell_type":"code","source":"def create_data(image_list):\n    batch_img = []\n    batch_mask = []\n    for name in image_list:\n        tmp_img = imread(train_img_dir + name)\n        batch_img.append(tmp_img)\n        mask_list = train_df['EncodedPixels'][train_df['ImageId'] == name].tolist()\n        one_mask = np.zeros((768, 768, 1))\n        for item in mask_list:\n            rle_list = str(item).split()\n            tmp_mask = rle_to_mask(rle_list, (768, 768))\n            one_mask[:,:,0] += tmp_mask\n        batch_mask.append(one_mask)\n    img = np.stack(batch_img, axis=0)\n    mask = np.stack(batch_mask, axis=0)\n    img = img / 255.0\n    mask = mask / 255.0\n    return img, mask","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"16f578e4c9040d6f8ccf0b9805ef331e85443360"},"cell_type":"markdown","source":"- put it together and search optimal threshold"},{"metadata":{"trusted":true,"_uuid":"d3231b850835ae2a14a76210a52181dbe169734d"},"cell_type":"code","source":"from tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"72951698b0a229289bea4d4b75d33c0e4472d1cd"},"cell_type":"code","source":"#search threshold\nscores_list = dict()\nthreshold_list = [x/100 for x in range(20,80,10)]\nfor threshold in threshold_list:\n    scores = []\n    for i in tqdm(range(len(val_list)//2)):\n        temp_list = val_list[i*2:(i+1)*2]\n        val_img, val_mask = create_data(temp_list)\n        pred_mask = model.predict(val_img)\n        F2 = calc_score_all_image(val_mask, pred_mask, threshold=threshold)*2\n        scores.append(F2)\n    val_F2 = np.sum(scores)/(len(val_list)//2 *2)\n    scores_list[threshold] = val_F2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c189c29e0a3710c7c6c5dec04f781089ec29d7a8"},"cell_type":"code","source":"scores_list","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f2ef157ba4aaa035be93065855bad3b4b91941f1"},"cell_type":"code","source":"opt_threshold = max(scores_list, key=scores_list.get)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"44da6c465f5bb6f247e74d05d85e549e40c0c57a"},"cell_type":"markdown","source":"# visualize predict images\ndisplay 5 images"},{"metadata":{"trusted":true,"_uuid":"60e827ad3090b8f64e1fd039c3c179914511615b"},"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a8350045f26f0f7c3edf0eeee3be7d06916aaf6"},"cell_type":"code","source":"image_list = val_list[20:30]\nfig, axes = plt.subplots(len(image_list), 3, figsize=(5,5*len(image_list)))\nfig.subplots_adjust(left=0.075,right=0.95,bottom=0.05,top=0.52,wspace=0.2,hspace=0.10)\nfor i in range(len(image_list)):\n    img = imread(train_img_dir + image_list[i])\n    input_img, gt_mask = create_data([image_list[i]])\n    pred_mask = model.predict(input_img)\n    pred_mask = pred_mask > opt_threshold\n    pred_mask = pred_mask.reshape(768,768,1)\n    gt_mask = gt_mask * 255\n    gt_mask = gt_mask.reshape(768,768)\n    pred_mask = pred_mask.reshape(768,768)\n    axes[i, 0].imshow(img)\n    axes[i, 1].imshow(gt_mask)\n    axes[i, 2].imshow(pred_mask)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"347084c09bb0c85401e796eb7f58f9e2e73b52ed"},"cell_type":"markdown","source":"# predict test set and submission with Test Time Augmentation"},{"metadata":{"trusted":true,"_uuid":"6c77b88803cd0ff553588acdf47ff3bf7dced6ec"},"cell_type":"code","source":"test_img_names = [x.split('.')[0] for x in os.listdir(test_img_dir)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fe14489bb81d8c4aee7d8c2468105e48c8e13bad"},"cell_type":"code","source":"def multi_rle_encode(img, **kwargs):\n    '''\n    Encode connected regions as separated masks\n    '''\n    labels = label(img[0,:,:,:])\n    if img.ndim > 2:\n        return [rle_encode(np.sum(labels==k, axis=2), **kwargs) for k in np.unique(labels[labels>0])]\n    else:\n        return [rle_encode(labels==k, **kwargs) for k in np.unique(labels[labels>0])]\n\n# ref: https://www.kaggle.com/paulorzp/run-length-encode-and-decode\ndef rle_encode(img, min_max_threshold=1e-3, max_mean_threshold=None):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    if np.max(img) < min_max_threshold:\n        return '' ## no need to encode if it's all zeros\n    if max_mean_threshold and np.mean(img) > max_mean_threshold:\n        return '' ## ignore overfilled mask\n    pixels = img.T.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"739de9efa942890b48985972a28432d26415ee07"},"cell_type":"code","source":"pred_rows = []\nfor name in tqdm(test_img_names):\n    test_img = imread(test_img_dir + name + '.jpg')\n    test_img_1 = test_img.reshape(1,768,768,3)/255.0\n    test_img_2 = test_img_1[:, :, ::-1, :]\n    test_img_3 = test_img_1[:, ::-1, :, :]\n    test_img_4 = test_img_1[:, ::-1, ::-1, :]\n    pred_prob_1 = model.predict(test_img_1)\n    pred_prob_2 = model.predict(test_img_2)\n    pred_prob_3 = model.predict(test_img_3)\n    pred_prob_4 = model.predict(test_img_4)\n    pred_prob = (pred_prob_1 + pred_prob_2[:, :, ::-1, :] + pred_prob_3[:, ::-1, :, :] + pred_prob_4[:, ::-1, ::-1, :])/4\n    pred_mask = pred_prob > opt_threshold\n    rles = multi_rle_encode(pred_mask)\n    if len(rles)>0:\n        for rle in rles:\n            pred_rows += [{'ImageId': name + '.jpg', 'EncodedPixels': rle}]\n    else:\n        pred_rows += [{'ImageId': name + '.jpg', 'EncodedPixels': None}]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c8a40b3b7c50419be4e03f3ee3dec296977165aa"},"cell_type":"code","source":"submission_df = pd.DataFrame(pred_rows)[['ImageId', 'EncodedPixels']]\nsubmission_df.to_csv('submission.csv', index=False)","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}