{"metadata": {"language_info": {"codemirror_mode": {"version": 3, "name": "ipython"}, "name": "python", "pygments_lexer": "ipython3", "mimetype": "text/x-python", "version": "3.6.1", "file_extension": ".py", "nbconvert_exporter": "python"}, "kernelspec": {"display_name": "Python 3", "name": "python3", "language": "python"}}, "cells": [{"outputs": [], "cell_type": "code", "execution_count": null, "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 in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nfrom subprocess import check_output\nprint(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))\n\n# Any results you write to the current directory are saved as output.\n\nimport numpy as np\nimport gzip\nimport os\nfrom os.path import basename\nimport glob\nimport time\nimport cv2\nimport pandas as pd\nimport random\nfrom PIL import Image\n#import scipy.ndimage\nfrom scipy import ndimage\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nfrom scipy.misc import imresize\nfrom skimage.transform import resize\n\nfrom sklearn.model_selection import train_test_split\nfrom keras.models import Model\nfrom keras.layers import Input, merge, Conv2D, MaxPooling2D, UpSampling2D, Concatenate\n#from keras.layers import Dense, Conv2D, Input, MaxPool2D, UpSampling2D, Concatenate, Conv2DTranspose\nfrom keras.optimizers import Adam\nfrom keras.optimizers import SGD\nfrom keras.callbacks import ModelCheckpoint, LearningRateScheduler, EarlyStopping\nfrom keras.preprocessing.image import array_to_img, img_to_array, load_img, ImageDataGenerator\nfrom keras import backend as K\n\nK.set_image_dim_ordering('th') # Theano dimension ordering in this code\n", "metadata": {"_uuid": "d8ced1a0aa872c3cc87411fc768cf85f71280e66", "_cell_guid": "a1d71cec-86ee-469f-8882-46248d06ae77", "trusted": true}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "INPUT_PATH = '../input/'\ndims = [128, 128] \nimg_rows = dims[0]\nimg_cols = dims[1]\ntrain = sorted(glob.glob(INPUT_PATH + 'train/*.jpg'))\nmasks = sorted(glob.glob(INPUT_PATH + 'train_masks/*.gif'))\ntest  = sorted(glob.glob(INPUT_PATH + 'test/*.jpg'))\nprint('Number of training images: ', len(train), ' Number of corresponding masks: ', len(masks), ' Number of test images: ', len(test))\n\nmeta = pd.read_csv(INPUT_PATH + 'metadata.csv')\nmask_df = pd.read_csv(INPUT_PATH + 'train_masks.csv')\nids_train = mask_df['img'].map(lambda s: s.split('_')[0]).unique()\nprint('Length of ids_train ', len(ids_train))", "metadata": {"trusted": true, "_cell_guid": "edba2f8f-fa80-4c23-8ee0-fd1fe3eca466", "_uuid": "262c7b4cd14b034c5a9a896f7f0dca2ab9e93218"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "mask_df.head()\n#'''rle_mask is the run-length encoded version of the training set masks the input for the encoder has to be binary; zeroes and ones.\n#I read the encoding output as the pixel number of the first 1 (in the flattened mask) followed by the count of consecutive (uninterupted) series of pixels with value \n#'''", "metadata": {"trusted": true, "_cell_guid": "01329c52-6e6f-4949-b69b-910c55d44958", "_uuid": "5f084de85087d51719704bc41f483b0bb3848e80"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "image = cv2.imread(INPUT_PATH + 'train/00087a6bd4dc_01.jpg')\nplt.imshow(image)\nplt.show()", "metadata": {"trusted": true, "_cell_guid": "ff3f3cb0-92b3-47a8-8b71-3ff2e5d1ec89", "_uuid": "1d67c7bffeddb8e4c71868b3aad8df31c8f96271"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "img = Image.open(INPUT_PATH + 'train_masks/00087a6bd4dc_01_mask.gif').convert('RGB')\nplt.imshow(img)\nplt.show()", "metadata": {"trusted": true, "_cell_guid": "35bf6466-b2e3-4257-a2a9-3468f4f6692e", "_uuid": "dcb7cea3aabe842c74d6abe80ee06692d39433cf"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# from ecobill:\n\nsmooth = 1.\n\ndef 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 + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n\ndef dice_coef_np(y_true,y_pred):\n    y_true_f = y_true.flatten()\n    y_pred_f = y_pred.flatten()\n    intersection = np.sum(y_true_f * y_pred_f)\n    return (2. * intersection + smooth) / (np.sum(y_true_f) + np.sum(y_pred_f) + smooth)\n\ndef dice_coef_loss(y_true, y_pred):\n    return -dice_coef(y_true, y_pred)\n", "metadata": {"collapsed": true, "trusted": true, "_cell_guid": "412f9461-d051-45d2-ac97-6e08b615bf78", "_uuid": "67b164b7bbfcc1de536b6b70b5256fd361f65c5a"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# this is the U-Net model I encountered in the LUNA16 Challenge\ndef get_unet():\n    inputs = Input((3,img_rows, img_cols))\n    conv1 = Conv2D(32, (3, 3), padding=\"same\", activation='relu')(inputs)    \n    conv1 = Conv2D(32, (3, 3), padding=\"same\", activation='relu')(conv1)\n    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n\n    conv2 = Conv2D(64, (3, 3), padding=\"same\", activation='relu')(pool1)\n    conv2 = Conv2D(64, (3, 3), padding=\"same\", activation='relu')(conv2)    \n    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n\n    conv3 = Conv2D(128, (3, 3), padding=\"same\", activation='relu')(pool2)\n    conv3 = Conv2D(128, (3, 3), padding=\"same\", activation='relu')(conv3)\n    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n\n    conv4 = Conv2D(256, (3, 3), padding=\"same\", activation='relu')(pool3)\n    conv4 = Conv2D(256, (3, 3), padding=\"same\", activation='relu')(conv4)\n    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n\n    conv5 = Conv2D(512, (3, 3), padding=\"same\", activation='relu')(pool4)\n    conv5 = Conv2D(512, (3, 3), padding=\"same\", activation='relu')(conv5)\n\n    up6 = Concatenate(axis=1)([UpSampling2D(size=(2, 2))(conv5), conv4])\n    #      Concatenate(axis=3)([residual, upconv])\n    conv6 = Conv2D(256, (3, 3), padding=\"same\", activation='relu')(up6)\n    conv6 = Conv2D(256, (3, 3), padding=\"same\", activation='relu')(conv6)\n\n    up7 = Concatenate(axis=1)([UpSampling2D(size=(2, 2))(conv6), conv3])\n    conv7 = Conv2D(128, (3, 3), padding=\"same\", activation='relu')(up7)\n    conv7 = Conv2D(128, (3, 3), padding=\"same\", activation='relu')(conv7)\n\n    up8 = Concatenate(axis=1)([UpSampling2D(size=(2, 2))(conv7), conv2])\n    conv8 = Conv2D(64, (3, 3), padding=\"same\", activation='relu')(up8)\n    conv8 = Conv2D(64, (3, 3), padding=\"same\", activation='relu')(conv8)\n\n    up9 = Concatenate(axis=1)([UpSampling2D(size=(2, 2))(conv8), conv1])\n    conv9 = Conv2D(32, (3, 3), padding=\"same\", activation='relu')(up9)\n    conv9 = Conv2D(32, (3, 3), padding=\"same\", activation='relu')(conv9)\n\n    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)   #9\n\n    model = Model(inputs=inputs, outputs=conv10)\n    #      `Model(inputs=/input_19, outputs=sigmoid.0)`\n\n    #model.compile(optimizer=Adam(lr=1.0e-5), loss=dice_coef_loss, metrics=[dice_coef])  #LUNA16\n    model.compile(optimizer=Adam(5e-4), loss='binary_crossentropy', metrics=[dice_coef]) #ecobill\n\n    return model\n", "metadata": {"collapsed": true, "trusted": true, "_cell_guid": "864b9559-b741-4984-9a4b-6ea567da2644", "_uuid": "891e9c523397c37a4f80186ae0322f6c4a601b90"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# split the train set into train and validation:\ntrain_images, validation_images = train_test_split(train, train_size=0.8, test_size=0.2)\nprint('Split into training set with ', len(train_images), ' images and validation set with  ', len(validation_images), ' images')", "metadata": {"trusted": true, "_cell_guid": "41ab6140-b753-4829-a470-40ffa935d86a", "_uuid": "ee2c720c8191804cb8fd953c2397e19c4980b800"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "#use loading functions from: ecobill\n\n# utility function to convert greyscale images to rgb\ndef grey2rgb(img):\n    new_img = []\n    for i in range(img.shape[0]):\n        for j in range(img.shape[1]):\n            new_img.append(list(img[i][j])*3)\n    new_img = np.array(new_img).reshape(img.shape[0], img.shape[1], 3)\n    return new_img\n\n\n# generator that we will use to read the data from the directory\ndef data_gen_small(data_dir, masks, images, batch_size, dims):\n        \"\"\"\n        data_dir: where the actual images are kept\n        mask_dir: where the actual masks are kept\n        images: the filenames of the images we want to generate batches from\n        batch_size: self explanatory\n        dims: the dimensions in which we want to rescale our images\n        \n        Image.resize(size, resample=0)\n\n        Returns a resized copy of this image.\n        Parameters:\t\n\n        size \u2013 The requested size in pixels, as a 2-tuple: (width, height).\n        resample \u2013 An optional resampling filter. This can be one of PIL.Image.NEAREST, \n        PIL.Image.BOX, PIL.Image.BILINEAR, PIL.Image.HAMMING, PIL.Image.BICUBIC or PIL.Image.LANCZOS. \n        If omitted, or if the image has mode \u201c1\u201d or \u201cP\u201d, it is set PIL.Image.NEAREST\n        \"\"\"\n        while True:\n            ix = np.random.choice(np.arange(len(images)), batch_size)\n            imgs = []\n            labels = []\n            for i in ix:\n                # images\n                original_img = cv2.imread(images[i])\n                resized_img = imresize(original_img, dims+[3]) #this looks like TensorFlow ordering \n                array_img = resized_img / 255   \n                array_img = array_img.swapaxes(0,2)\n                imgs.append(array_img)\n                #imgs is a numpy array with dim: (batch size X 128 X 128 X 3)\n                \n                # masks\n                mask_filename = basename(images[i])\n                no_extension = os.path.splitext(mask_filename)[0]\n                correct_mask = INPUT_PATH + 'train_masks/' + no_extension + '_mask.gif' \n                original_mask = Image.open(correct_mask).convert('L')\n                data = np.asarray( original_mask, dtype=\"int32\" )\n                resized_mask = imresize(original_mask, dims+[3])\n                array_mask = resized_mask / 255\n                labels.append(array_mask)\n            imgs = np.array(imgs)\n            labels = np.array(labels)\n            relabel = labels.reshape(-1, dims[0], dims[1], 1)\n            yield imgs, relabel.swapaxes(1, 3)\n\n", "metadata": {"collapsed": true, "trusted": true, "_cell_guid": "bae7a945-ebd4-496e-be5b-d02a1fe46944", "_uuid": "664af9161caffe4969bd497b177a187432628098"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "train_gen = data_gen_small(INPUT_PATH + 'train/', masks, train_images, 2, dims) \nimg, msk = next(train_gen)\nprint('Size of batch: ', len(img))\nprint('shape of img ', img.shape, 'number dimensions: ', img[0].ndim)\nprint('shape of msk ', msk.shape, 'number dimensions: ', msk[0].ndim)\nnewshape = img[0].swapaxes(0,2)\nplt.imshow(newshape)\nplt.show()\n\n#try resize up \n\nresized_img = imresize(img[0], [1280, 1918]+[3])\nprint('resized up: ', resized_img.shape)\nnewshape = resized_img.swapaxes(0,1)\nprint('resized swapaxes: ', newshape.shape)\nprint('resized swapaxes shape[-1]: ', newshape.shape[-1])\n\nplt.imshow(newshape)\nplt.show()\n\nnewshape = msk.swapaxes(1,3)\nprint(newshape.shape)\nplt.imshow(grey2rgb(newshape[0]), alpha=0.5)\nplt.show()", "metadata": {"trusted": true, "_cell_guid": "b820af94-942c-4f32-a909-513e2c70126e", "_uuid": "698b55db65166fea536bd1e83b15e01f61b1d4df"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# create an instance of a validation generator:\nvalidation_gen = data_gen_small(INPUT_PATH + 'train/', masks, validation_images, 4, dims) ", "metadata": {"trusted": true, "_cell_guid": "ae0f75ca-c1ad-4418-bc1d-3aa75353f264", "_uuid": "beccf98a40eb129b2069c6adf966a55d30c25c44"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# define and compile the model\nmodel = get_unet()\nmodel.summary()", "metadata": {"trusted": true, "_cell_guid": "f9b24275-296e-4c49-b0f6-0866ce33b2e9", "_uuid": "c453eb9b43c70369f458fbf5e39a908c59868260"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# fit the model and check dice_coef on validation data at end of each epoch\nmodel.fit_generator(train_gen, steps_per_epoch=50, epochs=1, validation_data=validation_gen, validation_steps=50)", "metadata": {"trusted": true, "_cell_guid": "ab099a5b-6cb0-48af-a3ac-caf1fa786d8d", "_uuid": "1f6474172ac73246e238d9172032013ccde29a2e"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# lets look at one of the predicted masks\nimg, msk = next(validation_gen)\npredicted_mask = model.predict(img)\npredicted_mask.shape", "metadata": {"trusted": true, "_cell_guid": "4e55ca8a-4484-41e4-af92-9a919d4721ac", "_uuid": "120d88683c9139026fa1583aebe0ac2deaafb48c"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "newshape = predicted_mask.swapaxes(1,3)\nprint('newshape shape ', newshape.shape)\ngrey = grey2rgb(newshape[3])\nprint('grey shape ', grey.shape)\nplt.imshow(grey, alpha = 0.5)\nplt.show()", "metadata": {"trusted": true, "_cell_guid": "facfa412-a7ff-4c53-b944-77a40bce995d", "_uuid": "6bc63d5939f19157b1522d51f1c0ee8b913b42e4"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "# the corresponding image is:\nnewshape = img[3].swapaxes(0,2)\nplt.imshow(newshape)\nplt.show()", "metadata": {"trusted": true, "_cell_guid": "21f97d6a-d5a6-4c54-9a15-e9c0dbb5df4b", "_uuid": "306a30277889ed3d9bf8f531bbb06f8c0bb7de4f"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "source": "", "metadata": {"collapsed": true, "trusted": true, "_cell_guid": "4efa0f6b-4b27-4789-be1e-81d04bf71101", "_uuid": "a4dfa6d4e6a38aa8923f5f234904902e275d956a"}}], "nbformat_minor": 1, "nbformat": 4}