| by YoungTimes | No comments

深度学习中的反卷积(Transposed Convolution)

反卷积(Transposed Convolution)是一种图像上采样(UpSample)的方法,在DCGAN中用它来将随机采样的值转换为一张完整的图像。

DCGAN生成手写数字。图片来源【5】

Transposed Convolution

反向卷积也叫转置卷积,它是一种特殊的正向卷积,先按照一定的比例通过补0来扩大输入图像的尺寸,接着旋转卷积核(Kernel),再进行正向卷积。

反卷积的操作只是恢复了矩阵的尺寸大小,并不能恢复每个元素值。

tf.nn.conv2d_transpose(
    input, filters, output_shape, strides, padding='SAME', data_format='NHWC',
    dilations=None, name=None
)

Transposed Convolution将Output Size恢复为Input Size,对于Convolution过程,我们知道其Output Size与Input Size的尺寸关系如下:

$$
o=\left\lfloor \frac{i+2p-k}{s} \right\rfloor + 1
$$

其中,o为Output Size, i是Input Size, p为Padding Size,s为Stride。

若要将o恢复为i,需考虑2种情况,$\frac{i+2p−k}{s}$整除以及不整除两种情况。

详细的公式就不推导了,网上有很多资料,有兴趣可以深入研究下这些材料:

https://www.cnblogs.com/shine-lee/p/11559825.html

A guide to convolution arithmetic for deep learning

Tensorflow中实现反卷积

假设我们令输入图像为:

$$
\text{input} =
\begin{bmatrix}
1 & 2 & 3 \
4 & 5 & 6 \
7 & 8 & 9
\end{bmatrix}
$$

卷积核(kernel)为:

$$
\text{kernel} =
\begin{bmatrix}
1 & 0 & 0 \
0 & 1 & 0 \
0 & 0 & 1
\end{bmatrix}
$$

Case 1

如果要使输出的尺寸是5 x 5,步长stride = 2,tensorflow代码:

tf.nn.conv2d_transpose(
    value=input, filter=kernel,
    output_shape=[1,5,5,1], 
    strides=2, padding='SAME')

Tensorflow的内部做了以下几件事情:

1)根据步数stride对Input进行填充,即在Input的每个元素之间填充0 ,填充0的个数n与stride的关系为:

$$
\text{n} = \text{stride} – 1
$$

这里stride=1,所以在每个元素之间填充一个0。

$$
\text {input}_{pad}=\left[\begin{array}{ccccc}
0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 1 & 0 & 2 & 0 & 3 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 4 & 0 & 5 & 0 & 6 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 7 & 0 & 8 & 0 & 9 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0
\end{array}\right]
$$

2)用卷积核kernel对填充后的输入$input_{pad}$进行stride=1的正向卷积,输入尺寸为5 x 5。

$$
\text {output}=\left[\begin{array}{ccccc}
1 & 0 & 2 & 0 & 3 \
0 & 6 & 0 & 8 & 0 \
4 & 0 & 5 & 0 & 6 \
0 & 12 & 0 & 14 & 0 \
7 & 0 & 8 & 0 & 9
\end{array}\right]
$$

Case 2

如果要使输出的尺寸是6×6,其它参数不变,tensorflow代码:

tf.nn.conv2d_transpose(
    value=input, filter=kernel,
    output_shape=[1,6,6,1], 
    strides=2, padding='SAME')

卷积类型是same,我们首先在外围填充一圈0。此时仍然不能生成尺寸为6×6的图片,Tensorflow会在左上再填充一行和一列0,填充后的输入为:

$$
\text {input}=\left[\begin{array}{ccccccc}
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 0 & 1 & 0 & 2 & 0 & 3 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 0 & 4 & 0 & 5 & 0 & 6 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \
0 & 0 & 7 & 0 & 8 & 0 & 9 & 0 \
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0
\end{array}\right]
$$

对input执行卷积核为3×3的卷积操作,结果如下:

$$
\text {input}=\left[\begin{array}{cccccc}
1 & 0 & 2 & 0 & 3 & 0 \
0 & 1 & 0 & 2 & 0 & 3 \
4 & 0 & 6 & 0 & 8 & 0 \
0 & 4 & 0 & 5 & 0 & 6 \
7 & 0 & 12 & 0 & 14 & 0 \
0 & 7 & 0 & 8 & 0 & 9
\end{array}\right]
$$

反卷积动图效果

No padding, no strides, transposed,图片来源【1】
No padding, strides=1, transposed,图片来源【1】

参考材料

1.https://github.com/vdumoulin/conv_arithmetic
2.https://www.tensorflow.org/api_docs/python/tf/nn/conv2d_transpose
3.https://zhuanlan.zhihu.com/p/31988761
4.https://www.cnblogs.com/shine-lee/p/11559825.html
5.https://www.tensorflow.org/tutorials/generative/dcgan?hl=zh-cn

发表评论