Search code examples
pythontensorflowkeraskeras-layer

Strange padding layer output


I am trying to construct a model that looks like this.
Model1

Notice that the output shape of the padding layer is 1 * 48 * 48 * 32. The input shape to padding layer is 1 * 48 * 48 * 16. Which type of padding operation does that?

My code:

    prelu3 = tf.keras.layers.PReLU(shared_axes = [1, 2])(add2)
    deptconv3 = tf.keras.layers.DepthwiseConv2D(3, strides=(2, 2), padding='same')(prelu3)
    conv4 = tf.keras.layers.Conv2D(32, 1, strides=(1, 1), padding='same')(deptconv3)
    maxpool1 = tf.keras.layers.MaxPool2D()(prelu3)
    pad1 = tf.keras.layers.ZeroPadding2D(padding=(1, 1))(maxpool1) # This is the padding layer where problem lies.

This is the part of code that is trying to replicate that block. However, I get model that looks like this.
Model1

Am I missing something here or am I using the wrong layer?


Solution

  • By default, keras maxpool2d takes in:

    Input shape : 4D tensor with shape (batch_size, rows, cols, channels).
    Output shape : (batch_size, padded_rows, padded_cols, chamels)
    

    PLease have a look here zero_padding2d layer docs in keras.

    In that respect you are trying to double what is getting treated as a channel here. Your input looks more like (batch, x, y, z) and you want to have a (batch, x, y, 2*z) Why do you want to have a zeropadding to double your z? I would rather suggest you to use a dense layer like

    tf.keras.layers.Dense(32)(maxpool1)
    

    That would increase z shape from 16 to 32.

    Edited:

    I got something which can help you.

    tf.keras.layers.ZeroPadding2D(
        padding=(0, 8), data_format="channels_first"
    )(maxpool1)
    

    What this does is treats your y, z as (x, y) and x as channel and pads (0, 8) around (y, z) to give (y, 32)

    Demo:

    import tensorflow as tf
    input_shape = (4, 28, 28, 3)
    x = tf.keras.layers.Input(shape=input_shape[1:])
    y = tf.keras.layers.Conv2D(16, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x)
    x=tf.keras.layers.ZeroPadding2D(
        padding=(0, 8), data_format="channels_first"
    )(y)
    print(y.shape, x.shape)
    
    (None, 24, 24, 16) (None, 24, 24, 32)