{"cells":[{"metadata":{"_cell_guid":"e61ef2d8-f315-4f7f-b07e-1de0f4e8441a","_uuid":"1677fddbb95f7545b6540e9201f3339a0fdbfc5d"},"cell_type":"markdown","source":"# Intro\n# Unet based optimized model code LB .347\n# Approximatley 100 eoochs val_dice_coef - 91%\n\nMost of the code is from the below kernels.. \nhttps://www.kaggle.com/keegil/keras-u-net-starter-lb-0-277\nhttps://www.kaggle.com/shenmbsw/data-augmentation-and-tensorflow-u-net"},{"metadata":{"trusted":false,"collapsed":true,"_uuid":"b256b8c337afe2440cfb721e77f16a0c84da579d"},"cell_type":"code","source":"import os\nimport sys\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport h5py\n\n\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom itertools import chain\nfrom skimage.io import imread, imshow, imread_collection, concatenate_images\nfrom skimage.transform import resize\nfrom skimage.morphology import label\nfrom skimage import img_as_uint\n\n\n\nfrom keras.models import Model, load_model\nfrom keras.layers import Input, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, UpSampling2D\nfrom keras.layers.core import Dropout, Lambda\nfrom keras.layers.convolutional import Conv2D, Conv2DTranspose\nfrom keras.layers.pooling import MaxPooling2D\nfrom keras.layers.merge import concatenate\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom keras import backend as K\nimport keras\nfrom keras import optimizers\n\n%matplotlib inline\n\nimport tensorflow as tf\nimport sklearn\nimport skimage\nfrom skimage import transform\nfrom os import environ\n\nseed = 42\n\nwarnings.filterwarnings('ignore', category=UserWarning, module='skimage')\nprint('Python       :', sys.version.split('\\n')[0])\nprint('Numpy        :', np.__version__)\nprint('Skimage      :', skimage.__version__)\nprint('Scikit-learn :', sklearn.__version__)\nprint('Keras        :', keras.__version__)\nprint('Tensorflow   :', tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"42aa9cebcfbb41a86dd47fa7094ee762545a65dc"},"cell_type":"code","source":"IMG_WIDTH = 256\nIMG_HEIGHT = 256\nIMG_CHANNELS = 3\nTRAIN_PATH = 'input/stage1_train/'\nTEST_PATH = 'input/stage1_test/'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e3a6121804eb428a44f5e0d40c7b475c6fa8af68","trusted":false,"collapsed":true},"cell_type":"code","source":"from tensorflow.python.client import device_lib\nprint(device_lib.list_local_devices())","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"2d962f36aecb98eed88a7d5a2492f7d15c96a9e9"},"cell_type":"code","source":"train_ids = next(os.walk(TRAIN_PATH))[1]\ntest_ids = next(os.walk(TEST_PATH))[1]","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"b263a7065a91cf7b8f510c320ed011e31ee501e5"},"cell_type":"code","source":"def read_image_labels(image_id, aug_idx=-1, read_aug=False):\n    # most of the content in this function is taken from 'Example Metric Implementation' kernel \n    # by 'William Cukierski'\n    if read_aug == False:\n        image_file = \"{}{}/images/{}.png\".format(TRAIN_PATH,image_id,image_id)\n        mask_file = \"{}{}/masks/*.png\".format(TRAIN_PATH, image_id)\n    else:\n        image_file = \"{}{}/augs/{}_{}.png\".format(TRAIN_PATH,image_id,image_id,aug_idx)\n        mask_file = \"{}{}/augs_masks/{}_{}.png\".format(TRAIN_PATH,image_id,image_id,aug_idx)\n    \n    image = skimage.io.imread(image_file)[:,:,:IMG_CHANNELS]\n    if read_aug == False:\n        masks = skimage.io.imread_collection(mask_file).concatenate()    \n        height, width, _ = image.shape\n        num_masks = masks.shape[0]\n        label = np.zeros((height, width), np.bool)\n        for index in range(0, num_masks):\n            label[masks[index] > 0] = index + 1\n    else:\n        label = skimage.io.imread(mask_file)\n        label = np.copy(label).astype('bool')\n\n    return image, label","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"c81bf00c8e45580511b38e94d1b662f495e96975"},"cell_type":"code","source":"def data_aug(image,label,angel=30,resize_rate=0.9):\n    \n    flip = random.randint(0, 1)\n    \n    w = image.shape[0]\n    h = image.shape[1]\n\n    rwsize = random.randint(np.floor(random.uniform(0.5, 0.9)*w), w)\n    rhsize = random.randint(np.floor(random.uniform(0.5, 0.9)*h), h)\n    w_s = random.randint(0, w - rwsize)\n    h_s = random.randint(0, h - rhsize)\n        \n    #print(image.shape, w_s, rwsize, h_s, rhsize)\n    \n    sh = random.random()/2-0.25\n    rotate_angel = random.random()/180*np.pi*angel\n    # Create Afine transform\n    afine_tf = transform.AffineTransform(shear=sh,rotation=rotate_angel)\n    # Apply transform to image data\n    image = transform.warp(image, inverse_map=afine_tf,mode='edge')\n    label = transform.warp(label, inverse_map=afine_tf,mode='edge')\n    \n    # Randomly corpping image frame\n    image = image[w_s:w_s+rwsize, h_s:h_s+rhsize,:]\n    label = label[w_s:w_s+rwsize, h_s:h_s+rhsize]\n    \n    # Ramdomly flip frame\n    if flip:\n        image = image[:,::-1,:]\n        label = label[:,::-1]\n    #print(image.dtype, label.dtype)\n    image = resize(image, (IMG_HEIGHT, IMG_WIDTH, 3), mode='constant', preserve_range=True)\n    image = skimage.img_as_ubyte(image)\n    label = resize(label, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)\n    label = np.copy(label).astype('bool')\n    \n    return image, label","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"f47b34431ec3817f3d9d289a6836d3f610343b4d"},"cell_type":"code","source":"def save_single_data_augmentation(image_id, idx, new_image, new_label):\n    image,labels = read_image_labels(image_id)\n    if not os.path.exists(\"{}{}/augs/\".format(TRAIN_PATH,image_id)):\n        os.makedirs(\"{}{}/augs/\".format(TRAIN_PATH, image_id))\n    if not os.path.exists(\"{}{}/augs_masks/\".format(TRAIN_PATH,image_id)):\n        os.makedirs(\"{}{}/augs_masks/\".format(TRAIN_PATH, image_id))\n            \n    # also save the original image in augmented file \n    #plt.imsave(fname=\"../input/stage1_train/{}/augs/{}.png\".format(image_id,image_id), arr = image)\n    #plt.imsave(fname=\"../input/stage1_train/{}/augs_masks/{}.png\".format(image_id,image_id),arr = labels)\n\n    #for i in range(split_num):\n    aug_img_dir = \"{}{}/augs/{}_{}.png\".format(TRAIN_PATH,image_id,image_id,idx)\n    aug_mask_dir = \"{}{}/augs_masks/{}_{}.png\".format(TRAIN_PATH,image_id,image_id,idx)\n    skimage.io.imsave(aug_img_dir, new_image)\n    skimage.io.imsave(aug_mask_dir, img_as_uint(new_label))\n    return aug_img_dir, aug_mask_dir","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"e6fe99e777b16ccdbc7769920a97434d4533c1e9"},"cell_type":"code","source":"def make_data_augmentation(image_ids,split_num):\n    for ax_index, image_id in tqdm(enumerate(image_ids),total=len(image_ids)):\n        image, labels = read_image_labels(image_id)\n        for i in range(split_num):\n            new_image, new_label = data_aug(image,labels,angel=5,resize_rate=0.9)\n            save_single_data_augmentation(image_id, i, new_image, new_label)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"87ece0fe66fe588dbefcbc5e3dbad52fe9cbc580"},"cell_type":"code","source":"import shutil\ndef clean_data_augmentation(image_ids):\n    for ax_index, image_id in tqdm(enumerate(image_ids),total=len(image_ids)):\n        if os.path.exists(\"{}{}/augs/\".format(TRAIN_PATH, image_id)):\n            shutil.rmtree(\"{}{}/augs/\".format(TRAIN_PATH, image_id))\n        if os.path.exists(\"{}{}/augs_masks/\".format(TRAIN_PATH, image_id)):\n            shutil.rmtree(\"{}{}/augs_masks/\".format(TRAIN_PATH, image_id))","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"1be09d036d74f8ad27c58d88749861911c073641"},"cell_type":"code","source":"plt.close('all')\nfor i in range(0, 10):\n        image_id = train_ids[i]\n        fig, axes = plt.subplots(1, 4, figsize=(18, 18))\n        image, labels = read_image_labels(image_id)\n        \n        image = resize(image, (IMG_HEIGHT, IMG_WIDTH, 3), mode='constant', preserve_range=True)\n        image = np.copy(image).astype('uint8')\n        labels = resize(labels, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)\n        labels = np.copy(labels).astype('bool')\n    \n        j=0\n        axes[j].imshow(image)\n        axes[j].axis('off')\n        axes[j].set_title('{} th X'.format(image_id[:4]))\n        \n        j+=1\n        axes[j].imshow(np.squeeze(labels))\n        axes[j].axis('off')\n        axes[j].set_title('{} th Y'.format(image_id[:4]))\n\n        #fig, axes = plt.subplots(1, 2, figsize=(18, 18))\n\n        new_image, new_label = data_aug(image, labels, angel=10, resize_rate=0.9)\n        #print(new_image[:2,:2,1:2])\n        w = random.randint(10,15)\n        #print(new_image.dtype, new_image.shape, new_image[10:w,10:w])\n        #print(new_label.dtype, new_label.shape, new_label[10:w,10:w])\n        aug_img_file, aug_mask_file = save_single_data_augmentation(image_id, 0, new_image, new_label)\n            \n        new_image, new_label = read_image_labels(image_id, 0, True)\n        new_label = np.expand_dims(new_label, axis=-1)\n        #print(new_image.dtype, new_image.shape, new_image[10:w,10:w])\n        #print(new_label.dtype, new_label.shape, new_label[10:w,10:w])\n\n        j+=1\n        axes[j].imshow(new_image)\n        axes[j].axis('off')\n        axes[j].set_title('{} th aug X'.format(image_id[:4]))\n        \n        j+=1\n        axes[j].imshow(np.squeeze(new_label))\n        axes[j].axis('off')\n        axes[j].set_title('{} th aug Y'.format(image_id[:4]))","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"70bae6517a1ddedba69f3a03bdd51fd8d2251562"},"cell_type":"code","source":"clean_data_augmentation(train_ids)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"7803ea87ff143bb8e17f1d2daa37f89fc6d94a8f"},"cell_type":"code","source":"make_data_augmentation(train_ids, 3)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"59c4a25d-645f-4b74-9c53-145ac78cc481","_uuid":"875af74f980236825de3a650825b46e25632422c"},"cell_type":"markdown","source":"# Get the data\nGet X_train Data and artificial data"},{"metadata":{"_cell_guid":"ca0cc34b-c26f-41ee-88d7-975aebdb634e","_uuid":"9e389ba8bdb5b6fc03b231b6a6c84a8bde634053","collapsed":true,"trusted":false},"cell_type":"code","source":"# Get and resize train images and masks\nX_train = np.zeros((len(train_ids) + len(train_ids)*3, IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nY_train = np.zeros((len(train_ids) + len(train_ids)*3, IMG_HEIGHT, IMG_WIDTH, 1), dtype=np.bool)\nprint('Getting and resizing train images and masks ... ')\nsys.stdout.flush()\ncount = 0\nfor n, id_ in tqdm(enumerate(train_ids), total=len(train_ids)):\n    image, label = read_image_labels(id_)\n    image = resize(image, (IMG_HEIGHT, IMG_WIDTH, 3), mode='constant', preserve_range=True)\n    \n    label = resize(label, (IMG_HEIGHT, IMG_WIDTH, 1), mode='constant', preserve_range=True)\n    label = np.copy(label).astype('bool')\n    \n    idx = n + count * 3\n    \n    X_train[idx] = image\n    Y_train[idx] = label\n\n    for i in range(3):\n        idx +=1\n        new_image, new_label = read_image_labels(id_, i, True)\n        new_label = np.expand_dims(new_label, axis=-1)\n        X_train[idx] = new_image\n        Y_train[idx] = new_label\n\n    count +=1\n        \n        \nprint('Done!')","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"43628fec17d787acd76197a01aeb6436e92ef194"},"cell_type":"code","source":"X_test = np.zeros((len(test_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nsizes_test = []\nprint('Getting and resizing 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\n\nprint('Done!')","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"c0523b03-1fc5-4505-a1b8-eb35ee617c8a","_uuid":"d4f8327802a1ec6139ce0585953986272ba62ce1"},"cell_type":"markdown","source":"Let's see if things look all right by drawing some random images and their associated masks."},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"4468120380c224a201aa4dc0ca64e43fef223b98"},"cell_type":"code","source":"plt.close('all')\nfor i in range(0, 20):\n        image_id = random.randint(0, (len(train_ids) + len(train_ids)*3-1))\n        fig, axes = plt.subplots(1, 3, figsize=(18, 18))\n    \n        j=0\n        axes[j].imshow(X_train[image_id])\n        axes[j].axis('off')\n        axes[j].set_title('{} th X'.format(image_id))\n        \n        j+=1\n        axes[j].imshow(np.squeeze(Y_train[image_id]))\n        axes[j].axis('off')\n        axes[j].set_title('{} th Y'.format(image_id))\n        \n        image_id = random.randint(0, len(test_ids))\n\n        j+=1\n        axes[j].imshow(X_test[image_id])\n        axes[j].axis('off')\n        axes[j].set_title('{} th X_test'.format(image_id))","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"6b201e336386b0497d17e812bca4d79c3beea4eb"},"cell_type":"code","source":"print(X_train.shape, Y_train.shape)\nprint(X_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"c1df6f3a-d58f-434b-9216-ef7be38637d4","_uuid":"5abd38950ae99b60f8afec7656eb654a48d449fe","collapsed":true,"trusted":false},"cell_type":"code","source":"# Define IoU metric\ndef mean_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":{"collapsed":true,"trusted":false,"_uuid":"616ad7761ab778d71641826ce3e368cd12fef76a"},"cell_type":"code","source":"def dice_coef_loss(y_true, y_pred):\n    return -dice_coef(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"1023c8133ea55d9e692d544498ee738ba10ae23a"},"cell_type":"code","source":"def dice_coef(y_true, y_pred):\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 + K.epsilon()) / (K.sum(y_true_f) + K.sum(y_pred_f) + K.epsilon())","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"0fc4e50ab594b97fa22237cbf0deccbb3dee4922"},"cell_type":"code","source":"def conv_layer(x, filters, k_size, act_func, dropout, batch_norm, name, k_init='he_normal', axis=3):\n    conv = Conv2D(filters, k_size, kernel_initializer=k_init, name=name, padding='same')(x)\n    if batch_norm is True:\n        conv = BatchNormalization(axis=axis)(conv)\n    conv = Activation(act_func)(conv)\n    if dropout > 0:\n        conv = Dropout(dropout)(conv)\n    return conv","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"9d2b4038dc60b6f03f0607ff17b6771d26a31f51"},"cell_type":"code","source":"def keras_model_Unet_2D(img_width=256, img_height=256):\n    '''\n    Modified from https://keunwoochoi.wordpress.com/2017/10/11/u-net-on-keras-2-0/\n    '''\n    n_ch_exps = [4, 5, 6, 7, 8, 9]   #the n-th deep channel's exponent i.e. 2**n 16,32,64,128,256\n    k_size = (3, 3)                  #size of filter kernel\n    k_init = 'he_normal'             #kernel initializer\n\n    if K.image_data_format() == 'channels_first':\n        ch_axis = 1\n        input_shape = (3, img_width, img_height)\n    elif K.image_data_format() == 'channels_last':\n        ch_axis = 3\n        input_shape = (img_width, img_height, 3)\n\n    inp = Input(shape=input_shape)\n    s = Lambda(lambda x: x / 255) (inp)\n\n    encodeds = []\n    k_size_list = [(3,3), (3,3)]\n    #k_size_list = [(3,3), (3,3)]\n\n    # encoder\n    enc = s\n    print(n_ch_exps)\n    for l_idx, n_ch in enumerate(n_ch_exps):\n        for i in range(len(k_size_list)):\n            k_size = k_size_list[i]\n            do = 0.1\n            enc = conv_layer(enc, 2**n_ch, k_size, 'relu', do, False, name='c{}_{}x{}_{}'.format((l_idx+1), \n                                                                                                        k_size[0], k_size[1], \n                                                                                                        (i+1)))\n            #round(0.1*l_idx,1), \n        encodeds.append(enc)\n\n        #print(l_idx, enc)\n        if n_ch < n_ch_exps[-1]:  #do not run max pooling on the last encoding/downsampling step\n            enc = MaxPooling2D(pool_size=(2,2))(enc)\n    \n\n    # decoder\n    dec = enc\n    print(n_ch_exps[::-1][1:])\n    decoder_n_chs = n_ch_exps[::-1][1:]\n    for l_idx, n_ch in enumerate(decoder_n_chs):\n        l_idx_rev = len(n_ch_exps) - l_idx - 2  #\n        \n        k_size=(2,2)\n        dec = UpSampling2D(size=k_size)(dec)\n        dec = Conv2DTranspose(filters=2**n_ch, kernel_size=k_size, \n                              activation='relu', \n                              padding='same', \n                              kernel_initializer=k_init)(dec)\n        \n        dec = concatenate([dec, encodeds[l_idx_rev]], axis=ch_axis)\n    \n        #for i in range(len(k_size_list)):\n        for i, k in reversed(list(enumerate(k_size_list))):    \n            k_size = k_size_list[i]\n            dec = conv_layer(dec, 2**n_ch, k_size, 'relu', do, False, 'dc{}_{}x{}_{}'.format((l_idx_rev+1), \n                                                                                                   k_size[0], k_size[1], (i+1)))\n        \n    #outp = Conv2DTranspose(filters=1, kernel_size=k_size, activation='sigmoid', padding='same', \n                           #kernel_initializer='glorot_normal')(dec)\n    \n    outp = Conv2D(filters=1, kernel_size=(1,1), activation='sigmoid', name='output')(dec)\n\n    model = Model(inputs=[inp], outputs=[outp])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"72330944-6ce7-4070-b276-c3c4b20c4fe5","_uuid":"92350b6e18cc50f3fa7b6e9a02d39fcbff8238f7"},"cell_type":"markdown","source":"*Update: Changed to ELU units, added dropout.*\n\nNext we fit the model on the training data, using a validation split of 0.1. We use a small batch size because we have so little data. I recommend using checkpointing and early stopping when training your model. I won't do it here to make things a bit more reproducible (although it's very likely that your results will be different anyway). I'll just train for 10 epochs, which takes around 10 minutes in the Kaggle kernel with the current parameters. \n\n*Update: Added early stopping and checkpointing and increased to 30 epochs.*"},{"metadata":{"trusted":false,"collapsed":true,"_uuid":"e5009007a13538be19fc6243ae4a18b3934cd8db"},"cell_type":"code","source":"model = keras_model_Unet_2D(img_width=IMG_WIDTH, img_height=IMG_HEIGHT)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"dab880b56316bcf3c8e46a7662d283a90daa198c"},"cell_type":"code","source":"\n# Perform a sanity check on some random training samples\nfor i in range(5):\n    ix = random.randint(0, len(train_ids)-1)\n    imshow(X_train_orig[ix])\n    plt.show()\n\n    imshow(np.squeeze(Y_train_orig[ix]))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"21b0f21bc125f1b5ef732aaabf8e605d52b0e3f5"},"cell_type":"code","source":"model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[dice_coef])","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"collapsed":true,"_uuid":"6523aaca6ece296ebd872d71332f595da0e5cd9e"},"cell_type":"code","source":"#callbacks_list = []\nmodelName = 'UNet_2D_UCCC_33_aug_do0.1_orig.h5'\nearlystopper = EarlyStopping(patience=10, verbose=1)\ncheckpointer = ModelCheckpoint(modelName, verbose=1, save_best_only=True)\nresults = model.fit(X_train_orig, Y_train_orig, validation_split=0.2, batch_size=32, epochs=1, #200,#50 \n                    callbacks=[earlystopper, checkpointer])","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"1f381f5b-1b71-4daa-a417-e02f4894540b","_uuid":"bb15226ea617cf91ed8f43179fccb5a15809e5a0"},"cell_type":"markdown","source":"All right, looks good! Loss seems to be a bit erratic, though. I'll leave it to you to improve the model architecture and parameters! \n\n# Make predictions\n\nLet's make predictions both on the test set, the val set and the train set (as a sanity check). Remember to load the best saved model if you've used early stopping and checkpointing."},{"metadata":{"collapsed":true,"trusted":false,"_uuid":"c9d54b7ff8e2a75eb042ce32111346f047029616"},"cell_type":"code","source":"print(modelName)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"2daa48d5-ac98-4e18-af3f-a582baaa44f0","_uuid":"f841760b4abca1a25cb750822f88268bd79bf2ce","trusted":false,"collapsed":true},"cell_type":"code","source":"# Predict on train, val and test\n#model = load_model(modelName, custom_objects={'dice_coef_loss':dice_coef_loss, 'dice_coef': dice_coef})\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]), \n                                       (sizes_test[i][0], sizes_test[i][1]), \n                                       mode='constant', preserve_range=True))","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"649248cd-a1fb-4da6-ade2-4bebad44bcab","_uuid":"7e06242a50870e07a080064a4912b761775990fa","collapsed":true,"trusted":false},"cell_type":"code","source":"# Perform a sanity check on some random training samples\nfor i in range(5):\n    ix = random.randint(0, len(preds_train_t))\n    imshow(X_train[ix])\n    plt.show()\n\n    imshow(np.squeeze(Y_train[ix]))\n    plt.show()\n\n    imshow(np.squeeze(preds_train_t[ix]))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"af602aea-5e56-42a8-9331-54b4b2650593","_uuid":"5fcee2b9aee2fba5c60d43ad48a14139e9c1318c"},"cell_type":"markdown","source":"The model is at least able to fit to the training data! Certainly a lot of room for improvement even here, but a decent start. How about the validation data?"},{"metadata":{"_cell_guid":"4f66b75c-c694-41a1-8c91-34bb6595837b","_uuid":"d4ccbb559375bc2777ffb692a20adc313159f2cc","collapsed":true,"trusted":false},"cell_type":"code","source":"# Perform a sanity check on some random validation samples\nix = random.randint(0, len(preds_val_t))\nimshow(X_train[int(X_train.shape[0]*0.9):][ix])\nplt.show()\nimshow(np.squeeze(Y_train[int(Y_train.shape[0]*0.9):][ix]))\nplt.show()\nimshow(np.squeeze(preds_val_t[ix]))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"a6690535-b2e4-49ac-98d9-7191bfabfb6f","_uuid":"6a34c98de7c6ae473f676a34fe7e099b46764eca"},"cell_type":"markdown","source":"Not too shabby! Definitely needs some more training and tweaking.\n\n# Encode and submit our results\n\nNow it's time to submit our results. I've stolen [this](https://www.kaggle.com/rakhlin/fast-run-length-encoding-python) excellent implementation of run-length encoding."},{"metadata":{"_cell_guid":"59a0af60-a7d7-41ef-a6fe-9e3c72defa07","_uuid":"4f99c1bf852e82b60bd4f982ca0df293f712cdf0","collapsed":true,"trusted":false},"cell_type":"code","source":"# Run-length encoding stolen from https://www.kaggle.com/rakhlin/fast-run-length-encoding-python\ndef rle_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 = skimage.morphology.label(x > cutoff)\n    for i in range(1, lab_img.max() + 1):\n        yield rle_encoding(lab_img == i)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"31133f8c-3f40-4dff-8e1d-898d56672332","_uuid":"2e07f6afc4787b068ba714428145dcb3951d718f"},"cell_type":"markdown","source":"Let's iterate over the test IDs and generate run-length encodings for each seperate mask identified by skimage ..."},{"metadata":{"_cell_guid":"22fe24a1-7659-4cc9-9d23-211f38e5b99f","_uuid":"089587843ed6a3955fdcb9b23a6ec3bf5d703688","collapsed":true,"trusted":false},"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":{"_cell_guid":"20b6b627-0fd6-425d-888f-da7f39efb124","_uuid":"849184a40a2c9c21506d8b8eb10ad9155fa229e8"},"cell_type":"markdown","source":"... and then finally create our submission!"},{"metadata":{"_cell_guid":"1ba0ee3a-cca0-4349-83f6-09a1ac6fcb44","_uuid":"ba589f56f5be1e6886bc88f5bf9e7d0a408e4048","collapsed":true,"trusted":false},"cell_type":"code","source":"# Create submission DataFrame\nsub = 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('UNet_2D_UCCC_33_aug_do0.1_orig.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"collapsed":true,"_uuid":"7d23aa1634a389de4513b67f678858e3f33165bb"},"cell_type":"code","source":"sub.describe()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"222475b9-3171-461a-90f0-a820a6bd2634","_uuid":"fb5e6f8cca872f1bd7036f6d9ac2ed2cab615536","collapsed":true},"cell_type":"markdown","source":"This scored 0.347 on the LB for me. \n\n**Have fun!**\n\nLB score history:\n- Version 10: 0.348 LB"}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.3"}},"nbformat":4,"nbformat_minor":1}