{"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": "import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom skimage.io import imread\nfrom skimage.transform import downscale_local_mean\nfrom os.path import join\nfrom tqdm import tqdm_notebook\nimport cv2\nfrom sklearn.model_selection import train_test_split\n\ninput_folder = join('..', 'input')\n\ndf_mask = pd.read_csv(join(input_folder, 'train_masks.csv'), usecols=['img'])\nids_train = df_mask['img'].map(lambda s: s.split('_')[0]).unique()\n\nimgs_idx = list(range(1, 17))", "metadata": {"trusted": false, "_cell_guid": "a7dd7f70-348f-4e49-a7be-b85543df6ec2", "_uuid": "da289a8da91de630b07363d12be05cd997bd3c08", "_execution_state": "idle"}}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "ec3cbbbc51dbf8d460e1dfe27c0a9d4684e2f417", "_cell_guid": "e2d4c1aa-6632-4ab2-9ebc-4010ae62d4fd", "_execution_state": "idle", "trusted": false}, "source": "load_img = lambda im, idx: imread(join(input_folder, 'train', '{}_{:02d}.jpg'.format(im, idx)))\nload_mask = lambda im, idx: imread(join(input_folder, 'train_masks', '{}_{:02d}_mask.gif'.format(im, idx)))\nresize = lambda im: downscale_local_mean(im, (4,4) if im.ndim==2 else (4,4,1))\nmask_image = lambda im, mask: (im * np.expand_dims(mask, 2))"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "f7cf80499f3276ad7515cbc4e6beb4b3aa6025b5", "_cell_guid": "a326095e-915d-4010-89d9-e5fdae29557e", "_execution_state": "busy", "trusted": false}, "source": "num_train = 32  # len(ids_train)\n\n# Load data for position id=1\nX = np.empty((num_train, 320, 480, 12), dtype=np.float32)\ny = np.empty((num_train, 320, 480, 1), dtype=np.float32)\n\nwith tqdm_notebook(total=num_train) as bar:\n    idx = 1 # Rotation index\n    for i, img_id in enumerate(ids_train[:num_train]):\n        imgs_id = [resize(load_img(img_id, j)) for j in imgs_idx]\n        # Input is image + mean image per channel + std image per channel\n        X[i, ..., :9] = np.concatenate([imgs_id[idx-1], np.mean(imgs_id, axis=0), np.std(imgs_id, axis=0)], axis=2)\n        y[i] = resize(np.expand_dims(load_mask(img_id, idx), 2)) / 255.\n        del imgs_id # Free memory\n        bar.update()"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "1ddd542d69fb2864eb7b249f2725e761dc88fe65", "_cell_guid": "76f63a38-9d44-4f41-bd11-e9de85e7153a", "_execution_state": "idle", "trusted": false}, "source": "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "d2b36b72192a699865dcf47a86bf1d1cc35a44fe", "_cell_guid": "d1aec6c7-7ac0-48e2-9e15-7ae758c25192", "_execution_state": "idle", "trusted": false}, "source": "# Concat overall y info to X\n# This is important as the kernels of CNN used below has no information of its location\ny_train_mean = y_train.mean(axis=0)\ny_train_std = y_train.std(axis=0)\ny_train_min = y_train.min(axis=0)\n\ny_features = np.concatenate([y_train_mean, y_train_std, y_train_min], axis=2)\n\nX_train[:, ..., -3:] = y_features\nX_val[:, ..., -3:] = y_features"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "04091a9270eaf4a1decfc5c57493118b75b24a79", "_cell_guid": "989df4b5-d155-4353-b4c1-e7dbed04e554", "_execution_state": "idle", "trusted": false}, "source": "# Normalize input and output\nX_mean = X_train.mean(axis=(0,1,2), keepdims=True)\nX_std = X_train.std(axis=(0,1,2), keepdims=True)\n\nX_train -= X_mean\nX_train /= X_std\n\nX_val -= X_mean\nX_val /= X_std"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "a10d2e2d5dda8ca70550548e811bcd045b7cf3fc", "_cell_guid": "0063e2ce-1679-424a-befa-68b82d2c0ab8", "_execution_state": "idle", "trusted": false}, "source": "# Create simple model\nfrom keras.layers import Conv2D\nfrom keras.models import Sequential\nimport keras.backend as K\n\nmodel = Sequential()\nmodel.add( Conv2D(16, 3, activation='relu', padding='same', input_shape=(320, 480, 12) ) )\nmodel.add( Conv2D(32, 3, activation='relu', padding='same') )\nmodel.add( Conv2D(1, 5, activation='sigmoid', padding='same') )"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "446deb6830d09d449b9580563566027ca5563afa", "_cell_guid": "32e333e1-e7e7-4764-8fbd-80f1e88c5b70", "_execution_state": "idle", "trusted": false}, "source": "from keras.optimizers import Adam\nfrom keras.losses import binary_crossentropy\n\nsmooth = 1.\n\n# From here: https://github.com/jocicmarko/ultrasound-nerve-segmentation/blob/master/train.py\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\n\ndef bce_dice_loss(y_true, y_pred):\n    return 0.5 * binary_crossentropy(y_true, y_pred) - dice_coef(y_true, y_pred)\n\nmodel.compile(Adam(lr=1e-3), bce_dice_loss, metrics=['accuracy', dice_coef])"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "337205abca7bdd6064ecccfb612b3fb5cb587a54", "_cell_guid": "166062b9-66fe-4cdb-bb0f-2dbac4fdbafe", "_execution_state": "idle", "trusted": false}, "source": "history = model.fit(X_train, y_train, epochs=15, validation_data=(X_val, y_val), batch_size=5, verbose=2)"}, {"outputs": [], "metadata": {"collapsed": false, "_uuid": "d461bec0b38d15f398f63faf5c5f721634b80546", "_cell_guid": "b39b0f0e-fe0d-4666-951e-77925a4c6a53", "_execution_state": "idle"}, "cell_type": "code", "source": "pd.DataFrame(history.history)[['dice_coef', 'val_dice_coef']].plot()", "execution_count": 15}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "45c065685f88d6bd1ec33a429c28e3a36cd52588", "_cell_guid": "06b5003e-a4ba-49dd-a488-be92b362975e", "_execution_state": "idle", "trusted": false}, "source": "idx = 0\nx = X_val[idx]\n\nfig, ax = plt.subplots(5,3, figsize=(16, 16))\nax = ax.ravel()\n\ncmaps = ['Reds', 'Greens', 'Blues']\nfor i in range(x.shape[-1]):\n    ax[i].imshow(x[...,i], cmap='gray') #cmaps[i%3])\n    ax[i].set_title('channel {}'.format(i))\n\nax[-3].imshow((x[...,:3] * X_std[0,...,:3] + X_mean[0,...,:3]) / 255.)\nax[-3].set_title('X')\n\nax[-2].imshow(y_train[idx,...,0], cmap='gray')\nax[-2].set_title('y')\n\ny_pred = model.predict(x[None]).squeeze()\nax[-1].imshow(y_pred, cmap='gray')\nax[-1].set_title('y_pred')"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "344427a75091f65fdb01ea0b352c436847c47093", "_cell_guid": "cadf3a5c-f63f-4836-8050-9cac33507b12", "_execution_state": "idle", "trusted": false}, "source": "plt.imshow(y_pred > 0.5, cmap='gray')"}, {"outputs": [], "cell_type": "code", "execution_count": null, "metadata": {"collapsed": false, "_uuid": "c298fc64a6b516140687f2241d90f75cf0e5f622", "_cell_guid": "e4ff72f4-1a7e-42c0-9e70-c9db615b13fe", "_execution_state": "idle", "trusted": false}, "source": ""}], "nbformat_minor": 0, "nbformat": 4}