Files
pipe-segmentation/notebook.ipynb
T
2016-09-28 12:01:04 +08:00

2.0 MiB
Raw Blame History

Intro

This presents a proof of concept for a new application, pipe detection from aerial drone images.

See the readme.md for more.

In [1]:
import os
os.environ['THEANO_FLAGS']='mode=FAST_RUN,device=gpu,floatX=float32'
In [2]:
import skimage
from skimage import transform, color

from matplotlib import pyplot as plt
import numpy as np
# import pandas as pd
# import scipy as sp
import seaborn as sns
%matplotlib inline

# import h5py 
# import shapely
# from shapely import geometry, affinity

from path import Path
# import json
import arrow
from tqdm import tqdm

import keras
from keras.preprocessing import image
Using Theano backend.
Using gpu device 0: GeForce GTX 860M (CNMeM is disabled, cuDNN 4007)
In [3]:
plt.rcParams['figure.figsize']=(10,10)
In [4]:
from keras.models import Model
from keras.layers import Input, merge, Convolution2D, MaxPooling2D, UpSampling2D
from keras.optimizers import Adam
from keras.callbacks import ModelCheckpoint, LearningRateScheduler
from keras import backend as K

Test we have my PR to keras

Note this uses Keras with my prs

pip install https://github.com/wassname/keras/archive/patch-1.zip
In [7]:
from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28)
X_train = X_train.astype('float32')

data_gen_args=dict(horizontal_flip=True,vertical_flip=True,rotation_range=90.,width_shift_range=0.2,
                 height_shift_range=0.2, zoom_range=0.2,)
datagen1 = ImageDataGenerator(**data_gen_args)
datagen2 = ImageDataGenerator(**data_gen_args)

seed=1
batch_size=3
gen1=datagen1.flow(X_train, y_train, batch_size=batch_size ,seed=seed, shuffle=True)
gen2=datagen2.flow(X_train, y_train, batch_size=batch_size, seed=seed, shuffle=True)


for i in range(10):
    X_train1, y_train1=next(gen1)
    X_train2, y_train2=next(gen2)
    for b in range(batch_size-1):
        assert (X_train1[b]==X_train2[b]).all()
        assert (y_train1[b]==y_train2[b]).all()
print('✓ ImageDataGenerator is repeatable')
✓ ImageDataGenerator is repeatable

Load data

Our source data are split 1:2 for testing and training. These where augumented by:

  • random rotations up to 360 degrees
  • up to 80% horizontal and vertical translations
  • zoom of 80%
  • shear of up to 10 degrees
  • jitter of 1% for each color channel

Then resized to 80x112 for training.

In [8]:
img_rows = 80
img_cols = 112
batch_size=10
output_shape=(img_rows,img_cols)
In [12]:
dest_dir = Path('./data/augumented/train')
dest_dir_test = Path('./data/augumented/test')

# make sure image match
images=sorted(dest_dir.glob('image/*.png'))
masks=sorted(dest_dir.glob('mask/*.png'))
assert len(dest_dir.glob('image/*.png'))==len(dest_dir.glob('mask/*.png')), 'should be same number of pngs'
for i,[image,mask] in enumerate(zip(images,masks)):
    assert image.basename()==mask.basename(),'i=%s %s!=%s'%(i,image.basename(),mask.basename())
In [13]:
data_gen_args=dict(
                rotation_range=10.,
                width_shift_range=0.1,
                height_shift_range=0.1,
                shear_range=np.deg2rad(10),
                zoom_range=0.1,
                channel_shift_range=0.01,
                fill_mode='constant',
                horizontal_flip=True,
                vertical_flip=True,
                rescale=1/255.
)

datagen1 = ImageDataGenerator(**data_gen_args)
datagen2 = ImageDataGenerator(**data_gen_args)

image_gen=datagen1.flow_from_directory(dest_dir, 
                                  class_mode=None, 
                                  classes=['image'], 
                                  batch_size=batch_size, 
                                  seed=seed,
                                  target_size=output_shape,
                                 )
mask_gen=datagen2.flow_from_directory(dest_dir, 
                                  class_mode=None, 
                                  classes=['mask'], 
                                  batch_size=batch_size, 
                                  seed=seed,
                                  target_size=output_shape,
                                 )


# join the generators (converting the mask to greyscale)
def dual_gen(image_gen,mask_gen):
    for image,mask in zip(image_gen,mask_gen):
        mask=skimage.color.rgb2grey(np.transpose(mask,(0,2,3,1)))
        yield image,mask

train_gen=dual_gen(image_gen,mask_gen)

X_train, y_train=next(train_gen)
X_train.shape, y_train.shape
Out [13]:
Found 3870 images belonging to 1 classes.
Found 3870 images belonging to 1 classes.
((10, 3, 80, 112), (10, 80, 112))
In [14]:
# test gen
data_gen_args=dict(
                fill_mode='constant',
                rescale=1/255.
)

datagen_test1 = ImageDataGenerator(**data_gen_args)
datagen_test2 = ImageDataGenerator(**data_gen_args)

image_gen_test=datagen_test1.flow_from_directory(dest_dir_test, 
                                  class_mode=None, 
                                  classes=['image'], 
                                  batch_size=batch_size, 
                                  seed=seed,
                                  target_size=output_shape,
                                 )
mask_gen_test=datagen_test2.flow_from_directory(dest_dir_test, 
                                  class_mode=None, 
                                  classes=['mask'], 
                                  batch_size=batch_size, 
                                  seed=seed,
                                  target_size=output_shape,
                                 )

# join the generators
def dual_gen(image_gen,mask_gen):
    for image,mask in zip(image_gen,mask_gen):
        mask=skimage.color.rgb2grey(np.transpose(mask,(0,2,3,1)))
        yield image,mask

test_gen=dual_gen(image_gen_test,mask_gen_test)

X_test, y_test=next(test_gen)
X_test.shape, y_test.shape
Out [14]:
Found 503 images belonging to 1 classes.
Found 503 images belonging to 1 classes.
((10, 3, 80, 112), (10, 80, 112))
In [63]:
# train gen, but this time un-augumented so I can directly compare them for overfitting
data_gen_args=dict(
                fill_mode='constant',
                rescale=1/255.
)

datagen_test1b = ImageDataGenerator(**data_gen_args)
datagen_test2b = ImageDataGenerator(**data_gen_args)

image_gen_train2=datagen_test1b.flow_from_directory(dest_dir, 
                                  class_mode=None, 
                                  classes=['image'], 
                                  batch_size=batch_size, 
                                  seed=seed,
                                  target_size=output_shape,
                                 )
mask_gen_train2=datagen_test2b.flow_from_directory(dest_dir, 
                                  class_mode=None, 
                                  classes=['mask'], 
                                  batch_size=batch_size, 
                                  seed=seed,
                                  target_size=output_shape,
                                 )

# join the generators
def dual_gen(image_gen,mask_gen):
    for image,mask in zip(image_gen,mask_gen):
        mask=skimage.color.rgb2grey(np.transpose(mask,(0,2,3,1)))
        yield image,mask

train_gen_unaugumented=dual_gen(image_gen_train2,mask_gen_train2)

X_test, y_test=next(train_gen_unaugumented)
X_test.shape, y_test.shape
Out [63]:
Found 3870 images belonging to 1 classes.
Found 3870 images belonging to 1 classes.
((10, 3, 80, 112), (10, 80, 112))

Note: please check the images and mask match!

If they don't you probobly have the wrong version of keras. Use: pip install https://github.com/wassname/keras/archive/patch-1.zip

In [16]:
# View some of the data
seed=1
n=5
rows=n
cols=4

pltnb=0
plt.figure(figsize=(15,rows*2))
for i in range(n):
    X_train, y_train=next(train_gen)
    for b in range(2):
        # create a grid of 3x2
        pltnb+=1
        plt.subplot(rows,cols,pltnb)
        plt.title('i=%s batchn=%s datagen1'%(i,b))
        plt.imshow(np.transpose(X_train[b],(1,2,0)))
        plt.colorbar()
        plt.axis('off')


        pltnb+=1
        plt.subplot(rows,cols,pltnb)
        
        plt.title('i=%s batchn=%s gen2'%(i,b))
        plt.imshow(y_train[b], cmap=plt.get_cmap('gray'))
        plt.colorbar()
        plt.axis('off')
plt.tight_layout()
plt.show()
In [203]:
# show data dist
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
sns.distplot(X_train.flatten())
plt.title('X')

plt.subplot(1,2,2)
sns.distplot(y_train.flatten())
plt.title('y')
Out [203]:
<matplotlib.text.Text at 0x7fb864bca0f0>

Metrics

We use the SørensenDice coefficient after transforming it to [0-1] and smoothing it to a ~L1 (linear) loss.

L = 1-\frac{ 2 \sum_i|A_i B_i|+ \delta}{\sum_i A_i^2 + B_i^2 + \delta}
In [38]:
# define custom loss and metric functions 

from keras import backend as K
smooth = 1

def dice_coef(y_true, y_pred, smooth=1):
    """
    Dice =  2*sum(|A*B|)/(sum(A^2)+sum(B^2))
    ref: https://arxiv.org/pdf/1606.04797v1.pdf
    """
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    return (2. * intersection + smooth) / (K.sum(K.square(y_true),-1) + K.sum(K.square(y_pred),-1) + smooth)

# I think the missing one was a mistake, because it made loss(y_true,y_true)=-1
def dice_coef_loss(y_true, y_pred):
    return 1-dice_coef(y_true, y_pred)

Model

model_diagram The model architecture. Each box is a inception module or convolution with the number of feature layers denotes in brackets. The output size is denoted below the box and the arrows denote differen't operation.

inception_module The inception module used in this paper, as originally proposed in 1 .


  1. https://arxiv.org/pdf/1512.00567v3.pdf "Rethinking the Inception Architecture for Computer Vision" ↩︎

In [45]:
import sys
from keras.models import Model
from keras.layers import Input, merge, Convolution2D, MaxPooling2D, UpSampling2D, Dense
from keras.layers import BatchNormalization, Dropout, Flatten, Lambda, Reshape
from keras.layers.advanced_activations import ELU, LeakyReLU
from keras import backend as K


def unet_inception_model(optimiser, img_cols=512, img_rows=512, main_act=LeakyReLU, dropout=0.5):

    def inception_block(inputs, depth, batch_mode=0, splitted=False, activation='relu'):
        """Inception block  v1 with asymetric convolutions"""
        assert depth % 16 == 0
        actv = activation == 'relu' and (lambda: LeakyReLU(0.0)) or activation == 'elu' and (lambda: ELU(1.0)) or None

        c1_1 = Convolution2D(int(depth/4), 1, 1, init='he_normal', border_mode='same')(inputs)

        c2_1 = Convolution2D(int(depth/8*3), 1, 1, init='he_normal', border_mode='same')(inputs)
        c2_1 = actv()(c2_1)
        if splitted:
            c2_2 = Convolution2D(int(depth/2), 1, 3, init='he_normal', border_mode='same')(c2_1)
            c2_2 = BatchNormalization(mode=batch_mode, axis=1)(c2_2)
            c2_2 = actv()(c2_2)
            c2_3 = Convolution2D(int(depth/2), 3, 1, init='he_normal', border_mode='same')(c2_2)
        else:
            c2_3 = Convolution2D(int(depth/2), 3, 3, init='he_normal', border_mode='same')(c2_1)

        c3_1 = Convolution2D(int(depth/16), 1, 1, init='he_normal', border_mode='same')(inputs)
        #missed batch norm
        c3_1 = actv()(c3_1)
        if splitted:
            c3_2 = Convolution2D(int(depth/8), 1, 5, init='he_normal', border_mode='same')(c3_1)
            c3_2 = BatchNormalization(mode=batch_mode, axis=1)(c3_2)
            c3_2 = actv()(c3_2)
            c3_3 = Convolution2D(int(depth/8), 5, 1, init='he_normal', border_mode='same')(c3_2)
        else:
            c3_3 = Convolution2D(int(depth/8), 5, 5, init='he_normal', border_mode='same')(c3_1)

        p4_1 = MaxPooling2D(pool_size=(3,3), strides=(1,1), border_mode='same')(inputs)
        c4_2 = Convolution2D(int(depth/8), 1, 1, init='he_normal', border_mode='same')(p4_1)

        res = merge([c1_1, c2_3, c3_3, c4_2], mode='concat', concat_axis=1)
        res = BatchNormalization(mode=batch_mode, axis=1)(res)
        res = actv()(res)
        return res


    def residual_skip(inputs, num, depth, scale=0.1):
        """
        A skip connection with a branch to a residual block

               / 1x1conv \
        input ---------- - output
        """
        residual = Convolution2D(depth, num, num, border_mode='same')(inputs)
        residual = BatchNormalization(mode=2, axis=1)(residual)
        residual = Lambda(lambda x: x*scale)(residual)
        res = merge([inputs, residual], mode="sum")
        # res = _shortcut(inputs, residual)
        return main_act()(res)


    def reduction_block(nb_filter, nb_row, nb_col, border_mode='same', subsample=(1, 1)):
        """Downsampling using a strided convolution followed by batchnorm and activation"""
        def f(_input):
            conv = Convolution2D(nb_filter=nb_filter, nb_row=nb_row, nb_col=nb_col, subsample=subsample,
                                  border_mode=border_mode)(_input)
            norm = BatchNormalization(mode=2, axis=1)(conv)
            return main_act()(norm)

        return f

    def get_unet_inception_2head(optimizer):
        splitted = True
        act = 'relu'

        inputs = Input((3, img_rows, img_cols), name='main_input')
        conv1 = inception_block(inputs, 32, batch_mode=2, splitted=splitted, activation=act)

        pool1 = reduction_block(32, 3, 3, border_mode='same', subsample=(2,2))(conv1)
        pool1 = Dropout(dropout)(pool1)

        conv2 = inception_block(pool1, 64, batch_mode=2, splitted=splitted, activation=act)
        pool2 = reduction_block(64, 3, 3, border_mode='same', subsample=(2,2))(conv2)
        pool2 = Dropout(dropout)(pool2)

        conv3 = inception_block(pool2, 128, batch_mode=2, splitted=splitted, activation=act)
        pool3 = reduction_block(128, 3, 3, border_mode='same', subsample=(2,2))(conv3)
        pool3 = Dropout(dropout)(pool3)

        conv4 = inception_block(pool3, 256, batch_mode=2, splitted=splitted, activation=act)
        pool4 = reduction_block(256, 3, 3, border_mode='same', subsample=(2,2))(conv4)
        pool4 = Dropout(dropout)(pool4)

        conv5 = inception_block(pool4, 512, batch_mode=2, splitted=splitted, activation=act)
        conv5 = Dropout(dropout)(conv5)

        after_conv4 = residual_skip(conv4, 1, 256)
        up6 = merge([UpSampling2D(size=(2, 2))(conv5), after_conv4], mode='concat', concat_axis=1)
        conv6 = inception_block(up6, 256, batch_mode=2, splitted=splitted, activation=act)
        conv6 = Dropout(dropout)(conv6)

        after_conv3 = residual_skip(conv3, 1, 128)
        up7 = merge([UpSampling2D(size=(2, 2))(conv6), after_conv3], mode='concat', concat_axis=1)
        conv7 = inception_block(up7, 128, batch_mode=2, splitted=splitted, activation=act)
        conv7 = Dropout(dropout)(conv7)

        after_conv2 = residual_skip(conv2, 1, 64)
        up8 = merge([UpSampling2D(size=(2, 2))(conv7), after_conv2], mode='concat', concat_axis=1)
        conv8 = inception_block(up8, 64, batch_mode=2, splitted=splitted, activation=act)
        conv8 = Dropout(dropout)(conv8)

        after_conv1 = residual_skip(conv1, 1, 32)
        up9 = merge([UpSampling2D(size=(2, 2))(conv8), after_conv1], mode='concat', concat_axis=1)
        conv9 = inception_block(up9, 32, batch_mode=2, splitted=splitted, activation=act)
        conv9 = Dropout(dropout)(conv9)

        conv10 = Convolution2D(1, 1, 1, init='he_normal', activation='hard_sigmoid')(conv9)
        reshp = Reshape((img_rows,img_cols), name='main_output')(conv10)

        model = Model(input=inputs, output=reshp)
        model.compile(optimizer=optimizer,
                      loss=[dice_coef_loss],
                      metrics=['accuracy']
                     )

        return model

    return get_unet_inception_2head(optimiser)

Train

Training

We used a Adam optimizer with Nesterov momentum with a learning rate of 0.0002 and decay of 1e-5 per epoch. We trained with 300 samples per epoch for 160 epochs with a batch size of 10.

This acheived an accuracy of 0.15 on the training data and 0.99 on the test data. This is because the varience of the training data was augumented with jittering.

Attempts

  • optimizer = keras.optimizers.Nadam(lr=2e-4,schedule_decay=1e-5), samples 300 epochs 300, 0.9-0.15
In [21]:
model_name='unet_inception_inv2'
optimizer = keras.optimizers.Nadam(lr=2e-4)
model = unet_inception_model(optimizer,img_cols,img_rows,LeakyReLU,dropout=0.5)
model_checkpoint = ModelCheckpoint('models/%s_weights.hdf5'%model_name, monitor='val_acc', save_best_only=True, save_weights_only=True)
early_stopping = keras.callbacks.EarlyStopping(patience=2, monitor='val_acc')
In [22]:
model.summary()
____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
main_input (InputLayer)          (None, 3, 80, 112)    0                                            
____________________________________________________________________________________________________
convolution2d_2 (Convolution2D)  (None, 12, 80, 112)   48          main_input[0][0]                 
____________________________________________________________________________________________________
convolution2d_5 (Convolution2D)  (None, 2, 80, 112)    8           main_input[0][0]                 
____________________________________________________________________________________________________
leakyrelu_1 (LeakyReLU)          (None, 12, 80, 112)   0           convolution2d_2[0][0]            
____________________________________________________________________________________________________
leakyrelu_3 (LeakyReLU)          (None, 2, 80, 112)    0           convolution2d_5[0][0]            
____________________________________________________________________________________________________
convolution2d_3 (Convolution2D)  (None, 16, 80, 112)   592         leakyrelu_1[0][0]                
____________________________________________________________________________________________________
convolution2d_6 (Convolution2D)  (None, 4, 80, 112)    44          leakyrelu_3[0][0]                
____________________________________________________________________________________________________
batchnormalization_1 (BatchNormal(None, 16, 80, 112)   32          convolution2d_3[0][0]            
____________________________________________________________________________________________________
batchnormalization_2 (BatchNormal(None, 4, 80, 112)    8           convolution2d_6[0][0]            
____________________________________________________________________________________________________
leakyrelu_2 (LeakyReLU)          (None, 16, 80, 112)   0           batchnormalization_1[0][0]       
____________________________________________________________________________________________________
leakyrelu_4 (LeakyReLU)          (None, 4, 80, 112)    0           batchnormalization_2[0][0]       
____________________________________________________________________________________________________
maxpooling2d_1 (MaxPooling2D)    (None, 3, 80, 112)    0           main_input[0][0]                 
____________________________________________________________________________________________________
convolution2d_1 (Convolution2D)  (None, 8, 80, 112)    32          main_input[0][0]                 
____________________________________________________________________________________________________
convolution2d_4 (Convolution2D)  (None, 16, 80, 112)   784         leakyrelu_2[0][0]                
____________________________________________________________________________________________________
convolution2d_7 (Convolution2D)  (None, 4, 80, 112)    84          leakyrelu_4[0][0]                
____________________________________________________________________________________________________
convolution2d_8 (Convolution2D)  (None, 4, 80, 112)    16          maxpooling2d_1[0][0]             
____________________________________________________________________________________________________
merge_1 (Merge)                  (None, 32, 80, 112)   0           convolution2d_1[0][0]            
                                                                   convolution2d_4[0][0]            
                                                                   convolution2d_7[0][0]            
                                                                   convolution2d_8[0][0]            
____________________________________________________________________________________________________
batchnormalization_3 (BatchNormal(None, 32, 80, 112)   64          merge_1[0][0]                    
____________________________________________________________________________________________________
leakyrelu_5 (LeakyReLU)          (None, 32, 80, 112)   0           batchnormalization_3[0][0]       
____________________________________________________________________________________________________
convolution2d_9 (Convolution2D)  (None, 32, 40, 56)    9248        leakyrelu_5[0][0]                
____________________________________________________________________________________________________
batchnormalization_4 (BatchNormal(None, 32, 40, 56)    64          convolution2d_9[0][0]            
____________________________________________________________________________________________________
leakyrelu_6 (LeakyReLU)          (None, 32, 40, 56)    0           batchnormalization_4[0][0]       
____________________________________________________________________________________________________
dropout_1 (Dropout)              (None, 32, 40, 56)    0           leakyrelu_6[0][0]                
____________________________________________________________________________________________________
convolution2d_11 (Convolution2D) (None, 24, 40, 56)    792         dropout_1[0][0]                  
____________________________________________________________________________________________________
convolution2d_14 (Convolution2D) (None, 4, 40, 56)     132         dropout_1[0][0]                  
____________________________________________________________________________________________________
leakyrelu_7 (LeakyReLU)          (None, 24, 40, 56)    0           convolution2d_11[0][0]           
____________________________________________________________________________________________________
leakyrelu_9 (LeakyReLU)          (None, 4, 40, 56)     0           convolution2d_14[0][0]           
____________________________________________________________________________________________________
convolution2d_12 (Convolution2D) (None, 32, 40, 56)    2336        leakyrelu_7[0][0]                
____________________________________________________________________________________________________
convolution2d_15 (Convolution2D) (None, 8, 40, 56)     168         leakyrelu_9[0][0]                
____________________________________________________________________________________________________
batchnormalization_5 (BatchNormal(None, 32, 40, 56)    64          convolution2d_12[0][0]           
____________________________________________________________________________________________________
batchnormalization_6 (BatchNormal(None, 8, 40, 56)     16          convolution2d_15[0][0]           
____________________________________________________________________________________________________
leakyrelu_8 (LeakyReLU)          (None, 32, 40, 56)    0           batchnormalization_5[0][0]       
____________________________________________________________________________________________________
leakyrelu_10 (LeakyReLU)         (None, 8, 40, 56)     0           batchnormalization_6[0][0]       
____________________________________________________________________________________________________
maxpooling2d_2 (MaxPooling2D)    (None, 32, 40, 56)    0           dropout_1[0][0]                  
____________________________________________________________________________________________________
convolution2d_10 (Convolution2D) (None, 16, 40, 56)    528         dropout_1[0][0]                  
____________________________________________________________________________________________________
convolution2d_13 (Convolution2D) (None, 32, 40, 56)    3104        leakyrelu_8[0][0]                
____________________________________________________________________________________________________
convolution2d_16 (Convolution2D) (None, 8, 40, 56)     328         leakyrelu_10[0][0]               
____________________________________________________________________________________________________
convolution2d_17 (Convolution2D) (None, 8, 40, 56)     264         maxpooling2d_2[0][0]             
____________________________________________________________________________________________________
merge_2 (Merge)                  (None, 64, 40, 56)    0           convolution2d_10[0][0]           
                                                                   convolution2d_13[0][0]           
                                                                   convolution2d_16[0][0]           
                                                                   convolution2d_17[0][0]           
____________________________________________________________________________________________________
batchnormalization_7 (BatchNormal(None, 64, 40, 56)    128         merge_2[0][0]                    
____________________________________________________________________________________________________
leakyrelu_11 (LeakyReLU)         (None, 64, 40, 56)    0           batchnormalization_7[0][0]       
____________________________________________________________________________________________________
convolution2d_18 (Convolution2D) (None, 64, 20, 28)    36928       leakyrelu_11[0][0]               
____________________________________________________________________________________________________
batchnormalization_8 (BatchNormal(None, 64, 20, 28)    128         convolution2d_18[0][0]           
____________________________________________________________________________________________________
leakyrelu_12 (LeakyReLU)         (None, 64, 20, 28)    0           batchnormalization_8[0][0]       
____________________________________________________________________________________________________
dropout_2 (Dropout)              (None, 64, 20, 28)    0           leakyrelu_12[0][0]               
____________________________________________________________________________________________________
convolution2d_20 (Convolution2D) (None, 48, 20, 28)    3120        dropout_2[0][0]                  
____________________________________________________________________________________________________
convolution2d_23 (Convolution2D) (None, 8, 20, 28)     520         dropout_2[0][0]                  
____________________________________________________________________________________________________
leakyrelu_13 (LeakyReLU)         (None, 48, 20, 28)    0           convolution2d_20[0][0]           
____________________________________________________________________________________________________
leakyrelu_15 (LeakyReLU)         (None, 8, 20, 28)     0           convolution2d_23[0][0]           
____________________________________________________________________________________________________
convolution2d_21 (Convolution2D) (None, 64, 20, 28)    9280        leakyrelu_13[0][0]               
____________________________________________________________________________________________________
convolution2d_24 (Convolution2D) (None, 16, 20, 28)    656         leakyrelu_15[0][0]               
____________________________________________________________________________________________________
batchnormalization_9 (BatchNormal(None, 64, 20, 28)    128         convolution2d_21[0][0]           
____________________________________________________________________________________________________
batchnormalization_10 (BatchNorma(None, 16, 20, 28)    32          convolution2d_24[0][0]           
____________________________________________________________________________________________________
leakyrelu_14 (LeakyReLU)         (None, 64, 20, 28)    0           batchnormalization_9[0][0]       
____________________________________________________________________________________________________
leakyrelu_16 (LeakyReLU)         (None, 16, 20, 28)    0           batchnormalization_10[0][0]      
____________________________________________________________________________________________________
maxpooling2d_3 (MaxPooling2D)    (None, 64, 20, 28)    0           dropout_2[0][0]                  
____________________________________________________________________________________________________
convolution2d_19 (Convolution2D) (None, 32, 20, 28)    2080        dropout_2[0][0]                  
____________________________________________________________________________________________________
convolution2d_22 (Convolution2D) (None, 64, 20, 28)    12352       leakyrelu_14[0][0]               
____________________________________________________________________________________________________
convolution2d_25 (Convolution2D) (None, 16, 20, 28)    1296        leakyrelu_16[0][0]               
____________________________________________________________________________________________________
convolution2d_26 (Convolution2D) (None, 16, 20, 28)    1040        maxpooling2d_3[0][0]             
____________________________________________________________________________________________________
merge_3 (Merge)                  (None, 128, 20, 28)   0           convolution2d_19[0][0]           
                                                                   convolution2d_22[0][0]           
                                                                   convolution2d_25[0][0]           
                                                                   convolution2d_26[0][0]           
____________________________________________________________________________________________________
batchnormalization_11 (BatchNorma(None, 128, 20, 28)   256         merge_3[0][0]                    
____________________________________________________________________________________________________
leakyrelu_17 (LeakyReLU)         (None, 128, 20, 28)   0           batchnormalization_11[0][0]      
____________________________________________________________________________________________________
convolution2d_27 (Convolution2D) (None, 128, 10, 14)   147584      leakyrelu_17[0][0]               
____________________________________________________________________________________________________
batchnormalization_12 (BatchNorma(None, 128, 10, 14)   256         convolution2d_27[0][0]           
____________________________________________________________________________________________________
leakyrelu_18 (LeakyReLU)         (None, 128, 10, 14)   0           batchnormalization_12[0][0]      
____________________________________________________________________________________________________
dropout_3 (Dropout)              (None, 128, 10, 14)   0           leakyrelu_18[0][0]               
____________________________________________________________________________________________________
convolution2d_29 (Convolution2D) (None, 96, 10, 14)    12384       dropout_3[0][0]                  
____________________________________________________________________________________________________
convolution2d_32 (Convolution2D) (None, 16, 10, 14)    2064        dropout_3[0][0]                  
____________________________________________________________________________________________________
leakyrelu_19 (LeakyReLU)         (None, 96, 10, 14)    0           convolution2d_29[0][0]           
____________________________________________________________________________________________________
leakyrelu_21 (LeakyReLU)         (None, 16, 10, 14)    0           convolution2d_32[0][0]           
____________________________________________________________________________________________________
convolution2d_30 (Convolution2D) (None, 128, 10, 14)   36992       leakyrelu_19[0][0]               
____________________________________________________________________________________________________
convolution2d_33 (Convolution2D) (None, 32, 10, 14)    2592        leakyrelu_21[0][0]               
____________________________________________________________________________________________________
batchnormalization_13 (BatchNorma(None, 128, 10, 14)   256         convolution2d_30[0][0]           
____________________________________________________________________________________________________
batchnormalization_14 (BatchNorma(None, 32, 10, 14)    64          convolution2d_33[0][0]           
____________________________________________________________________________________________________
leakyrelu_20 (LeakyReLU)         (None, 128, 10, 14)   0           batchnormalization_13[0][0]      
____________________________________________________________________________________________________
leakyrelu_22 (LeakyReLU)         (None, 32, 10, 14)    0           batchnormalization_14[0][0]      
____________________________________________________________________________________________________
maxpooling2d_4 (MaxPooling2D)    (None, 128, 10, 14)   0           dropout_3[0][0]                  
____________________________________________________________________________________________________
convolution2d_28 (Convolution2D) (None, 64, 10, 14)    8256        dropout_3[0][0]                  
____________________________________________________________________________________________________
convolution2d_31 (Convolution2D) (None, 128, 10, 14)   49280       leakyrelu_20[0][0]               
____________________________________________________________________________________________________
convolution2d_34 (Convolution2D) (None, 32, 10, 14)    5152        leakyrelu_22[0][0]               
____________________________________________________________________________________________________
convolution2d_35 (Convolution2D) (None, 32, 10, 14)    4128        maxpooling2d_4[0][0]             
____________________________________________________________________________________________________
merge_4 (Merge)                  (None, 256, 10, 14)   0           convolution2d_28[0][0]           
                                                                   convolution2d_31[0][0]           
                                                                   convolution2d_34[0][0]           
                                                                   convolution2d_35[0][0]           
____________________________________________________________________________________________________
batchnormalization_15 (BatchNorma(None, 256, 10, 14)   512         merge_4[0][0]                    
____________________________________________________________________________________________________
leakyrelu_23 (LeakyReLU)         (None, 256, 10, 14)   0           batchnormalization_15[0][0]      
____________________________________________________________________________________________________
convolution2d_36 (Convolution2D) (None, 256, 5, 7)     590080      leakyrelu_23[0][0]               
____________________________________________________________________________________________________
batchnormalization_16 (BatchNorma(None, 256, 5, 7)     512         convolution2d_36[0][0]           
____________________________________________________________________________________________________
leakyrelu_24 (LeakyReLU)         (None, 256, 5, 7)     0           batchnormalization_16[0][0]      
____________________________________________________________________________________________________
dropout_4 (Dropout)              (None, 256, 5, 7)     0           leakyrelu_24[0][0]               
____________________________________________________________________________________________________
convolution2d_38 (Convolution2D) (None, 192, 5, 7)     49344       dropout_4[0][0]                  
____________________________________________________________________________________________________
convolution2d_41 (Convolution2D) (None, 32, 5, 7)      8224        dropout_4[0][0]                  
____________________________________________________________________________________________________
leakyrelu_25 (LeakyReLU)         (None, 192, 5, 7)     0           convolution2d_38[0][0]           
____________________________________________________________________________________________________
leakyrelu_27 (LeakyReLU)         (None, 32, 5, 7)      0           convolution2d_41[0][0]           
____________________________________________________________________________________________________
convolution2d_39 (Convolution2D) (None, 256, 5, 7)     147712      leakyrelu_25[0][0]               
____________________________________________________________________________________________________
convolution2d_42 (Convolution2D) (None, 64, 5, 7)      10304       leakyrelu_27[0][0]               
____________________________________________________________________________________________________
batchnormalization_17 (BatchNorma(None, 256, 5, 7)     512         convolution2d_39[0][0]           
____________________________________________________________________________________________________
batchnormalization_18 (BatchNorma(None, 64, 5, 7)      128         convolution2d_42[0][0]           
____________________________________________________________________________________________________
leakyrelu_26 (LeakyReLU)         (None, 256, 5, 7)     0           batchnormalization_17[0][0]      
____________________________________________________________________________________________________
leakyrelu_28 (LeakyReLU)         (None, 64, 5, 7)      0           batchnormalization_18[0][0]      
____________________________________________________________________________________________________
maxpooling2d_5 (MaxPooling2D)    (None, 256, 5, 7)     0           dropout_4[0][0]                  
____________________________________________________________________________________________________
convolution2d_37 (Convolution2D) (None, 128, 5, 7)     32896       dropout_4[0][0]                  
____________________________________________________________________________________________________
convolution2d_40 (Convolution2D) (None, 256, 5, 7)     196864      leakyrelu_26[0][0]               
____________________________________________________________________________________________________
convolution2d_43 (Convolution2D) (None, 64, 5, 7)      20544       leakyrelu_28[0][0]               
____________________________________________________________________________________________________
convolution2d_44 (Convolution2D) (None, 64, 5, 7)      16448       maxpooling2d_5[0][0]             
____________________________________________________________________________________________________
merge_5 (Merge)                  (None, 512, 5, 7)     0           convolution2d_37[0][0]           
                                                                   convolution2d_40[0][0]           
                                                                   convolution2d_43[0][0]           
                                                                   convolution2d_44[0][0]           
____________________________________________________________________________________________________
convolution2d_45 (Convolution2D) (None, 256, 10, 14)   65792       leakyrelu_23[0][0]               
____________________________________________________________________________________________________
batchnormalization_19 (BatchNorma(None, 512, 5, 7)     1024        merge_5[0][0]                    
____________________________________________________________________________________________________
batchnormalization_20 (BatchNorma(None, 256, 10, 14)   512         convolution2d_45[0][0]           
____________________________________________________________________________________________________
leakyrelu_29 (LeakyReLU)         (None, 512, 5, 7)     0           batchnormalization_19[0][0]      
____________________________________________________________________________________________________
lambda_1 (Lambda)                (None, 256, 10, 14)   0           batchnormalization_20[0][0]      
____________________________________________________________________________________________________
dropout_5 (Dropout)              (None, 512, 5, 7)     0           leakyrelu_29[0][0]               
____________________________________________________________________________________________________
merge_6 (Merge)                  (None, 256, 10, 14)   0           leakyrelu_23[0][0]               
                                                                   lambda_1[0][0]                   
____________________________________________________________________________________________________
upsampling2d_1 (UpSampling2D)    (None, 512, 10, 14)   0           dropout_5[0][0]                  
____________________________________________________________________________________________________
leakyrelu_30 (LeakyReLU)         (None, 256, 10, 14)   0           merge_6[0][0]                    
____________________________________________________________________________________________________
merge_7 (Merge)                  (None, 768, 10, 14)   0           upsampling2d_1[0][0]             
                                                                   leakyrelu_30[0][0]               
____________________________________________________________________________________________________
convolution2d_47 (Convolution2D) (None, 96, 10, 14)    73824       merge_7[0][0]                    
____________________________________________________________________________________________________
convolution2d_50 (Convolution2D) (None, 16, 10, 14)    12304       merge_7[0][0]                    
____________________________________________________________________________________________________
leakyrelu_31 (LeakyReLU)         (None, 96, 10, 14)    0           convolution2d_47[0][0]           
____________________________________________________________________________________________________
leakyrelu_33 (LeakyReLU)         (None, 16, 10, 14)    0           convolution2d_50[0][0]           
____________________________________________________________________________________________________
convolution2d_48 (Convolution2D) (None, 128, 10, 14)   36992       leakyrelu_31[0][0]               
____________________________________________________________________________________________________
convolution2d_51 (Convolution2D) (None, 32, 10, 14)    2592        leakyrelu_33[0][0]               
____________________________________________________________________________________________________
batchnormalization_21 (BatchNorma(None, 128, 10, 14)   256         convolution2d_48[0][0]           
____________________________________________________________________________________________________
batchnormalization_22 (BatchNorma(None, 32, 10, 14)    64          convolution2d_51[0][0]           
____________________________________________________________________________________________________
leakyrelu_32 (LeakyReLU)         (None, 128, 10, 14)   0           batchnormalization_21[0][0]      
____________________________________________________________________________________________________
leakyrelu_34 (LeakyReLU)         (None, 32, 10, 14)    0           batchnormalization_22[0][0]      
____________________________________________________________________________________________________
maxpooling2d_6 (MaxPooling2D)    (None, 768, 10, 14)   0           merge_7[0][0]                    
____________________________________________________________________________________________________
convolution2d_46 (Convolution2D) (None, 64, 10, 14)    49216       merge_7[0][0]                    
____________________________________________________________________________________________________
convolution2d_49 (Convolution2D) (None, 128, 10, 14)   49280       leakyrelu_32[0][0]               
____________________________________________________________________________________________________
convolution2d_52 (Convolution2D) (None, 32, 10, 14)    5152        leakyrelu_34[0][0]               
____________________________________________________________________________________________________
convolution2d_53 (Convolution2D) (None, 32, 10, 14)    24608       maxpooling2d_6[0][0]             
____________________________________________________________________________________________________
merge_8 (Merge)                  (None, 256, 10, 14)   0           convolution2d_46[0][0]           
                                                                   convolution2d_49[0][0]           
                                                                   convolution2d_52[0][0]           
                                                                   convolution2d_53[0][0]           
____________________________________________________________________________________________________
convolution2d_54 (Convolution2D) (None, 128, 20, 28)   16512       leakyrelu_17[0][0]               
____________________________________________________________________________________________________
batchnormalization_23 (BatchNorma(None, 256, 10, 14)   512         merge_8[0][0]                    
____________________________________________________________________________________________________
batchnormalization_24 (BatchNorma(None, 128, 20, 28)   256         convolution2d_54[0][0]           
____________________________________________________________________________________________________
leakyrelu_35 (LeakyReLU)         (None, 256, 10, 14)   0           batchnormalization_23[0][0]      
____________________________________________________________________________________________________
lambda_2 (Lambda)                (None, 128, 20, 28)   0           batchnormalization_24[0][0]      
____________________________________________________________________________________________________
dropout_6 (Dropout)              (None, 256, 10, 14)   0           leakyrelu_35[0][0]               
____________________________________________________________________________________________________
merge_9 (Merge)                  (None, 128, 20, 28)   0           leakyrelu_17[0][0]               
                                                                   lambda_2[0][0]                   
____________________________________________________________________________________________________
upsampling2d_2 (UpSampling2D)    (None, 256, 20, 28)   0           dropout_6[0][0]                  
____________________________________________________________________________________________________
leakyrelu_36 (LeakyReLU)         (None, 128, 20, 28)   0           merge_9[0][0]                    
____________________________________________________________________________________________________
merge_10 (Merge)                 (None, 384, 20, 28)   0           upsampling2d_2[0][0]             
                                                                   leakyrelu_36[0][0]               
____________________________________________________________________________________________________
convolution2d_56 (Convolution2D) (None, 48, 20, 28)    18480       merge_10[0][0]                   
____________________________________________________________________________________________________
convolution2d_59 (Convolution2D) (None, 8, 20, 28)     3080        merge_10[0][0]                   
____________________________________________________________________________________________________
leakyrelu_37 (LeakyReLU)         (None, 48, 20, 28)    0           convolution2d_56[0][0]           
____________________________________________________________________________________________________
leakyrelu_39 (LeakyReLU)         (None, 8, 20, 28)     0           convolution2d_59[0][0]           
____________________________________________________________________________________________________
convolution2d_57 (Convolution2D) (None, 64, 20, 28)    9280        leakyrelu_37[0][0]               
____________________________________________________________________________________________________
convolution2d_60 (Convolution2D) (None, 16, 20, 28)    656         leakyrelu_39[0][0]               
____________________________________________________________________________________________________
batchnormalization_25 (BatchNorma(None, 64, 20, 28)    128         convolution2d_57[0][0]           
____________________________________________________________________________________________________
batchnormalization_26 (BatchNorma(None, 16, 20, 28)    32          convolution2d_60[0][0]           
____________________________________________________________________________________________________
leakyrelu_38 (LeakyReLU)         (None, 64, 20, 28)    0           batchnormalization_25[0][0]      
____________________________________________________________________________________________________
leakyrelu_40 (LeakyReLU)         (None, 16, 20, 28)    0           batchnormalization_26[0][0]      
____________________________________________________________________________________________________
maxpooling2d_7 (MaxPooling2D)    (None, 384, 20, 28)   0           merge_10[0][0]                   
____________________________________________________________________________________________________
convolution2d_55 (Convolution2D) (None, 32, 20, 28)    12320       merge_10[0][0]                   
____________________________________________________________________________________________________
convolution2d_58 (Convolution2D) (None, 64, 20, 28)    12352       leakyrelu_38[0][0]               
____________________________________________________________________________________________________
convolution2d_61 (Convolution2D) (None, 16, 20, 28)    1296        leakyrelu_40[0][0]               
____________________________________________________________________________________________________
convolution2d_62 (Convolution2D) (None, 16, 20, 28)    6160        maxpooling2d_7[0][0]             
____________________________________________________________________________________________________
merge_11 (Merge)                 (None, 128, 20, 28)   0           convolution2d_55[0][0]           
                                                                   convolution2d_58[0][0]           
                                                                   convolution2d_61[0][0]           
                                                                   convolution2d_62[0][0]           
____________________________________________________________________________________________________
convolution2d_63 (Convolution2D) (None, 64, 40, 56)    4160        leakyrelu_11[0][0]               
____________________________________________________________________________________________________
batchnormalization_27 (BatchNorma(None, 128, 20, 28)   256         merge_11[0][0]                   
____________________________________________________________________________________________________
batchnormalization_28 (BatchNorma(None, 64, 40, 56)    128         convolution2d_63[0][0]           
____________________________________________________________________________________________________
leakyrelu_41 (LeakyReLU)         (None, 128, 20, 28)   0           batchnormalization_27[0][0]      
____________________________________________________________________________________________________
lambda_3 (Lambda)                (None, 64, 40, 56)    0           batchnormalization_28[0][0]      
____________________________________________________________________________________________________
dropout_7 (Dropout)              (None, 128, 20, 28)   0           leakyrelu_41[0][0]               
____________________________________________________________________________________________________
merge_12 (Merge)                 (None, 64, 40, 56)    0           leakyrelu_11[0][0]               
                                                                   lambda_3[0][0]                   
____________________________________________________________________________________________________
upsampling2d_3 (UpSampling2D)    (None, 128, 40, 56)   0           dropout_7[0][0]                  
____________________________________________________________________________________________________
leakyrelu_42 (LeakyReLU)         (None, 64, 40, 56)    0           merge_12[0][0]                   
____________________________________________________________________________________________________
merge_13 (Merge)                 (None, 192, 40, 56)   0           upsampling2d_3[0][0]             
                                                                   leakyrelu_42[0][0]               
____________________________________________________________________________________________________
convolution2d_65 (Convolution2D) (None, 24, 40, 56)    4632        merge_13[0][0]                   
____________________________________________________________________________________________________
convolution2d_68 (Convolution2D) (None, 4, 40, 56)     772         merge_13[0][0]                   
____________________________________________________________________________________________________
leakyrelu_43 (LeakyReLU)         (None, 24, 40, 56)    0           convolution2d_65[0][0]           
____________________________________________________________________________________________________
leakyrelu_45 (LeakyReLU)         (None, 4, 40, 56)     0           convolution2d_68[0][0]           
____________________________________________________________________________________________________
convolution2d_66 (Convolution2D) (None, 32, 40, 56)    2336        leakyrelu_43[0][0]               
____________________________________________________________________________________________________
convolution2d_69 (Convolution2D) (None, 8, 40, 56)     168         leakyrelu_45[0][0]               
____________________________________________________________________________________________________
batchnormalization_29 (BatchNorma(None, 32, 40, 56)    64          convolution2d_66[0][0]           
____________________________________________________________________________________________________
batchnormalization_30 (BatchNorma(None, 8, 40, 56)     16          convolution2d_69[0][0]           
____________________________________________________________________________________________________
leakyrelu_44 (LeakyReLU)         (None, 32, 40, 56)    0           batchnormalization_29[0][0]      
____________________________________________________________________________________________________
leakyrelu_46 (LeakyReLU)         (None, 8, 40, 56)     0           batchnormalization_30[0][0]      
____________________________________________________________________________________________________
maxpooling2d_8 (MaxPooling2D)    (None, 192, 40, 56)   0           merge_13[0][0]                   
____________________________________________________________________________________________________
convolution2d_64 (Convolution2D) (None, 16, 40, 56)    3088        merge_13[0][0]                   
____________________________________________________________________________________________________
convolution2d_67 (Convolution2D) (None, 32, 40, 56)    3104        leakyrelu_44[0][0]               
____________________________________________________________________________________________________
convolution2d_70 (Convolution2D) (None, 8, 40, 56)     328         leakyrelu_46[0][0]               
____________________________________________________________________________________________________
convolution2d_71 (Convolution2D) (None, 8, 40, 56)     1544        maxpooling2d_8[0][0]             
____________________________________________________________________________________________________
merge_14 (Merge)                 (None, 64, 40, 56)    0           convolution2d_64[0][0]           
                                                                   convolution2d_67[0][0]           
                                                                   convolution2d_70[0][0]           
                                                                   convolution2d_71[0][0]           
____________________________________________________________________________________________________
convolution2d_72 (Convolution2D) (None, 32, 80, 112)   1056        leakyrelu_5[0][0]                
____________________________________________________________________________________________________
batchnormalization_31 (BatchNorma(None, 64, 40, 56)    128         merge_14[0][0]                   
____________________________________________________________________________________________________
batchnormalization_32 (BatchNorma(None, 32, 80, 112)   64          convolution2d_72[0][0]           
____________________________________________________________________________________________________
leakyrelu_47 (LeakyReLU)         (None, 64, 40, 56)    0           batchnormalization_31[0][0]      
____________________________________________________________________________________________________
lambda_4 (Lambda)                (None, 32, 80, 112)   0           batchnormalization_32[0][0]      
____________________________________________________________________________________________________
dropout_8 (Dropout)              (None, 64, 40, 56)    0           leakyrelu_47[0][0]               
____________________________________________________________________________________________________
merge_15 (Merge)                 (None, 32, 80, 112)   0           leakyrelu_5[0][0]                
                                                                   lambda_4[0][0]                   
____________________________________________________________________________________________________
upsampling2d_4 (UpSampling2D)    (None, 64, 80, 112)   0           dropout_8[0][0]                  
____________________________________________________________________________________________________
leakyrelu_48 (LeakyReLU)         (None, 32, 80, 112)   0           merge_15[0][0]                   
____________________________________________________________________________________________________
merge_16 (Merge)                 (None, 96, 80, 112)   0           upsampling2d_4[0][0]             
                                                                   leakyrelu_48[0][0]               
____________________________________________________________________________________________________
convolution2d_74 (Convolution2D) (None, 12, 80, 112)   1164        merge_16[0][0]                   
____________________________________________________________________________________________________
convolution2d_77 (Convolution2D) (None, 2, 80, 112)    194         merge_16[0][0]                   
____________________________________________________________________________________________________
leakyrelu_49 (LeakyReLU)         (None, 12, 80, 112)   0           convolution2d_74[0][0]           
____________________________________________________________________________________________________
leakyrelu_51 (LeakyReLU)         (None, 2, 80, 112)    0           convolution2d_77[0][0]           
____________________________________________________________________________________________________
convolution2d_75 (Convolution2D) (None, 16, 80, 112)   592         leakyrelu_49[0][0]               
____________________________________________________________________________________________________
convolution2d_78 (Convolution2D) (None, 4, 80, 112)    44          leakyrelu_51[0][0]               
____________________________________________________________________________________________________
batchnormalization_33 (BatchNorma(None, 16, 80, 112)   32          convolution2d_75[0][0]           
____________________________________________________________________________________________________
batchnormalization_34 (BatchNorma(None, 4, 80, 112)    8           convolution2d_78[0][0]           
____________________________________________________________________________________________________
leakyrelu_50 (LeakyReLU)         (None, 16, 80, 112)   0           batchnormalization_33[0][0]      
____________________________________________________________________________________________________
leakyrelu_52 (LeakyReLU)         (None, 4, 80, 112)    0           batchnormalization_34[0][0]      
____________________________________________________________________________________________________
maxpooling2d_9 (MaxPooling2D)    (None, 96, 80, 112)   0           merge_16[0][0]                   
____________________________________________________________________________________________________
convolution2d_73 (Convolution2D) (None, 8, 80, 112)    776         merge_16[0][0]                   
____________________________________________________________________________________________________
convolution2d_76 (Convolution2D) (None, 16, 80, 112)   784         leakyrelu_50[0][0]               
____________________________________________________________________________________________________
convolution2d_79 (Convolution2D) (None, 4, 80, 112)    84          leakyrelu_52[0][0]               
____________________________________________________________________________________________________
convolution2d_80 (Convolution2D) (None, 4, 80, 112)    388         maxpooling2d_9[0][0]             
____________________________________________________________________________________________________
merge_17 (Merge)                 (None, 32, 80, 112)   0           convolution2d_73[0][0]           
                                                                   convolution2d_76[0][0]           
                                                                   convolution2d_79[0][0]           
                                                                   convolution2d_80[0][0]           
____________________________________________________________________________________________________
batchnormalization_35 (BatchNorma(None, 32, 80, 112)   64          merge_17[0][0]                   
____________________________________________________________________________________________________
leakyrelu_53 (LeakyReLU)         (None, 32, 80, 112)   0           batchnormalization_35[0][0]      
____________________________________________________________________________________________________
dropout_9 (Dropout)              (None, 32, 80, 112)   0           leakyrelu_53[0][0]               
____________________________________________________________________________________________________
convolution2d_81 (Convolution2D) (None, 1, 80, 112)    33          dropout_9[0][0]                  
____________________________________________________________________________________________________
main_output (Reshape)            (None, 80, 112)       0           convolution2d_81[0][0]           
====================================================================================================
Total params: 1858475
____________________________________________________________________________________________________
In [23]:
# load pre-trained model?
# model.load_weights('models/unet_inception_inv2_20160927-05-11-02_acc-0.70_weights.hdf5')
In [ ]:
model_checkpoint = ModelCheckpoint('models/%s_weights.hdf5'%model_name, monitor='val_acc', save_best_only=True, save_weights_only=True)
early_stopping = keras.callbacks.EarlyStopping(patience=2, monitor='val_acc')

history3 = model.fit_generator(train_gen, 
                               samples_per_epoch=400, 
                               nb_epoch=350, 
                               verbose=1, 
                               validation_data=test_gen,
                               nb_val_samples=170,
                               callbacks=[
                                          model_checkpoint,
#                                          early_stopping
                                         ])
In [132]:
%%time
score = model.evaluate_generator(test_gen, val_samples=150)
score=dict(zip(model.metrics_names,score))
print(score)
{'loss': 0.10378610715270042, 'mean_squared_error': 0.006491463553781311, 'acc': 0.69975000619888306}
CPU times: user 3.86 s, sys: 916 ms, total: 4.78 s
Wall time: 3.18 s
In [133]:
import arrow
ts=arrow.utcnow().format('YYYYMMDD-HH-mm-ss')
fn='models/{}_{}_acc-{:2.2f}.hdf5'.format(model_name,ts,score['acc'])
model.save(fn)
fn
Out [133]:
'models/unet_inception_inv2_20160927-05-11-02_acc-0.70.hdf5'
In [134]:
wfn='models/{}_{}_acc-{:2.2f}_weights.hdf5'.format(model_name,ts,score['acc'])
model.save_weights(wfn)
wfn
Out [134]:
'models/unet_inception_inv2_20160927-05-11-02_acc-0.70_weights.hdf5'
In [95]:
def plot_hist(history):
    """plot keras history object"""
    for label in history.history:
        if not label.startswith('val'):
            plt.title(label)
            plt.plot(history.history[label], label=label)
            if 'val_' + label in history.history:
                plt.plot(history.history['val_' + label], label=label)
            plt.xlabel('epoch')
            plt.show()

plot_hist(model.history)

Results

Note we compare the unugumented training and unugumented testing data to see if it overfits. If we compared the augumented and unaugumented we would get strange results like more accuracy on the validation data than the test data, but this is due to artificially increased variance on the augumented training data.

In [46]:
# remove dropout
model = unet_inception_model(optimiser,img_cols,img_rows,LeakyReLU,dropout=0.0)

# load best checkpoint
model.load_weights('models/%s_weights.hdf5'%model_name)

# or load pre-trained model
# model.load_weights('models/unet_inception_inv2_20160927-05-11-02_acc-0.70_weights.hdf5')
In [47]:
score = model.evaluate_generator(test_gen, val_samples=batch_size)
score=dict(zip(model.metrics_names,score))
print(score)
{'acc': 0.70276403033694024, 'loss': 0.10917609349729204}
In [48]:
score = model.evaluate_generator(train_gen_unaugumented, val_samples=batch_size)
score=dict(zip(model.metrics_names,score))
print(score)
{'acc': 0.71395832896232603, 'loss': 0.074744646375377977}
In [61]:
X_test, y_test = next(test_gen)
y_pred = model.predict(X_test)
In [62]:
from matplotlib.colors import LogNorm
norm=LogNorm(vmin=1e-3, vmax=1.0)
sns.set_style("dark")
n=10
plt.figure(figsize=(9,2.5*n))


fontsize=16
for i in range(n):
    
    ax=plt.subplot(n,3,1+i*3)
    if i==0: plt.title('(a) Input image', fontsize=fontsize)
    plt.imshow(np.transpose(X_test,(0,2,3,1))[i])
    plt.axis('off')
    ax.axes.get_xaxis().set_visible(False)
    ax.axes.get_yaxis().set_visible(False)
    
    ax=plt.subplot(n,3,2+i*3)
    if i==0: plt.title('(a) Manual mask', fontsize=fontsize)
    plt.imshow(np.transpose(X_test,(0,2,3,1))[i])
    cm=plt.imshow(y_test[i]>0.5, norm=norm, alpha=1, cmap=plt.cm.rainbow)
    plt.axis('off')
    ax.axes.get_xaxis().set_visible(False)
    ax.axes.get_yaxis().set_visible(False)
    
    ax=plt.subplot(n,3,3+i*3)
    if i==0: plt.title('(b) Predicted mask', fontsize=fontsize)
    plt.imshow(np.transpose(X_test,(0,2,3,1))[i])
    cm=plt.imshow(y_pred[i]>0.5, norm=norm, alpha=1, cmap=plt.cm.rainbow)
    plt.axis('off')
    ax.axes.get_xaxis().set_visible(False)
    ax.axes.get_yaxis().set_visible(False)
    
plt.tight_layout()
plt.savefig('images/results.png')
plt.show()
In [ ]: