tf.nn.conv2d_transpose的padding有什么作用?

gau*_*clb 5 convolution tensorflow deconvolution

我们知道,我们可以tensor通过 的填充模式来计算输出的形状conv2d算法很清晰,但是我很困惑conv2d_transpose,它是否填充输入张量然后调用conv2d?它在哪里转置过滤器或输入?如何根据填充模式SAMEVALIDfor计算输出张量的形状conv2d_transpose

Pan*_*hin 2

Padding 对于 conv2d_transpose 意味着什么?

“SAME”意味着简单地将输入形状乘以步幅。例如,如果输入形状的高度和宽度为 7,并且 conv2d_transpose 的 padding=same 和 strides=3,则输出形状的高度和宽度将为 7x3 = 21。

“有效”几乎相同。从“SAME”开始,然后检查 kernel_size 与步幅的比较。如果它更大,则将该值添加到高度和宽度中。为什么?因为当内核在图像上移动进行卷积时(一次按步幅量),最后一个内核将通过差异悬在图像上。想象一下上面的示例,高度和宽度为 7 作为输入,这次 padding=valid、strides=3 和 kernel=5。输出高度和宽度将为 7x3 + (5-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)
Run Code Online (Sandbox Code Playgroud)

示例有效(内核比步幅更大)

>>> 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)
Run Code Online (Sandbox Code Playgroud)

示例有效(内核等于或小于步幅)

>>> 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)
Run Code Online (Sandbox Code Playgroud)

小内核跨步的 ZEROS 示例

>>> 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)
Run Code Online (Sandbox Code Playgroud)