keras-team / keras

Deep Learning for humans
http://keras.io/
Apache License 2.0
61.86k stars 19.44k forks source link

ValueError: A `Concatenate` layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape=[(None, 88, 88, 128), (None, 89, 89, 128)] #19964

Closed TheKnowingEye closed 2 months ago

TheKnowingEye commented 3 months ago

I am getting this error when I try to compile my U-NET model ValueError: A Concatenate layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape=[(None, 88, 88, 128), (None, 89, 89, 128)]

I was not getting this error when I had 256x256 as my input shape in the Input layer

How to reproduce

def unet(n_levels, initial_features=32, n_blocks=2, kernel_size=3, pooling_size=2, in_channels=1, out_channels=1):
    inputs = tf.keras.layers.Input(shape=(358, 358, in_channels))
    x = inputs

    convpars = dict(kernel_size=kernel_size, activation='relu', padding='same')

    #downstream
    skips = {}
    for level in range(n_levels):
        for _ in range(n_blocks):
            x = tf.keras.layers.Conv2D(initial_features * 2 ** level, **convpars)(x)
        if level < n_levels - 1:
            skips[level] = x
            x = tf.keras.layers.MaxPool2D(pooling_size)(x)

    # upstream
    for level in reversed(range(n_levels-1)):
        x = tf.keras.layers.Conv2DTranspose(initial_features * 2 ** level, strides=pooling_size, **convpars)(x)
        x = tf.keras.layers.Concatenate()([x, skips[level]])
        for _ in range(n_blocks):
            x = tf.keras.layers.Conv2D(initial_features * 2 ** level, **convpars)(x)

    # output
    activation = 'sigmoid' if out_channels == 1 else 'softmax'
    x = tf.keras.layers.Conv2D(out_channels, kernel_size=1, activation=activation, padding='same')(x)

    return tf.keras.Model(inputs=[inputs], outputs=[x], name=f'UNET-L{n_levels}-F{initial_features}')

NUM_TRAIN = 672
NUM_TEST = 169
BATCH_SIZE_TRAIN=32
BATCH_SIZE_TEST=32

EPOCH_STEP_TRAIN = NUM_TRAIN // BATCH_SIZE_TRAIN
EPOCH_STEP_TEST = NUM_TEST // BATCH_SIZE_TEST

model = unet(5)
model.compile(optimizer=Adam(learning_rate = 0.0001), loss=binary_crossentropy, metrics=[MeanIoU(num_classes=2)])
mehtamansi29 commented 3 months ago

Hi @TheKnowingEye -

Thanks for reporting this issue. Here the error reproduces due to convolution shape mismatch during skip connections uses in UNET network. To resolve this error you can either use cropping or padding technique to get same shape. Padding is much better to use here to preserve image height and width.

Using Cropping:

        ###adding cropping 2D layer before concatenate with height and width adjusted
        height = max(0,skips[level].shape[1]- x.shape[1])
        width = max(0,skips[level].shape[2]- x.shape[2])
        cropped_x= tf.keras.layers.Cropping2D(cropping=((0, height), (0, width)))(skips[level])
        x = tf.keras.layers.Concatenate()([x, cropped_x])

Padding:

        ###adding padding 2D layer before concatenate with height and width adjusted
        pad_top = (skips[level].shape[1] - x.shape[1]) // 2
        pad_bottom = skips[level].shape[1] - x.shape[1] - pad_top
        pad_left = (skips[level].shape[2] - x.shape[2]) // 2
        pad_right = skips[level].shape[2] - x.shape[2] - pad_left
        padded_x = tf.keras.layers.ZeroPadding2D(padding=((pad_top, pad_bottom), (pad_left, pad_right)))(x)
        x = tf.keras.layers.Concatenate()([skips[level], padded_x])

Attached the gist for the reference as well.

github-actions[bot] commented 2 months ago

This issue is stale because it has been open for 14 days with no activity. It will be closed if no further activity occurs. Thank you.

github-actions[bot] commented 2 months ago

This issue was closed because it has been inactive for 28 days. Please reopen if you'd like to work on this further.

google-ml-butler[bot] commented 2 months ago

Are you satisfied with the resolution of your issue? Yes No