我们知道,我们可以通过conv2d的填充模式计算输出tensor的形状,算法很清晰,但我对conv2d_transpose非常困惑,它是否填充了输入Tensor然后调用conv2d?它在哪里转置过滤器或输入?如何根据填充模式计算输出Tensor的形状,conv2d_transpose的SAME或VALID?
conv2d
tensor
conv2d_transpose
SAME
VALID
6l7fqoea1#
在这两种情况下,如果内核小于步幅,你只会在输出中得到一大堆零。为什么?考虑一下步幅的作用。对于给定的stride值,输入图像会增加很多倍。stride为3会使输入图像的宽度和高度增加3倍。原始值占据每3个位置,其余的填充为零!对于padding=valid,有我们之前讨论过的额外内容。kernel_size是卷积核的大小,它在图像上以步幅移动。所以,如果kernel_size为1,步幅为3,那么你的输出大部分是零。
>>> conv2d_tr = tf.keras.layers.Conv2DTranspose(5,kernel_size=3,padding='same',strides=2) >>> conv2d_tr(np.zeros([3,2,2,4],dtype=np.float32)).numpy().shape (3, 4, 4, 5)
>>> conv2d_tr = tf.keras.layers.Conv2DTranspose(5,kernel_size=3,padding='valid',strides=2) >>> conv2d_tr(np.zeros([3,10,10,4],dtype=np.float32)).numpy().shape (3, 21, 21, 5)
>>> conv2d_tr = tf.keras.layers.Conv2DTranspose(5,kernel_size=2,padding='valid',strides=2) >>> conv2d_tr(np.zeros([3,2,2,4],dtype=np.float32)).numpy().shape (3, 20, 20, 5)
>>> conv2d_tr = tf.keras.layers.Conv2DTranspose(1,kernel_size=1,padding='same',strides=2) >>> conv2d_tr(np.ones([1,2,2,3],dtype=np.float32)).numpy().shape (1, 4, 4, 1) >>> conv2d_tr(np.ones([1,2,2,3],dtype=np.float32)).numpy() array([[[[0.702],[0. ],[0.702],[0. ]], [[0. ],[0. ],[0. ],[0. ]], [[0.702],[0. ],[0.702],[0. ]], [[0. ],[0. ],[0. ],[0. ]]]], dtype=float32)
1条答案
按热度按时间6l7fqoea1#
padding对于conv2d_transpose是什么意思?
在这两种情况下,如果内核小于步幅,你只会在输出中得到一大堆零。为什么?考虑一下步幅的作用。
对于给定的stride值,输入图像会增加很多倍。stride为3会使输入图像的宽度和高度增加3倍。原始值占据每3个位置,其余的填充为零!对于padding=valid,有我们之前讨论过的额外内容。
kernel_size是卷积核的大小,它在图像上以步幅移动。所以,如果kernel_size为1,步幅为3,那么你的输出大部分是零。
示例#
示例VALID(内核大于strides)
示例VALID(内核等于或小于stride)
小内核的ZEROS示例