Different output of transpose convolution
in Keras
and Tensorflow
.
Keras
gives output (1, 5, 5, 1)
only:
import tensorflow as tf
x = tf.random.normal(shape=(1, 2, 2, 1))
print()
y = tf.keras.layers.Conv2DTranspose(1, (3, 3), 2, padding="valid")(x)
print(y.shape)
print()
Tensorflow
gives output (1, 6, 6, 1)
or (1, 5, 5, 1)
if configs output_shape
repectively:
import tensorflow as tf
with tf.compat.v1.Session() as sess:
x1 = tf.constant(
[4.5, 5.4, 8.1, 9.0],
shape=([1, 2, 2, 1]),
dtype=tf.float32
)
dev_con1 = tf.ones(
shape=([3, 3, 1, 1]),
dtype=tf.float32
)
y1 = tf.nn.conv2d_transpose(
x1,
dev_con1,
output_shape=[1,6,6,1] # OK with [1,5,5,1], too,
strides=[1, 2, 2, 1],
padding="VALID"
)
tf.compat.v1.global_variables_initializer()
y1, x1 = sess.run([y1,x1])
print(x1.shape)
print()
print(y1.shape)
CodePudding user response:
If strides > 1
then multiple output shapes for transpose convolution are possible.
In a normal convolution one can calculate the output shape if padding is VALID
:
out_shape = ceil((inp_shape - kernel_size 1) / strides)
Thinking reversely, in transpose convolution, output_shape
would be equal to the shape of the normal convolution's input's shape if it was convolved with specific filter and strides values.
With other words, there are more than one possible output shape for transpose convolution as you round the numbers.
Example from your code:
y1 = tf.nn.conv2d_transpose(
x1,
dev_con1,
output_shape=[1,5,5,1], # OK with [1,5,5,1], too,
strides=[1, 2, 2, 1],
padding="VALID"
)
If I convolve this with same filters and strides:
tf.nn.conv2d(y1, filters = tf.ones(shape=([3, 3, 1, 1]),dtype=tf.float32), s
trides = [1,2,2,1], padding = 'VALID')
>> <tf.Tensor: shape=(1, 2, 2, 1) ...
It produced the same shape like x1
in the first place.
Changing the output shape to [1, 6, 6, 1] in conv2d_transpose
:
y1 = tf.nn.conv2d_transpose(
x1,
dev_con1,
output_shape=[1,6,6,1], # OK with [1,5,5,1], too,
strides=[1, 2, 2, 1],
padding="VALID"
)
tf.nn.conv2d(y1, filters = tf.ones(shape=([3, 3, 1, 1]),dtype=tf.float32),
strides = [1,2,2,1], padding = 'VALID')
>> <tf.Tensor: shape=(1, 2, 2, 1) ...
So tf.keras.layers.Conv2DTranspose
gives the minimum possible output shape.