How to convert a Tensor with shape (None, 512) into a Tensor with shape (None, 12, 12, 512)

Viewed 619

I'm using Python 3.7.7., Tensorflow 2.1.0 and Functional Api to define an encoder with this summary:

Model: "encoder"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 200, 200, 1)]     0         
_________________________________________________________________
conv1_1 (Conv2D)             (None, 200, 200, 64)      1664      
_________________________________________________________________
conv1_2 (Conv2D)             (None, 200, 200, 64)      102464    
_________________________________________________________________
pool1 (MaxPooling2D)         (None, 100, 100, 64)      0         
_________________________________________________________________
conv2_1 (Conv2D)             (None, 100, 100, 96)      55392     
_________________________________________________________________
conv2_2 (Conv2D)             (None, 100, 100, 96)      83040     
_________________________________________________________________
pool2 (MaxPooling2D)         (None, 50, 50, 96)        0         
_________________________________________________________________
conv3_1 (Conv2D)             (None, 50, 50, 128)       110720    
_________________________________________________________________
conv3_2 (Conv2D)             (None, 50, 50, 128)       147584    
_________________________________________________________________
pool3 (MaxPooling2D)         (None, 25, 25, 128)       0         
_________________________________________________________________
conv4_1 (Conv2D)             (None, 25, 25, 256)       295168    
_________________________________________________________________
conv4_2 (Conv2D)             (None, 25, 25, 256)       1048832   
_________________________________________________________________
pool4 (MaxPooling2D)         (None, 12, 12, 256)       0         
_________________________________________________________________
conv5_1 (Conv2D)             (None, 12, 12, 512)       1180160   
_________________________________________________________________
conv5_2 (Conv2D)             (None, 12, 12, 512)       2359808   
_________________________________________________________________
global_average_pooling2d (Gl (None, 512)               0         
=================================================================
Total params: 5,384,832
Trainable params: 5,384,832
Non-trainable params: 0
_________________________________________________________________
None

I get the encoder from a U-Net network with this code:

u_net: Model = get_unet_uncompiled(img_shape = (200, 200, 1))

encoder_input = Model(inputs=u_net.layers[0].input, outputs=u_net.layers[14].output)
encoder_output = GlobalAveragePooling2D()(encoder_input.layers[-1].output)

encoder = Model(encoder_input.input, encoder_output, name='encoder')

print(encoder.summary())

I want to up pooling its output to a shape of (None, 12, 12, 512).

I have tried this:

u_net: Model = get_unet_uncompiled(img_shape = (200, 200, 1))

encoder_input = Model(inputs=u_net.layers[0].input, outputs=u_net.layers[14].output)
encoder_output = GlobalAveragePooling2D()(encoder_input.layers[-1].output)

up = UpSampling2D(size=(12, 12))(encoder_output)

encoder = Model(encoder_input.input, up, name='encoder')

But I have this error:

ValueError: Input 0 of layer up_sampling2d is incompatible with the layer: expected ndim=4, found ndim=2. Full shape received: [None, 512]

I have no idea about what I'm doing. Maybe UpSampling2D is wrong here.

But, how can I convert it to shape (None, 12, 12, 512)?

2 Answers

Deconvolution/ Upsamping operation forms the same connectivity as the normal convolution but in the backward direction. For, Upsampling in Keras input shape is

4D tensor with shape: - If data_format is "channels_last": (batch_size, rows, cols,channels)

But, you give output global_average_pooling2d layer that is a 2D tensor ([None, 512]), so this throws the error. If you want to use Upsamping here you should remove the Global Average Pooling layer, then upsampling will work. This is an example of UNet implemented from scratch in Keras.

You can use a Lambda layer:

import tensorflow as tf

inputs = tf.random.uniform((100, 512),0, 1, dtype=tf.int32)

layer = tf.keras.layers.Lambda(lambda x: tf.tile(tf.reshape(x, (100, 1, 1, 512)), 
                                                 (1, 12, 12, 1)))

print(layer(inputs).shape)
TensorShape([100, 12, 12, 512])
Related