1 简介
反卷积(deconvolution)又称转置卷积,是卷积的拟操作,常用于GAN等模型中。反卷积是上采样的一种,上采样是指将特征图维度恢复到原始图的维度,这种增大维度的过程被称为上采样。上采样可以用插值或反卷积实现。
在CNN中,卷积一般会让图像尺寸变小,属于下采样。例如最大化池化(可视为特殊的卷积)是将相邻像素中最大的像素提取出来,丢弃了其他不重要的像素。卷积和反卷积是相反的过程。
GAN等生成模型中经常使用反卷积,为什么呢?因为隐含层(特征图)包含最基本的图像特征,一般维度很小。比如要生成小狗的图片,那么特征就要有眼睛,耳朵等,但只有轮廓或大纲而已,还需要反卷积丰富细节,比如添加上草坪,丰富颜色,增加光影等,从而扩大图像维度。
可以把隐含层(特征图)想象成泡腾片,它是浓缩的精华,包含最基本的维生素营养,人是无法直接生食泡腾片的(就像人不好直接看懂隐含层的图片一样),而反卷积就是将泡腾片放进水中的过程,让人更容易饮用。
2 计算过程
反卷积实际上也是使用常规的卷积运算实现的。
计算过程如下图所示。
下方蓝色为输入的2*2图像,在中间插入了0,再在周围填充上了0,表示成白色。然后用3*3的卷积核扫描,得到上方绿色的输出,为5*5的图像。
下面举一个数值例子
输入图像为3*3
卷积核kernel_size为3*3
2.1 根据Stride插入零元素
若stride=2,则输入图像的每行和每列之间插入(stride-1)行(列)的零元素,并在补零后的矩阵的左边和上边添加额外的(stride-1)行(列)的零元素。
2.2 根据Padding在上下左右插入零元素
若padding=same(后文会详细讨论含义),则上下左右各添加(kernel_size-1)/2个行(列)元素,
总之要保证添加的总行/列数=kernel_size-1
这里先埋下伏笔,后文会具体讨论。
当然,如果除不尽,则让右方、下方添加的更多,左方、上方添加的更少。比如kernel_size=4,(kernel_size-1)/2=1.5,则右方、下方添加2,左方、上方添加1。
经过此步,在周围一圈都填充了0(绿色)得到下图的输入。
2.3 计算卷积
插入零元素之后,按照正常卷积算法计算即可,注意反卷积的stride和padding步骤仅影响输入图像填充0,stride主要影响输入图像像素之间的填充,padding主要影响像素周围的填充,填充后这2个参数就完成使命了,在做卷积运算时是固定按步长为1、不填充来计算的。
注意tensorflow中反卷积核是将卷积核旋转180°的结果(即做了reverse),因此参与正向卷积运算的核为旋转180°,为
卷积运算,得到结果为
以右下角的18为例说明算法,卷积核每一项与输入图像右下角3*3的矩阵元素分别相乘求和。则结果为
1*0+0*0+1*0+...+2*9+...+1*0=18
3 棋盘效应
这里是采纳了https://www.zhihu.com/question/48279880/answer/1682194600,原文说得很清楚,这里只是使用笔者自己的语言转述。棋盘效应是指反卷积得到的结果中经常会出现“棋盘”、“格子”形状,尤其是在深色的图像中。
这是因为反卷积中“不均匀重叠”(Uneven overlap)的结果。
3.1 出现情况:卷积核的大小不能被步长整除
如下图a所示,假设卷积核是2,步长是1,这时候卷积核可以倍步长整除。上边一排黑框是输入图像,下边一排黑框是输出图像,可以发现输出图像第二个元素既接收了输入图像第一个元素(红框),又接收了第二个元素(绿框),因此其颜色更深。但是这种情况下,中间的这些黑框深浅是一样的,所以不会出现棋盘效应。
下图中的a、b同样如此。但是c和d就出现了棋盘效应,尤其二维空间下更明显。
3.2 如何避免
3.2.1 选择卷积核和步长使得二者可以整除
但是无法避免卷积核本身训练成了不均匀的深浅颜色。见下图
3.2.2 调整卷积核权重
使得卷积核的深浅恰好能调整输出图像深浅一致,但是难度太大,增加了训练的成本,而且实战中往往不能尽如人意。
3.2.3 插值
左图表示原始的图像,中图和右图代表插值后的结果,可以看到输出图像更加均匀了。先对输入图像 像素之间做插值,然后插值的像素也做卷积,其实相当于卷积核大小还是3,步长变成1了。只要步长是1,即使训练后卷积核其中一个元素过深,也能保证输出图像颜色均匀。