为什么在 Keras 和 Tensorflow 中转置 conv2d 的输出不同



KerasTensorflowtranspose convolution的不同输出。

Keras仅提供输出(1, 5, 5, 1)

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给出输出(1, 6, 6, 1)(1, 5, 5, 1)配置是否重复output_shape

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) 

如果strides > 1,则可以使用多个输出形状进行转置卷积。

在正常的卷积中,如果填充VALID,则可以计算输出形状:

out_shape = ceil((inp_shape - kernel_size + 1) / strides)    

反过来思考,在转置卷积中,如果output_shape与特定的过滤器和步幅值卷积,它将等于正常卷积输入的形状。

换句话说,当您对数字进行四舍五入时,有多个可能的输出形状用于转置卷积。

代码中的示例:

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"
)

如果我使用相同的过滤器和步骤对此进行卷积:

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) ...

它首先产生了与x1相同的形状。

conv2d_transpose将输出形状更改为 [1, 6, 6, 1] :

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) ...

因此,tf.keras.layers.Conv2DTranspose给出了尽可能小的输出形状。

最新更新