1
$\begingroup$

I have a convolutional network, taken from this github, the one in build.py. Because it was made in an outdated version of keras I am trying to rewrite this to version 2.1.4. I came a long but I have some trouble with (hopefully) the last step. Below I posted the code I have now but what I need to do yet is the final reshaping. I receive the error ValueError: total size of new array must be unchanged which according to this answer I got this error because the shape of my output is not corresponding to what I want to reshape it to. However my height and width are both factors of 32 so I do not understand the problem. The final layer of the network (a batch normalization) returns a shape of (Bat (None, 0, 256, 2). According to the code I found I have to reshape this using

autoencoder.add(Reshape((n_labels, img_h*img_w))

which would be (2, (256 * 256)). This sounds incorrect the 256 * 256 part is very large, but I don't fully understand the reshape function. After all I took this from github so it should be correct but the notation can be changed with the introduction of the new keras versions.

Can somebody shed some light on what this reshaping does and maybe suggest to what dimensions I need to reshape?


This is the entire model I'm using:

from keras import models
from keras.layers.core import Activation, Reshape, Permute
from keras.layers.convolutional import Conv2D, MaxPooling2D, UpSampling2D
from keras.layers.normalization import BatchNormalization
import json

img_w = 256
img_h = 256
n_labels = 2

kernel = 3

encoding_layers = [
    Conv2D(64, (kernel,kernel), padding='same', input_shape=(1, img_h, img_w)),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(64, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    MaxPooling2D(),

    Conv2D(128, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(128, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    MaxPooling2D(),

    Conv2D(256, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(256, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(256, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    MaxPooling2D(),

    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    MaxPooling2D(),

    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    MaxPooling2D(),
]

autoencoder = models.Sequential()
autoencoder.encoding_layers = encoding_layers

for l in autoencoder.encoding_layers:
    autoencoder.add(l)

decoding_layers = [
    UpSampling2D(),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),

    UpSampling2D(),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(512, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(256, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),

    UpSampling2D(),
    Conv2D(256, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(256, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(128, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),

    UpSampling2D(),
    Conv2D(128, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(64, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),

    UpSampling2D(),
    Conv2D(64, (kernel,kernel), padding='same'),
    BatchNormalization(),
    Activation('relu'),
    Conv2D(n_labels, (1, 1), padding='valid'),
    BatchNormalization(),
]
autoencoder.decoding_layers = decoding_layers
for l in autoencoder.decoding_layers:
    autoencoder.add(l)

autoencoder.add(Reshape((n_labels, img_h * img_w)))
autoencoder.add(Permute((2, 1)))
autoencoder.add(Activation('softmax'))

with open('model_5l.json', 'w') as outfile:
    outfile.write(json.dumps(json.loads(autoencoder.to_json()), indent=2))

$\endgroup$

1 Answer 1

2
$\begingroup$

Your data format is not the default data format.

By default, Conv2D, MaxPooling2D, and UpSampling2D expect inputs of the form [batch, height, width, channels]. Your input is of the form [batch, channels, height, width].

So your algorithm tries to apply convolution, pooling and upsampling to the channels and height dimensions, not to the height and width dimensions as intended. The fix is easy: Add the option data_format='channels_first' to all convolution, pooling and upsampling layers. (Or change your data format).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.