【总结】反卷积、转置卷积
首先举个栗子,看个简单的卷积操作:
4x4的输入,卷积Kernel为3x3, 没有Padding和Stride, 则输出为2x2。
输入矩阵可展开为16维向量,记作
输出矩阵可展开为4维向量,记作
卷积运算可表示为
不难想象其实就是如下的稀疏阵:
简单说运算过程就是 = (4*16)*(16*1)=(4*1)。
首先要想了解反卷积的原理要补充一下卷积的相关操作:
caffe里有im2col层,如果对matlab比较熟悉的话,就应该知道im2col是什么意思。他先将一个大矩阵,重叠地划分为多个子矩阵,对每个子矩阵序列化成向量,最后得到另外一个矩阵。看看下面的图就知道了:
在caffe中,卷积运算就是先对数据进行im2col操作,再进行内积运算(inner product)。这样做,比原始的卷积操作速度更快。
再看一下上面的卷积操作:将输入X展成16*1的向量,这样进行矩阵的相乘(不是卷积也不是点乘),根据矩阵的运算法则(4*16)*(16*1)=(4*1),把(4*1)的结果再展成(2,2),这也是我们根据卷积运算法则得到的大小:2*2.
现在对输出的结果,进行转置卷积,也就是对得到的2*2的feature map进行操作得到4*4大小的原先的输入,我们用上一步得到的(4*1)的结果,乘上kernel的转置C‘,整个运算过程如果看矩阵维度的话是x=C'*y=(16*1)=(16*4)*(4*1),这个维度和我们输入的x是相同的。
如果从直观上理解上述过程:
正向卷积过程(蓝色为输入x,阴影为卷积核C,绿色为输出y)
对于No zero padding,unit stride 的卷积来说,转置卷积:
其对应关系可以理解为正向卷积为0 padding,那么转置卷积就是full padding。
【注:stride】当stride不为1的时候,转置卷积的卷积核就变成了一个带“洞”的卷积,也就是fractional stride convolution(微步卷积)。
例如正向卷积输入x,输入i=5,p=0,k=3,stride=2,那么得到的正向卷积结果大小是2*2的,若要恢复其5*5的大小,转置卷积的参数应该为i'=i_transformed(即在正向卷积的输出之间填补0)。得到的输出大小为(2-1)*2+3=5,即(5*5)大小。
另外:关于卷积、池化和转置卷积输出特征图大小的计算公式,见我另外一篇博客:http://www.cnblogs.com/wmr95/articles/8134234.html