Keras
和Tensorflow
中transpose 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
给出了尽可能小的输出形状。