text_plain_output_1.png
from PIL import Image

from keras.callbacks import ModelCheckpoint

from keras.layers import Input, BatchNormalization, Activation,Softmax

from keras.layers.convolutional import Conv2D, Conv2DTranspose

from keras.layers.merge import concatenate

from keras.layers.pooling import MaxPooling2D

from keras.models import Model

import numpy as np

import os

import seaborn as sns

EPOCHS = 10
BATCH_SIZE = 17
HEIGHT = 256
WIDTH = 256
N_CLASSES = 13

def LoadImage(name, path):
    img = Image.open(os.path.join(path, name))
    img = np.array(img)
    image = img[:, :256]
    mask = img[:, 256:]
    return (image, mask)
def bin_image(mask):
    bins = np.array([20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240])
    new_mask = np.digitize(mask, bins)
    return new_mask
def getSegmentationArr(image, classes, width=WIDTH, height=HEIGHT):
    seg_labels = np.zeros((height, width, classes))
    img = image[:, :, 0]
    for c in range(classes):
        seg_labels[:, :, c] = (img == c).astype(int)
    return seg_labels
def give_color_to_seg_img(seg, n_classes=N_CLASSES):
    seg_img = np.zeros((seg.shape[0], seg.shape[1], 3)).astype('float')
    colors = sns.color_palette('hls', n_classes)
    for c in range(n_classes):
        segc = seg == c
        seg_img[:, :, 0] += segc * colors[c][0]
        seg_img[:, :, 1] += segc * colors[c][1]
        seg_img[:, :, 2] += segc * colors[c][2]
    return seg_img
classes = 13

train_folder = '../input/cityscapes-image-pairs/cityscapes_data/train'
valid_folder = '../input/cityscapes-image-pairs/cityscapes_data/val'
num_of_training_samples = len(os.listdir(train_folder))
num_of_valid_samples = len(os.listdir(valid_folder))
def DataGenerator(path, batch_size=BATCH_SIZE, classes=N_CLASSES):
    files = os.listdir(path)
    while True:
        for i in range(0, len(files), batch_size):
            batch_files = files[i:i + batch_size]
            imgs = []
            segs = []
            for file in batch_files:
                image, mask = LoadImage(file, path)
                mask_binned = bin_image(mask)
                labels = getSegmentationArr(mask_binned, classes)
                imgs.append(image)
                segs.append(labels)
            yield (np.array(imgs), np.array(segs))

train_gen = DataGenerator(train_folder, batch_size=BATCH_SIZE)
val_gen = DataGenerator(valid_folder, batch_size=BATCH_SIZE)

def conv2d_block(input_tensor, n_filters, kernel_size=3):
    x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer='he_normal', padding='same')(input_tensor)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(filters=n_filters, kernel_size=(kernel_size, kernel_size), kernel_initializer='he_normal', padding='same')(input_tensor)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    return x

def get_unet(n_filters=16):
    inputs = Input((HEIGHT, WIDTH, 3))
    c1 = conv2d_block(inputs, n_filters * 1, kernel_size=3)
    p1 = MaxPooling2D((2, 2))(c1)
    c2 = conv2d_block(p1, n_filters * 2, kernel_size=3)
    p2 = MaxPooling2D((2, 2))(c2)
    c3 = conv2d_block(p2, n_filters * 4, kernel_size=3)
    p3 = MaxPooling2D((2, 2))(c3)
    c4 = conv2d_block(p3, n_filters * 8, kernel_size=3)
    p4 = MaxPooling2D((2, 2))(c4)
    c5 = conv2d_block(p4, n_filters=n_filters * 16, kernel_size=3)
    p5 = MaxPooling2D((2, 2))(c5)
    c6 = conv2d_block(p5, n_filters=n_filters * 32, kernel_size=3)
    u7 = Conv2DTranspose(n_filters * 16, (3, 3), strides=(2, 2), padding='same')(c6)
    u7 = concatenate([u7, c5])
    c7 = conv2d_block(u7, n_filters * 16, kernel_size=3)
    u8 = Conv2DTranspose(n_filters * 8, (3, 3), strides=(2, 2), padding='same')(c7)
    u8 = concatenate([u8, c4])
    c8 = conv2d_block(u8, n_filters * 8, kernel_size=3)
    u9 = Conv2DTranspose(n_filters * 4, (3, 3), strides=(2, 2), padding='same')(c8)
    u9 = concatenate([u9, c3])
    c9 = conv2d_block(u9, n_filters * 4, kernel_size=3)
    u10 = Conv2DTranspose(n_filters * 2, (3, 3), strides=(2, 2), padding='same')(c9)
    u10 = concatenate([u10, c2])
    c10 = conv2d_block(u10, n_filters * 2, kernel_size=3)
    u11 = Conv2DTranspose(n_filters * 1, (3, 3), strides=(2, 2), padding='same')(c10)
    u11 = concatenate([u11, c1])
    c11 = conv2d_block(u11, n_filters * 1, kernel_size=3)
    outputs = Conv2D(13, (1, 1), activation='sigmoid')(c11)
    model = Model(inputs, outputs=[outputs])
    return model

checkpoint = ModelCheckpoint('unet_model.hdf5', monitor='val_acc', verbose=1, save_best_only=True, mode='max')

model = get_unet()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()

TRAIN_STEPS = num_of_training_samples // BATCH_SIZE + 1
VAL_STEPS = num_of_valid_samples // BATCH_SIZE + 1
results = model.fit(train_gen, validation_data=val_gen, steps_per_epoch=TRAIN_STEPS, validation_steps=VAL_STEPS, epochs=EPOCHS, callbacks=checkpoint)