{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport keras\nimport keras.backend as K\nimport os\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data "},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/carvana-image-masking-challenge/train_masks.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2 = pd.read_csv('/kaggle/input/carvana-image-masking-challenge/metadata.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df2.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\n\nx = []\ny = []\nrows, columns = 256, 256\nchannels = 3\nnum_imgs = 200\nfor i,row in df.iterrows():\n    if i >= num_imgs:\n        break\n    img_id = str(row['img'].split('.')[0])\n    img = cv2.imread('../input/carvana-image-masking-challenge/train/{}.jpg'.format(img_id))\n    img = cv2.resize(img, (rows, columns))\n    img = np.asarray(img).astype('float32')\n    img /= 255.0\n    \n    file = '../input/carvana-image-masking-challenge/train_masks/' + img_id + '_mask.gif'\n    new_file = file.split('/')[-1][:-4] + '.jpg'\n    Image.open(file).convert('RGB').save(new_file)\n    mask = cv2.imread(new_file, 0)\n    mask = cv2.resize(mask, (rows, columns))\n    mask = np.asarray(mask).astype('float32')\n    mask /= 255.0\n    \n    x.append(img)\n    y.append(mask)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Image Samples"},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in (0, 8, 100, 108):\n    plt.figure(figsize = (10, 6))\n    plt.subplot(121)\n    plt.imshow(x[i])\n\n    plt.subplot(122)\n    plt.imshow(y[i])\n\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Analysis"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.array(x)\ny = np.array(y)\ny = y.reshape(num_imgs, 256, 256, 1)\nx.shape, y.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.losses import binary_crossentropy\n\ndef dice_coef(y_true, y_pred, smooth = 1):\n    intersection = K.sum(y_true * y_pred)\n    return (2 * intersection + smooth) / ((K.sum(y_true) + K.sum(y_pred)) + smooth)\ndef bce_dice_loss(y_true, y_pred):\n    return .5 * binary_crossentropy(y_true, y_pred) - dice_coef(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#def dice_coef(y_true, y_pred, smooth=1):\n#  intersection = K.sum(y_true * y_pred, axis=[1,2,3])\n#  union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])\n#  dice = K.mean((2. * intersection + smooth)/(union + smooth), axis=0)\n#  return dice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom keras.models import Sequential, Model \nfrom keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, Flatten,concatenate, Dense\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.optimizers import Adam","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.array(x)\ny = np.array(y)\ny = y.reshape(num_imgs, 256, 256, 1)\nx.shape, y.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.losses import binary_crossentropy\n\ndef dice_coef(y_true, y_pred, smooth = 1):\n    intersection = K.sum(y_true * y_pred)\n    return (2 * intersection + smooth) / ((K.sum(y_true) + K.sum(y_pred)) + smooth)\ndef bce_dice_loss(y_true, y_pred):\n    return .5 * binary_crossentropy(y_true, y_pred) - dice_coef(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def unet(input_size = (rows, columns, 3)):\n    input_ = Input(input_size)\n    conv0 = Conv2D(8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(input_)\n    conv0 = Conv2D(8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv0)\n    pool0 = MaxPooling2D(pool_size = (2, 2))(conv0)\n    \n    conv1 = Conv2D(16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool0)\n    conv1 = Conv2D(16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1)\n    pool1 = MaxPooling2D(pool_size = (2, 2))(conv1)\n    \n    conv2 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)\n    conv2 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)\n    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n    \n    conv3 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2)\n    conv3 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3)\n    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n    \n    conv4 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3)\n    conv4 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4)\n    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n    \n    conv5 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4)\n    conv5 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5)\n    \n    up6 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2, 2))(conv5))\n    merge6 = concatenate([conv4, up6], axis = 3)\n    conv6 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6)\n    conv6 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6)\n    \n    up7 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6))\n    merge7 = concatenate([conv3,up7], axis = 3)\n    conv7 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7)\n    conv7 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7)\n\n    up8 = Conv2D(32, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7))\n    merge8 = concatenate([conv2,up8], axis = 3)\n    conv8 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8)\n    conv8 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8)\n                                                                                                  \n    up9 = Conv2D(16, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8))\n    merge9 = concatenate([conv1,up9], axis = 3)\n    conv9 = Conv2D(16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9)\n    conv9 = Conv2D(16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)\n    \n    up10 = Conv2D(16, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv9))\n\n    conv10 = Conv2D(8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(up10)\n    conv11 = Conv2D(1, 1, activation = 'sigmoid')(conv10)\n\n    model = Model(input = input_, outputs = conv11)\n    \n    model.compile(optimizer = Adam(lr = 0.0001), loss = bce_dice_loss, metrics = [dice_coef])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = unet()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fit the model to the training set and compute dice coefficient at each validation set\nmodel_save = ModelCheckpoint('best_model.hdf5', save_best_only=True, monitor='val_loss', mode='min')\n\nmodel_run = model.fit(x, y, epochs = 10,  callbacks=[model_save])\n\nmodel.save(\"saved_model.h5\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Visualizations"},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.DataFrame(model_run.history)[['dice_coef']].plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred= model.predict(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(y_pred[0].reshape(256, 256)) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(y[0].reshape(256, 256))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Extra"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"x = []\ny = []\nfor directory, _, filenames in os.walk('../input/carvana-image-masking-challenge/train'):\n    for filename in filenames[:50]:\n        file = os.path.join(directory, filename)\n        img = cv2.imread(file, cv2.IMREAD_COLOR)\n        if img is not None:\n            img = np.asarray(img) / 255\n            x.append(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for directory, _, filenames in os.walk('../input/carvana-image-masking-challenge/train_masks'):\n    for filename in filenames[:50]:\n        file = os.path.join(directory, filename)\n        img = cv2.imread(file, cv2.IMREAD_COLOR)\n        if img is not None:\n            img = np.asarray(img) / 255\n            y.append(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Images"},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\n%matplotlib inline\n\nimage = cv2.imread('../input/carvana-image-masking-challenge/train/00087a6bd4dc_01.jpg')\nmask = Image.open('../input/carvana-image-masking-challenge/train_masks/00087a6bd4dc_01_mask.gif')\n\nimage2 = cv2.imread('../input/carvana-image-masking-challenge/train/02159e548029_04.jpg')\nmask2 = Image.open('../input/carvana-image-masking-challenge/train_masks/02159e548029_04_mask.gif')\n\nimage3 = cv2.imread('../input/carvana-image-masking-challenge/train/0495dcf27283_12.jpg')\nmask3 = Image.open('../input/carvana-image-masking-challenge/train_masks/0495dcf27283_12_mask.gif')\n\nplt.figure(figsize = (10, 6))\nplt.subplot(231)\nplt.imshow(image)\n\nplt.subplot(234)\nplt.imshow(mask)\n\nplt.subplot(232)\nplt.imshow(image2)\n\n\nplt.subplot(235)\nplt.imshow(mask2)\n\nplt.subplot(233)\nplt.imshow(image3)\n\nplt.subplot(236)\nplt.imshow(mask3)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data Generators"},{"metadata":{"trusted":true},"cell_type":"code","source":"datagen = ImageDataGenerator(\n    rotation_range = 180,\n    shear_range = .2,\n    zoom_range = .2,\n    horizontal_flip = True,\n    rescale = 1/255,\n    fill_mode = 'nearest')\n\ntest_datagen = ImageDataGenerator(rescale = 1/255)\nif K.image_data_format() == 'channels_first':\n    input_shape = (3, 150, 150)\nelse:\n    input_shape = (150, 150, 3)\n    \ntrain = datagen.flow_from_directory('intel-image-classification/seg_train/seg_train/',\n                                    target_size = (150, 150),\n                                    batch_size = 64,\n                                    class_mode = 'categorical')\ntest = test_datagen.flow_from_directory('intel-image-classification/seg_test/seg_test',\n                                        target_size = (150, 150),\n                                        batch_size = 64,\n                                        class_mode = 'categorical')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"## Tiramisu"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Model, load_model\nfrom keras.layers import Input, LSTM, Dense, Conv2D, MaxPooling2D, Reshape, Dropout, BatchNormalization, Activation, Conv2DTranspose, Add, concatenate\nfrom keras.models import model_from_json\nfrom keras.regularizers import l2\n\nclass Model_Tiramisu():\n    \n    def __init__(self):\n        \n        self.model = self.build_model()\n    def fit_model(self, x, y, epochs = 10,validation_split = .2, workers = 6): \n        self.model.fit(x, y, epochs =epochs,\n                      validation_split =validation_split ,\n                      workers = 6)\n        \n    def build_model(self):\n        \n        layer_per_block = [3, 3, 3, 3, 3, 4, 12, 10, 7, 5, 4]\n        \n        model = self.build_graph(layer_per_block, n_pool=5, growth_rate=16)    \n\n        model.compile(loss = [bce_dice_loss], optimizer = 'adam', metrics = [dice_coef])\n\n        return model\n\n    def denseBlock(self, t, nb_layers):\n        for _ in range(nb_layers):\n            tmp = t\n            t = BatchNormalization(axis = -1,\n                                    gamma_regularizer = l2(0.0001),\n                                    beta_regularizer = l2(0.0001))(t)\n\n            t = Activation('relu')(t)\n            t = Conv2D(16, kernel_size = (3, 3), padding = 'same', kernel_initializer = 'he_uniform', data_format = 'channels_last')(t)\n            t = Dropout(0.2)(t)\n            t = concatenate([t, tmp])\n        return t\n\n    def transitionDown(self, t, nb_features):\n        t = BatchNormalization(axis = -1,\n                               gamma_regularizer = l2(0.0001),\n                               beta_regularizer = l2(0.0001))(t)\n        t = Activation('relu')(t)\n        t = Conv2D(nb_features,\n                   kernel_size = (1, 1),\n                   padding = 'same',\n                   kernel_initializer = 'he_uniform',\n                   data_format='channels_last')(t)\n        t = Dropout(0.2)(t)\n        t = MaxPooling2D(pool_size = (2, 2),\n                         strides = 2,\n                         padding = 'same',\n                         data_format = 'channels_last')(t)\n        \n        return t\n\n    def build_graph(self, layer_per_block, n_pool = 3, growth_rate = 16):\n        input_layer = Input(shape = (256, 256, 3))\n        t = Conv2D(48, kernel_size = (3, 3), strides = (1, 1), padding = 'same')(input_layer)\n\n        #dense block\n        nb_features = 48\n        skip_connections = []\n        for i in range(n_pool):\n            t = self.denseBlock(t, layer_per_block[i])\n            skip_connections.append(t)\n            nb_features += growth_rate * layer_per_block[i]\n            t = self.transitionDown(t, nb_features)\n\n        t = self.denseBlock(t, layer_per_block[n_pool]) # bottle neck\n\n        skip_connections = skip_connections[::-1] #subvert the array\n\n        for i in range(n_pool):\n            keep_nb_features = growth_rate * layer_per_block[n_pool + i]\n            t = Conv2DTranspose(keep_nb_features, strides=2, kernel_size=(3, 3), padding='same', data_format='channels_last')(t) # transition Up\n            t = concatenate([t, skip_connections[i]])\n\n            t = self.denseBlock(t, layer_per_block[n_pool + i + 1])\n\n        t = Conv2D(1, kernel_size=(1, 1), padding='same', kernel_initializer='he_uniform', data_format='channels_last')(t)\n        output_layer = Activation('softmax')(t)\n\n        return Model(inputs = input_layer, outputs = output_layer)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x.shape,y.shape ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Model_Tiramisu()\n# Fit the model to the training set and compute dice coefficient at each validation set\nmodel_save = ModelCheckpoint('best_model.hdf5',\n                             save_best_only = True,\n                             monitor = 'bce_dice_loss',\n                             mode = 'min')\n\nmodel_run = model.fit_model(x, y,\n                      epochs = 10,\n                      validation_split = .2,\n                      #callbacks=[model_save],\n                      workers = 6)\n\nmodel.save(\"saved_model.h5\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}