[SOLVED] Overriding keras predict function

Issue

I have Keras model that accepts inputs which have 4D shapes as (n, height, width, channel).

However, my data generator is producing 2D arrays as(n, width*height). So, the predict function of Keras is expecting inputs as 4D. I have no chance to change the data generator because the model will be tested by someone else. So, is there a way to override the predict function of Keras.

My model structure

a = Input(shape=(width*height,))

d1 = 16  # depth of filter kernel each layer
d2 = 16
d3 = 64
d4 = 128
d5 = 256

drop_out = 0.25
patch_size = (3, 3)
k_size = (2, 2)

reshape = Reshape((height, width, 1))(a)

conv1 = Conv2D(filters=d1, kernel_size=patch_size, padding='same', activation='relu')(reshape)
conv1 = MaxPooling2D(pool_size=k_size, padding='same')(conv1)

conv2 = Convolution2D(filters=d2, kernel_size=patch_size, padding='same', activation='relu')(conv1)
conv2 = MaxPooling2D(pool_size=k_size, padding='same')(conv2)

conv3 = Convolution2D(filters=d3, kernel_size=patch_size, padding='same', activation='relu')(conv2)
conv3 = MaxPooling2D(pool_size=k_size, padding='same')(conv3)

conv4 = Convolution2D(filters=d4, kernel_size=patch_size, padding='same', activation='relu')(conv3)
conv4 = MaxPooling2D(pool_size=k_size, padding='same')(conv4)

conv5 = Convolution2D(filters=d5, kernel_size=patch_size, padding='same', activation='relu')(conv4)
conv5 = MaxPooling2D(pool_size=k_size, padding='same')(conv5)

x = Flatten()(conv5)

x = Dropout(drop_out)(x)
node = 32

x_1 = Dense(node, activation='relu')(x)  # connect the flatten layer to five classifier,each one comes to a digit.
x_2 = Dense(node, activation='relu')(x)
x_3 = Dense(node, activation='relu')(x)
x_4 = Dense(node, activation='relu')(x)
x_5 = Dense(node, activation='relu')(x)

d1 = Dense(n_class, activation='softmax')(x_1)
d2 = Dense(n_class, activation='softmax')(x_2)
d3 = Dense(n_class, activation='softmax')(x_3)
d4 = Dense(n_class, activation='softmax')(x_4)
d5 = Dense(n_class, activation='softmax')(x_5)

outputs = [d1, d2, d3, d4, d5]

model = Model(a, outputs)
model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])

model.fit(raw_train_data, raw_train_target, batch_size=200, epochs=5, validation_split=0.2)

Solution

You don’t override the predict, you simply add a Reshape layer at the beginning of your model.

With the functional API:

from keras.layers import *

inp = Input((width*heigth,))
first = Reshape((width,height,1))(inp)

..... other layers.....

model = Model(inp, outputFromTheLastLayer)    

With a sequential model:

model = Sequential()    
model.add(Reshape((width,height,1), input_shape = (width*height,)))
model.add(otherlayers)   

About the output shape.

Since you have 5 outputs, you need your target array to be a list of five arrays:

raw_train_target = [target1,target2,target3,target4,target5]

If you cannot do that, and raw_train_target is one single arary with the targets all following a sequence, you can try to use a concatenate layer at the end:

output = Concatenate()(outputs)     

Answered By – Daniel Möller

Answer Checked By – Marie Seifert (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *