1.首先声明一点,转置卷积不是卷积的逆运算,转置卷积也是一种卷积方式,作用是进行上采样!主要出现在分割和对抗神经网络模型中比较多。
2.其次,transposed convolution、fractionally-strided convolution 和 deconvolution都是指转置卷积,但是pytorch官方采用transposed convolution这种说法,也更能说明转置卷积的原理。下面是两种卷积的示意图:它们的具体参数为 stride=1;padding=0; kernel=3
convolution transposed convolution
2.操作步骤:
(1).在输入特征图元素之间填充stride-1 的行和列的0元素,stride为转置卷积的步长;
(2).在输入特征图的四周填充kernelsize-padding-1的行和列的0元素,kernelsize为转置卷积核的大小,padding为转置卷积的padding大小,这里padding和卷积的padding不一样,可以看到这里在进行转置卷积时特征图蓝色部分还是2*2,所以padding为0;
(3).将卷积核参数上下、左右翻转;
(4).做正常卷积运算(padding 0;stride 1)。
我说的实在浅薄,拾人牙慧也算不得,具体的例子,请参考这篇博文和视频博客:转置卷积的原理;B站:转置卷积的原理
3.Tips:另外,如果看完这两篇还是觉得云里雾里,没办法理解转置卷积的padding和stride到底是怎么会是的,建议参考github的这个项目来理解卷积;转置卷积动图,看完这个项目,我觉得转置卷积的padding和stride是和原始卷积保持一致的设置才能保证转置卷积后能还原到正常卷积之前的特征图大小,这两个参数对于转置卷积来说并不是体现在转置卷积的过程中,而是体现在转置卷积输入特征图元素间和四周的0元素设置上。举几个栗子给大家看看:
图1.原始的普通卷积:kernelsize=3;padding=0;stride=1
图形解释: 普通卷积输出特征图大小的计算公式:输出尺寸 =( 输入特征图尺寸-卷积核尺寸+ 2倍的padding大小)/ stride大小 + 1 , 这里size = (4-3+2*0)/1 + 1= 2, 所以输出的特征图大小为2*2。
图2. 转置卷积:kernelsize=3;padding=0;stride=1
图形解释:大家从上图可以看到,对于这个转置卷积来说,输入特征图周围是补了两行两列0的,那为什么这里padding=0,不是padding=2吗?这里就是转置卷积和普通卷积理解不一样的地方,有这个疑惑的朋友可以看看第3点我总结的,padding和stride参数的作用是用来对输入特征图进行处理的,而不是体现在卷积过程中的,尤其是步长这一参数,和普通卷积完全不同。接下来我来算一下,为什么会有4*4的特征矩阵输出:1.首先在输入特征图元素之间填充stride-1=0 行和列元素,即不填充;2.其次,在输入特征图四周填充kernel size-padding-1=2 行和列0元素,即填充两行两列0元素;3.将普通卷积核的参数上下、左右翻转;4.做正常的普通卷积操作(stride=1,padding=0)。
转置卷积操作后特征图的大小可以通过如下公式计算:
其中stride[0]表示高度方向的stride,padding[0]表示高度方向的padding,kernel_size[0]表示高度方向的kernel_size,索引[1]都表示宽度方向上的。通过上面公式可以看出padding越大,输出的特征矩阵高、宽越小,你可以理解为正向卷积过程中进行了padding然后得到了特征图,现在使用转置卷积还原到原来高、宽后要把之前的padding减掉。其实大部分情况下,高度和宽度上padding,kernel size还有stride都是相等的。
接下来,再看几个图,我想大家应该可以理解了:
图3.原始的普通卷积:kernelsize=3;padding=0;stride=2
图4. 转置卷积:kernelsize=3;padding=0;stride=2
图5.原始的普通卷积:kernelsize=3;padding=1;stride=2
图4. 转置卷积:kernelsize=3;padding=1;stride=2
好了,讲到这里,基本把转置卷积和普通卷积的简单流程和区别搞明白了,如果需要再深入学习的话,建议到我引用的链接中的大佬博客里面去学习!