{"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":"markdown","source":"**Identification and Segmentation of Nuclei From Images of Cells: A Deep Learning Approach**","metadata":{"_uuid":"ce12a9c661a91ad0906597233998ce29ba0c8cbf","_cell_guid":"66e72fd8-698a-4e23-a4a2-e2bf9b55dabe"}},{"cell_type":"markdown","source":"The nucleus is an organelle present within all eukaryotic cells, including human cells. Abberant nuclear shape can be used to identify cancer cells (e.g. pap smear tests and the diagnosis of cervical cancer). Likewise, a growing body of literature suggests that there is some connection between the shape of the nucleus and human disease states such as cancer and aging. As such, the quantitative assessment of nuclear size and shape has important biomedical applications.  Methods for assessing nuclear size and shape typically involve identifying the nucleus via traditional image segmentation approaches.  Here we demonstrate a deep learning approach for the identification and segmentation of nuclei from images of cells.  \n\nFor more information about the relationship between nuclear shape and human disease, please refer to the following resources: [Link #1](https://www.ncbi.nlm.nih.gov/pubmed/15343274), [Link #2](* Webster, M., Witkin, K.L., and Cohen-Fix, O. (2009), [Link #3](https://www.ncbi.nlm.nih.gov/pubmed/26940517)\n","metadata":{"_uuid":"4f0ad298597ca91477e40568c38be8c6043859f8","_cell_guid":"7ad7a57b-d617-491a-85c9-ededf2924e72"}},{"cell_type":"markdown","source":"*Step 1: Import Libraries*","metadata":{"_uuid":"3601f0d1c57e4a9f97306ac407538257b7a2a3b3","_cell_guid":"ca6f6b40-bfe3-423e-99bb-f90ca3cf0e88"}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport os\nfrom os.path import join\nimport glob\nimport sys\nimport random\nimport warnings\nfrom tqdm import tqdm\nimport itertools\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 sklearn.model_selection import train_test_split\nimport tensorflow as tf\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D, BatchNormalization, Conv2D, UpSampling2D, Lambda\nfrom keras.models import Model, load_model\nfrom keras.layers import Input\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 import backend as K\nfrom keras.callbacks import Callback, EarlyStopping, ReduceLROnPlateau, ModelCheckpoint\nfrom keras import initializers, layers, models\nfrom keras.utils import to_categorical\nfrom keras.utils.vis_utils import plot_model\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import callbacks\n# Remember to enable GPU\n%matplotlib inline","metadata":{"_kg_hide-input":true,"_uuid":"eb59375f3018dad80c95da9345b9f3156bfd8614","_cell_guid":"7279201f-1b60-4b67-9bdc-13c553069f0f","execution":{"iopub.status.busy":"2021-10-20T18:02:25.233635Z","iopub.execute_input":"2021-10-20T18:02:25.233915Z","iopub.status.idle":"2021-10-20T18:02:28.645686Z","shell.execute_reply.started":"2021-10-20T18:02:25.233863Z","shell.execute_reply":"2021-10-20T18:02:28.645050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 2: Explore Data*","metadata":{"_uuid":"7144e0662dda49ae6b025bdb1ba268ad1fc3b4ea","_cell_guid":"eda83e6f-a0a5-4921-8ace-d933d852d0a9"}},{"cell_type":"markdown","source":"Image segmentation can easily be performed via the use of the Python library OpenCV, but we want to use deep learning to develop an even more accurate result.  Below is an implementation of an OpenCV image segmentation task using the same images of nuclei in cells.","metadata":{"_uuid":"d08ebf4fcd81eddca1e1d3b091d907e630dbb555","_cell_guid":"9306af02-f26c-4b60-8535-33697764c66a"}},{"cell_type":"code","source":"import os\nprint(os.listdir())","metadata":{"execution":{"iopub.status.busy":"2021-10-20T17:05:28.302923Z","iopub.execute_input":"2021-10-20T17:05:28.303245Z","iopub.status.idle":"2021-10-20T17:05:28.309364Z","shell.execute_reply.started":"2021-10-20T17:05:28.303183Z","shell.execute_reply":"2021-10-20T17:05:28.308014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!7z x \"../input/stage1_test.zip\" -o\"/input/stage1_test\"\n!7z x \"../input/stage1_train.zip\" -o\"/input/stage1_train\"","metadata":{"execution":{"iopub.status.busy":"2021-10-20T18:02:38.122857Z","iopub.execute_input":"2021-10-20T18:02:38.123155Z","iopub.status.idle":"2021-10-20T18:02:50.035670Z","shell.execute_reply.started":"2021-10-20T18:02:38.123087Z","shell.execute_reply":"2021-10-20T18:02:50.034496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def openCVdemo():\n    ID = '0a7d30b252359a10fd298b638b90cb9ada3acced4e0c0e5a3692013f432ee4e9'\n    FILE = \"/input/stage1_train/{}/images/{}.png\".format(ID,ID)\n    img = cv2.imread(FILE,0)\n    # Otsu's thresholding after Gaussian filtering\n    blur = cv2.GaussianBlur(img,(5,5),0)\n    ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)   \n    # Plot Here\n    plt.figure(figsize=(15,5))\n    images = [blur, 0, th3]\n    titles = ['Original Image (X_train)','Gaussian filtered Image (OpenCV)',\"Segmentated Image (OpenCV)\"]\n    plt.subplot(1,3,1),plt.imshow(img,'gray')\n    plt.title(titles[0]), plt.xticks([]), plt.yticks([])\n    plt.subplot(1,3,2),plt.imshow(images[0],'gray')\n    plt.title(titles[1]), plt.xticks([]), plt.yticks([])\n    plt.subplot(1,3,3),plt.imshow(images[2],'gray')\n    plt.title(titles[2]), plt.xticks([]), plt.yticks([])\nopenCVdemo()","metadata":{"_uuid":"d0a2b8202d5ccc4593b40f898b3be2d1d2c99e5f","_cell_guid":"89bcd114-a164-478c-9b0e-9ce692c4f8ce","execution":{"iopub.status.busy":"2021-10-20T18:05:37.207392Z","iopub.execute_input":"2021-10-20T18:05:37.207777Z","iopub.status.idle":"2021-10-20T18:05:37.477746Z","shell.execute_reply.started":"2021-10-20T18:05:37.207719Z","shell.execute_reply":"2021-10-20T18:05:37.476984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 3: Load Data*","metadata":{"_uuid":"9c5ac2440aac77162a95a97155f5b50999827783","_cell_guid":"82f61d78-889e-41a1-b6ca-0b4b6afb4729"}},{"cell_type":"code","source":"# Set some parameters\nIMG_WIDTH = 128\nIMG_HEIGHT = 128\nIMG_CHANNELS = 3\nTRAIN_PATH = '/input/stage1_train/'\nTEST_PATH = '/input/stage1_test/'\n\nwarnings.filterwarnings('ignore', category=UserWarning, module='skimage')\nseed = 42\nrandom.seed = seed\nnp.random.seed = seed\n\n# Get train and test IDs\ntrain_ids = next(os.walk(TRAIN_PATH))[1]\ntest_ids = next(os.walk(TEST_PATH))[1]\n\n# Get and resize train images and masks\nX_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('Getting and resizing train 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('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\nprint('Done!')\n\nx_train, x_test, y_train, y_test = train_test_split(X_train, Y_train, test_size=0.2)\nprint('\\nx_train',x_train.shape)\nprint('x_test',x_test.shape)\nprint('y_train',y_train.shape)\nprint('y_test',y_test.shape)","metadata":{"_uuid":"3b6f9a7ebbe8cd8ad29e2412954914bbe61ef77e","_cell_guid":"e148005e-3d83-4aa9-a597-3bb62a9c0be0","execution":{"iopub.status.busy":"2021-10-20T18:05:46.357950Z","iopub.execute_input":"2021-10-20T18:05:46.358265Z","iopub.status.idle":"2021-10-20T18:06:58.225694Z","shell.execute_reply.started":"2021-10-20T18:05:46.358203Z","shell.execute_reply":"2021-10-20T18:06:58.224823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 4: Visualize Training Data*","metadata":{"_uuid":"cf4c4bf670a863b441913b05dd36827ccb42360e","_cell_guid":"5c76e76d-7b69-4140-a7ab-01cfe983159c"}},{"cell_type":"code","source":"def plotTrainData(a,b):\n    for i in range(5):\n        ix = random.randint(0, len(train_ids))\n        plt.subplot(1,2,1)\n        plt.title(\"X_train\")\n        imshow(a[ix])\n        plt.axis('off')\n        plt.subplot(1,2,2)\n        plt.title(\"Y_train\")\n        imshow(np.squeeze(b[ix]))\n        plt.axis('off')\n        plt.show()\nplotTrainData(X_train,Y_train)","metadata":{"scrolled":true,"_uuid":"2b1a1cf6d53fc139f9bbbd40bbb162300cb2db96","_cell_guid":"f9033354-4d31-481c-9cc9-222005f199b5","execution":{"iopub.status.busy":"2021-10-20T18:07:03.022199Z","iopub.execute_input":"2021-10-20T18:07:03.022543Z","iopub.status.idle":"2021-10-20T18:07:03.837906Z","shell.execute_reply.started":"2021-10-20T18:07:03.022492Z","shell.execute_reply":"2021-10-20T18:07:03.837165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 5: Define Helper Functions*","metadata":{"_uuid":"f2123996fea8eefb6869524424d2362a85e6ce22","_cell_guid":"6d98a495-ef36-4f33-9ab1-59eb9b22a201"}},{"cell_type":"code","source":"class MetricsCheckpoint(Callback):\n    \"\"\"Callback that saves metrics after each epoch\"\"\"\n    def __init__(self, savepath):\n        super(MetricsCheckpoint, self).__init__()\n        self.savepath = savepath\n        self.history = {}\n    def on_epoch_end(self, epoch, logs=None):\n        for k, v in logs.items():\n            self.history.setdefault(k, []).append(v)\n        np.save(self.savepath, self.history)\n\ndef plotKerasLearningCurve():\n    plt.figure(figsize=(10,5))\n    metrics = np.load('logs.npy')[()]\n    filt = ['acc'] # try to add 'loss' to see the loss learning curve\n    for k in filter(lambda x : np.any([kk in x for kk in filt]), metrics.keys()):\n        l = np.array(metrics[k])\n        plt.plot(l, c= 'r' if 'val' not in k else 'b', label='val' if 'val' in k else 'train')\n        x = np.argmin(l) if 'loss' in k else np.argmax(l)\n        y = l[x]\n        plt.scatter(x,y, lw=0, alpha=0.25, s=100, c='r' if 'val' not in k else 'b')\n        plt.text(x, y, '{} = {:.4f}'.format(x,y), size='15', color= 'r' if 'val' not in k else 'b')   \n    plt.legend(loc=4)\n    plt.axis([0, None, None, None]);\n    plt.grid()\n    plt.xlabel('Number of epochs')\n\ndef plot_learning_curve(history):\n    plt.figure(figsize=(8,8))\n    plt.subplot(1,2,1)\n    plt.plot(history.history['acc'])\n    plt.plot(history.history['val_acc'])\n    plt.title('model accuracy')\n    plt.ylabel('accuracy')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'test'], loc='upper left')\n    plt.savefig('./accuracy_curve.png')\n    #plt.clf()\n    # summarize history for loss\n    plt.subplot(1,2,2)\n    plt.plot(history.history['loss'])\n    plt.plot(history.history['val_loss'])\n    plt.title('model loss')\n    plt.ylabel('loss')\n    plt.xlabel('epoch')\n    plt.legend(['train', 'test'], loc='upper left')\n    plt.savefig('./loss_curve.png')\n\n# 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)\n\n#RLE encoding for submission\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 = label(x > cutoff)\n    for i in range(1, lab_img.max() + 1):\n        yield rle_encoding(lab_img == i)","metadata":{"_uuid":"fdd98f334783a2b1b20f80b8a4ae454348d2fbfd","_cell_guid":"33c9c73f-6e60-4f9a-933e-a1bfa397c243","execution":{"iopub.status.busy":"2021-10-20T18:07:13.726443Z","iopub.execute_input":"2021-10-20T18:07:13.726751Z","iopub.status.idle":"2021-10-20T18:07:14.123082Z","shell.execute_reply.started":"2021-10-20T18:07:13.726701Z","shell.execute_reply":"2021-10-20T18:07:14.122264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 6: Evaluate Convolutional Network*","metadata":{"_uuid":"c2a8225b0d4bf880b1faee38b3e7bd0866d47804","_cell_guid":"542da5f2-5e34-46f9-be5a-65a654866812"}},{"cell_type":"code","source":"def SIMPLE(a,b,c,d):\n    smooth = 1.\n    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 + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n    def dice_coef_loss(y_true, y_pred):\n        return -dice_coef(y_true, y_pred)\n    simple_cnn = Sequential()\n    simple_cnn.add(BatchNormalization(input_shape = (None, None, IMG_CHANNELS),name = 'NormalizeInput'))\n    simple_cnn.add(Conv2D(8, kernel_size = (3,3), padding = 'same'))\n    simple_cnn.add(Conv2D(8, kernel_size = (3,3), padding = 'same'))\n    # use dilations to get a slightly larger field of view\n    simple_cnn.add(Conv2D(16, kernel_size = (3,3), dilation_rate = 2, padding = 'same'))\n    simple_cnn.add(Conv2D(16, kernel_size = (3,3), dilation_rate = 2, padding = 'same'))\n    simple_cnn.add(Conv2D(32, kernel_size = (3,3), dilation_rate = 3, padding = 'same'))\n    # the final processing\n    simple_cnn.add(Conv2D(16, kernel_size = (1,1), padding = 'same'))\n    simple_cnn.add(Conv2D(1, kernel_size = (1,1), padding = 'same', activation = 'sigmoid'))\n    simple_cnn.summary()\n    checkpointer = ModelCheckpoint('model-dsbowl2018-1.h5', verbose=1, save_best_only=True)\n    earlystopper = EarlyStopping(patience=5, verbose=1)\n    simple_cnn.compile(optimizer = 'adam', \n                       loss = dice_coef_loss, \n                       metrics = [dice_coef, 'acc', 'mse'])\n    history = simple_cnn.fit(x_train,y_train, validation_data=(x_test,y_test),callbacks = [earlystopper, checkpointer, MetricsCheckpoint('logs')],epochs = 30)\n    plot_learning_curve(history)\n    plt.show()\n    plotKerasLearningCurve()\n    plt.show()\n    global modelY\n    modelY = simple_cnn\n    return modelY\nSIMPLE(x_train, y_train,x_test,y_test)","metadata":{"_uuid":"d1eb286840a6551d5cf81baa9baae1af1df986f0","_cell_guid":"8c15a0a3-e866-4261-9075-bd7fad96d3f1","execution":{"iopub.status.busy":"2021-10-20T18:07:24.262024Z","iopub.execute_input":"2021-10-20T18:07:24.262355Z","iopub.status.idle":"2021-10-20T18:07:43.010322Z","shell.execute_reply.started":"2021-10-20T18:07:24.262300Z","shell.execute_reply":"2021-10-20T18:07:43.009477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 7: Display Result and Compare to Training Data*","metadata":{"_uuid":"767308b0fee7074e376b3b236236b627415aa9ca","_cell_guid":"5b73cf1c-92e2-4d2c-95c2-0a16562bd544"}},{"cell_type":"code","source":"def plotPredictions(a,b,c,d,e):\n    model = e\n    # Threshold predictions\n    preds_train = model.predict(a[:int(a.shape[0]*0.9)], verbose=1)\n    preds_val = model.predict(a[int(a.shape[0]*0.9):], verbose=1)\n    preds_test = model.predict(c, verbose=1)\n    preds_train_t = (preds_train > 0.5).astype(np.uint8)\n    preds_val_t = (preds_val > 0.5).astype(np.uint8)\n    preds_test_t = (preds_test > 0.5).astype(np.uint8)\n    # Perform a sanity check on some random training samples\n    ix = random.randint(0, len(preds_train_t))\n    plt.subplot(1,3,1)\n    plt.title(\"X_train\")\n    plt.axis('off')\n    imshow(a[ix])\n    plt.subplot(1,3,2)\n    plt.title(\"Y_train\")\n    plt.axis('off')\n    imshow(np.squeeze(b[ix]))\n    plt.subplot(1,3,3)\n    plt.title(\"Prediction\")\n    plt.axis('off')\n    imshow(np.squeeze(preds_train_t[ix]))\n    plt.show()\n    # Perform a sanity check on some random validation samples\n    ix = random.randint(0, len(preds_val_t))\n    plt.subplot(1,3,1)\n    plt.title(\"X_test\")\n    plt.axis('off')\n    imshow(a[int(a.shape[0]*0.9):][ix])\n    plt.subplot(1,3,2)\n    plt.title(\"Y_test\")\n    plt.axis('off')\n    imshow(np.squeeze(b[int(b.shape[0]*0.9):][ix]))\n    plt.subplot(1,3,3)\n    plt.title(\"Prediction\")\n    plt.axis('off')\n    imshow(np.squeeze(preds_val_t[ix]))\n    plt.show()\nplotPredictions(x_train,y_train,x_test,y_test,modelY)","metadata":{"_uuid":"4af2a17fe169edfd80b2ef8890093505f7046ec4","_cell_guid":"63d0a76a-b3ac-494f-bf65-5e923a0340cb","execution":{"iopub.status.busy":"2021-10-20T18:08:23.678190Z","iopub.execute_input":"2021-10-20T18:08:23.678503Z","iopub.status.idle":"2021-10-20T18:08:24.894685Z","shell.execute_reply.started":"2021-10-20T18:08:23.678453Z","shell.execute_reply":"2021-10-20T18:08:24.893956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 8: Evaluate Convolutional Network with U-Net Architecture*","metadata":{"_uuid":"9bc37568468e2942f99327cf6270cf8522ca07bd","_cell_guid":"074d2f99-1883-41b9-b36a-b0eb9cea5593"}},{"cell_type":"code","source":"def UNET(a,b,c,d):\n    # Build U-Net model\n    inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))\n    s = Lambda(lambda x: x / 255) (inputs)\n    c1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (s)\n    c1 = Dropout(0.1) (c1)\n    c1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c1)\n    p1 = MaxPooling2D((2, 2)) (c1)\n    c2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p1)\n    c2 = Dropout(0.1) (c2)\n    c2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c2)\n    p2 = MaxPooling2D((2, 2)) (c2)\n    c3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p2)\n    c3 = Dropout(0.2) (c3)\n    c3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c3)\n    p3 = MaxPooling2D((2, 2)) (c3)\n    c4 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p3)\n    c4 = Dropout(0.2) (c4)\n    c4 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c4)\n    p4 = MaxPooling2D(pool_size=(2, 2)) (c4)\n    c5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p4)\n    c5 = Dropout(0.3) (c5)\n    c5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c5)\n    u6 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same') (c5)\n    u6 = concatenate([u6, c4])\n    c6 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u6)\n    c6 = Dropout(0.2) (c6)\n    c6 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c6)\n    u7 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (c6)\n    u7 = concatenate([u7, c3])\n    c7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u7)\n    c7 = Dropout(0.2) (c7)\n    c7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c7)\n    u8 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c7)\n    u8 = concatenate([u8, c2])\n    c8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u8)\n    c8 = Dropout(0.1) (c8)\n    c8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c8)\n    u9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (c8)\n    u9 = concatenate([u9, c1], axis=3)\n    c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u9)\n    c9 = Dropout(0.1) (c9)\n    c9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c9)\n    outputs = Conv2D(1, (1, 1), activation='sigmoid') (c9)\n    model = Model(inputs=[inputs], outputs=[outputs])\n    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[mean_iou,'accuracy'])\n    #model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])\n    model.summary()\n    # Fit model\n    earlystopper = EarlyStopping(patience=5, verbose=1)\n    checkpointer = ModelCheckpoint('model-dsbowl2018-2.h5', verbose=1, save_best_only=True)\n    results = model.fit(a,b,batch_size=16,verbose=1,epochs=40,validation_data=(c,d),callbacks = [earlystopper, checkpointer, MetricsCheckpoint('logs')])\n    plot_learning_curve(results)\n    plt.show()\n    plotKerasLearningCurve()\n    plt.show()\n    global modelZ\n    modelZ = model\n    return modelZ\nUNET(x_train, y_train,x_test,y_test)","metadata":{"_uuid":"2fe39e67e8678b9c0875058bfc8766df099f73b2","_cell_guid":"e4046630-bc9b-457a-a6c3-15b5560b8d50","execution":{"iopub.status.busy":"2021-10-20T18:08:29.133355Z","iopub.execute_input":"2021-10-20T18:08:29.133687Z","iopub.status.idle":"2021-10-20T18:10:11.541045Z","shell.execute_reply.started":"2021-10-20T18:08:29.133637Z","shell.execute_reply":"2021-10-20T18:10:11.540261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"*Step 9: Display Result and Compare to Training Data*","metadata":{"_uuid":"98e537ede7e9250252f69297aba735955bf87f05","_cell_guid":"2d4072b3-57d5-4cd5-b747-d5304546b5f2"}},{"cell_type":"code","source":"plotPredictions(x_train,y_train,x_test,y_test,modelZ)","metadata":{"_uuid":"79f0aa5ef0b3c34b76ca3c169c6c4af22f98506d","_cell_guid":"8f0c61e7-5d0a-40c9-bcdd-8a12439e3962","execution":{"iopub.status.busy":"2021-10-20T18:10:36.709081Z","iopub.execute_input":"2021-10-20T18:10:36.709395Z","iopub.status.idle":"2021-10-20T18:10:38.220950Z","shell.execute_reply.started":"2021-10-20T18:10:36.709339Z","shell.execute_reply":"2021-10-20T18:10:38.220230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The results using the U-Net convolutional network are most accurate (i.e. the predicted segmentation mask for X_train is most similar to the provided solution, Y_test).","metadata":{"_uuid":"79c51db952ae3de80a17dbbd166d1f8bf2fab081","_cell_guid":"2600c505-e684-4fe1-a6c6-8d56d3c153e1"}},{"cell_type":"markdown","source":"*Step 10: Save and Submit Results*","metadata":{"_uuid":"cae5f3dd26069dd111cb9dc2c410535ca21426ce","_cell_guid":"fee65846-361c-4499-ae7f-76a16d4240af"}},{"cell_type":"code","source":"#Submit Results for OpenCV Approach\nTEST_PATH = '/input/stage1_test/'\ntest_ids = os.listdir(TEST_PATH)\ntest_image_paths = [glob.glob(join(TEST_PATH, test_id, \"images\", \"*\"))[0] for test_id in test_ids]\n\ndef threshold(image_gray):\n    image_gray = cv2.GaussianBlur(image_gray, (7, 7), 1)\n    ret, thresh = cv2.threshold(image_gray, 0, 255, cv2.THRESH_OTSU)\n    \n    _, cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)\n    cnts = sorted(cnts, key=cv2.contourArea, reverse=True)\n    max_cnt_area = cv2.contourArea(cnts[0])\n    \n    if max_cnt_area > 50000:\n        ret, thresh = cv2.threshold(image_gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)\n    \n    return thresh\n\ndef apply_morphology(thresh):\n    mask = cv2.dilate(thresh, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)))\n    mask = cv2.erode(mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)))\n    return mask\n\nsegmented = []\nfor test_image_path in tqdm(test_image_paths):\n    tmp_image = cv2.imread(test_image_path, cv2.IMREAD_GRAYSCALE)\n    thresh = threshold(tmp_image)\n    mask = apply_morphology(thresh)\n    segmented.append(mask)\n\n# Submit Results for OpenCV Approach\nnew_test_ids = []\nrles = []\nfor n, id_ in enumerate(test_ids):\n    rle = list(prob_to_rles(segmented[n]))\n    rles.extend(rle)\n    new_test_ids.extend([id_] * len(rle))\n\nsubmission_df = pd.DataFrame()\nsubmission_df['ImageId'] = new_test_ids\nsubmission_df['EncodedPixels'] = pd.Series(rles).apply(lambda x: ' '.join(str(y) for y in x))\nsubmission_df.sample(3)\nsubmission_df.to_csv('modelX.csv', index=False)\nprint(\"\\nMethod 1: OpenCV\")\nprint(\"Results Saved\")\n\n# Submit Results for Deep Learning Approaches\ndef saveResults(a,b):        \n    preds_test = a.predict(b, verbose=1)\n    # Create list of upsampled test masks\n    preds_test_upsampled = []\n    for 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))\n    new_test_ids = []\n    rles = []\n    for 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))\n    # Create submission DataFrame\n    sub = pd.DataFrame()\n    sub['ImageId'] = new_test_ids\n    sub['EncodedPixels'] = pd.Series(rles).apply(lambda x: ' '.join(str(y) for y in x))\n    sub.to_csv(a.name+'.csv', index=False)\n    print(\"Results Saved\")\nprint(\"\\nMethod 2: Simple CNN\")\nsaveResults(modelY,X_test)\nprint(\"\\nMethod 3: U-Net CNN\")\nsaveResults(modelZ,X_test)","metadata":{"_uuid":"3398633737ec77f8dd82c08b5d742122ed9fca50","_cell_guid":"9ba06ca2-6a4f-4f6d-84ef-9d722683a8c6","execution":{"iopub.status.busy":"2021-10-20T18:11:05.585630Z","iopub.execute_input":"2021-10-20T18:11:05.585980Z","iopub.status.idle":"2021-10-20T18:11:14.277122Z","shell.execute_reply.started":"2021-10-20T18:11:05.585919Z","shell.execute_reply":"2021-10-20T18:11:14.275840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Credit: Many functions are adaptations from https://www.kaggle.com/kmader/nuclei-overview-to-submission/notebook and https://www.kaggle.com/keegil/keras-u-net-starter-lb-0-277/notebook and https://www.kaggle.com/gaborvecsei/basic-pure-computer-vision-segmentation-lb-0-229.","metadata":{"_uuid":"ddee582772d6a4c292807b17fd2633635e4345db","_cell_guid":"99cd2484-d572-4e1b-a005-a55521823565"}},{"cell_type":"code","source":"import os\nprint(os.listdir(\"./\"))\n# import shutil\n# shutil.rmtree(\"stage1_train.zip\")\n# os.remove(\"stage1_train.zip\")","metadata":{"execution":{"iopub.status.busy":"2021-10-20T18:11:36.659987Z","iopub.execute_input":"2021-10-20T18:11:36.660300Z","iopub.status.idle":"2021-10-20T18:11:36.665786Z","shell.execute_reply.started":"2021-10-20T18:11:36.660249Z","shell.execute_reply":"2021-10-20T18:11:36.665036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!curl https://api.gofile.io/getServer -k","metadata":{"execution":{"iopub.status.busy":"2021-10-20T18:13:48.377696Z","iopub.execute_input":"2021-10-20T18:13:48.378011Z","iopub.status.idle":"2021-10-20T18:13:49.963333Z","shell.execute_reply.started":"2021-10-20T18:13:48.377957Z","shell.execute_reply":"2021-10-20T18:13:49.962569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!curl -F file=@sequential_1.csv https://store2.gofile.io/uploadFile -k","metadata":{"execution":{"iopub.status.busy":"2021-10-20T18:15:20.691974Z","iopub.execute_input":"2021-10-20T18:15:20.692287Z","iopub.status.idle":"2021-10-20T18:15:23.077551Z","shell.execute_reply.started":"2021-10-20T18:15:20.692247Z","shell.execute_reply":"2021-10-20T18:15:23.076729Z"},"trusted":true},"execution_count":null,"outputs":[]}]}