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

2022-04-28 19:39:21 浏览数 (1)

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

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

Transposed Convolution

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

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

代码语言:javascript复制
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=leftlfloor frac{i 2p-k}{s} rightrfloor 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代码:

代码语言:javascript复制
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

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

代码语言:javascript复制
tf.nn.conv2d_transpose(
    value=input, filter=kernel,
    output_shape=[1,6,6,1],
    strides=2, padding='SAME')

卷积类型是same,我们首先在外围填充一圈0。此时仍然不能生成尺寸为6x6的图片,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执行卷积核为3x3的卷积操作,结果如下:

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】

0 人点赞