转置卷积是在图像分割领域中常用到的一种上采样措施,在U-Net,FCN中都有它的身影,其主要的目的也就是将低分辨率的特征图样上采样到原始图像的分辨率大小,以给出原始图片的分割结果。转置卷积又名反卷积、分数步长卷积,但实际上转置卷积并不是卷积的逆过程,只是输入输出在形状上对应而已,举个例子,步长为2的卷积可以实现将输入特征图样缩小到原大小的1/4,而转置卷积则可以将缩小后的特征图样复原到原始大小,但是对应位置处的值并不同。
为了介绍转置卷积,首先我们需要回顾一下卷积的原理,一般情况下,卷积操作是将原图中一块矩形区域的建立局部联系,映射到输出特征图样的一个值,是区域->个体的映射1。如下例子所示:
当然这种情况下我们很难看出卷积这一操作如何实现求逆或者求反(频域的方法先按下不表),因此我们可以将卷积的操作用更为规整的矩阵相乘形式来表示,将输入图像 X X X和输出特征图样 Y Y Y展平,将卷积核的元素嵌入到稀疏矩阵的对应位置处构成权重矩阵 W W W,则卷积可以表述为2:
Y = W X Y=WX Y=WX
具体的过程演示可以参见下图3:
那么相应的如果我们想要通过 X X X来求 Y Y Y,很直接的想法就是权重矩阵求逆后左乘,但权重矩阵并不为方阵,因此我们能做的只是构建一个满足左乘 Y Y Y的输出结果与 X X X相同的新矩阵,即满足shape(W’)=shape(W):
X = W ′ T Y X=W'^TY X=W′TY
同时要保证这一矩阵的映射关系是个体->区域的,且前后位置对应关系不变,满足这样条件的新矩阵也恰好可以也构成一个卷积核满足和 Y Y Y卷积的需求,对应于矩阵相乘的操作就又可以转化为卷积操作。从而转置卷积也被称之为逆卷积,但实际上并不是在矩阵求逆,或者逆卷积,而是权重矩阵的转置(也不确切,因为值并不相同,只是形状相同)。
前一小结的内容和网络上相关分析都大同小异,但关于转置卷积输入输出形状的分析却缺乏一个统一口径,往往是从现有函数或者转置卷积本身出发,没有联系到转置卷积和卷积的内在关系。因此,本节将从理论角度出发,推导转置卷积输入输出参数间的关系,从而确定计算公式。
首先对于普通的卷积过程而言,输入输出大小的确定十分简单,满足下述公式:
W 2 = W 1 + 2 P 1 − F 1 S 1 + 1 (1) W_2=\frac{W_1+2P_1-F_1}{S_1}+1\tag{1} W2=S1W1+2P1−F1+1(1)
该式非常好理解, W 1 + 2 P W_1+2P W1+2P为填充之后图片的长度, W 1 + 2 P 1 − F 1 {W_1+2P_1-F_1} W1+2P1−F1为图中最后可以容纳一个卷积核身位的位置, W 1 + 2 P 1 − F 1 S 1 \frac{W_1+2P_1-F_1}{S_1} S1W1+2P1−F1计算了以 S S S移动时卷积核需要移动多少次到达最后一个身位,加上最后一个身位即得出该式。
既然转置卷积也是一种卷积,那么它的输入输出一定也满足如下公式:
W 1 = W 2 + 2 P 2 − F 2 S 2 + 1 (2) W_1=\frac{W_2+2P_2-F_2}{S_2}+1\tag{2} W1=S2W2+2P2−F2+1(2)
那当我们确定了正向卷积的过程,就需要根据转置卷积前后的区域->个体的对应关系来确定转置卷积的参数。
卷积核的形状不会发生改变,在正向卷积过程和转置卷积中非零项的数目和位置都是相同的,这也是二者均可转化为卷积操作的基础,故 F 2 = F 1 F_2=F_1 F2=F1.
对于步长参数,在正向卷积过程中,步长定义了两次相邻卷积操作输入区域 X i , X i + 1 X_i,X_{i+1} Xi,Xi+1重叠的面积(宽度为 W − S W-S W−S),也就是在只考虑卷积核第一行运算时,同时与两个输出有关的输入值只有 W − S W-S W−S个。从而在转置卷积过程中,这意味着同时涉及到两个相邻输入 Y i , Y i + 1 Y_i,Y_{i+1} Yi,Yi+1的输出也只有 W − S W-S W−S个,为了达成这一目标,我们就需要向两相邻输入间填补0值,减缓卷积移动的步长。这就是为何转置卷积也被称为分数步长卷积,因为需要向输入元素间添加 S − 1 S-1 S−1个零,以满足输入输出对应关系的要求,原先一步跨越S个元素,现在S步跨越1个元素。即 S 2 = 1 S 1 S_2=\frac{1}{S_1} S2=S11。在这种分数步长的情况下,之前的输入输出计算公式已经不再适用了,因此表述为默认 S 2 = 1 S_2=1 S2=1,在相邻元素间添加 S 1 − 1 S_1-1 S1−1个零值,公式变成:
W 1 = W 2 + 2 P 2 − F 2 + ( W 2 − 1 ) ( S − 1 ) 1 + 1 W_1=\frac{W_2+2P_2-F_2+(W_2-1)(S-1)}{1}+1 W1=1W2+2P2−F2+(W2−1)(S−1)+1
确定了前两个参数后,联立两个式子就可以得到填充值之间的关系:
S 1 ( W 2 − 1 ) + F − 2 P 1 = W 2 + 2 P 2 − F + ( W 2 − 1 ) ( S 1 − 1 ) + 1 F − 2 P 1 = 2 P 2 − F + 2 P 2 = F − P 1 − 1 S_1(W_2-1)+F-2P_1=W_2+2P_2-F+(W_2-1)(S_1-1)+1\\ F-2P_1=2P_2-F+2\\ P_2=F-P_1-1 S1(W2−1)+F−2P1=W2+2P2−F+(W2−1)(S1−1)+1F−2P1=2P2−F+2P2=F−P1−1
这三个参数的一一对应确保了正向卷积、转置卷积过程中元素对应关系不发生任何的变化,读者可自行验证4。
通常定义转置卷积时也会使用到卷积核大小,步长,填充值, F , S , P F,S,P F,S,P这三个参数,其中 S S S实际上是真实步长的倒数, S − 1 S-1 S−1为相邻元素间填充0值的个数。而最最最最蠢的问题来了,通常定义一个转置卷积时,为了强调它是转置卷积,我们是使用它所对应的正向卷积参数来定义它。那么由前两节卷积和转置卷积参数对应关系,我们就可以得知,转置卷积的输出大小为:
O = S ( W − 1 ) + 1 + 2 ( F − P − 1 ) − F + 1 = S ( W − 1 ) − 2 P + F \begin{aligned} O&=S(W-1)+1+2(F-P-1)-F+1 \\ &= S(W-1)-2P+F \end {aligned} O=S(W−1)+1+2(F−P−1)−F+1=S(W−1)−2P+F
其实式1并不准确,因为存在着 W 1 + 2 P 1 − F 1 S 1 \frac{W_1+2P_1-F_1}{S_1} S1W1+2P1−F1非整数的情况,此时默认是向下取整,也就是 [ N S , N S + a ] , a ∈ { 0 , 1 , . . . , s − 1 } [NS,NS+a],a\in\{0,1,...,s-1\} [NS,NS+a],a∈{0,1,...,s−1}范围内的 W 1 + 2 P 1 − F 1 S 1 \frac{W_1+2P_1-F_1}{S_1} S1W1+2P1−F1都对应与同样大小的输出结果,那么为了复原出这一部分的大小,我们就需要计算出这省略值的数目5
a = ( W 1 + 2 P 1 − F 1 ) m o d ( S ) a=({W_1+2P_1-F_1})mod(S) a=(W1+2P1−F1)mod(S)
然后在计算转置卷积时padding之外额外再补 a a a个零值,至于是在左侧上侧补足,还是右侧下侧补足就依照所用函数而定。
总之,定义转置卷积的参数有4个,均来自于对应的正向卷积,分别为正向卷积时的步长、卷积核大小、填充数,多余量, S , F , P , a S,F,P,a S,F,P,a,用这些参数可求得正向卷积输入大小即转置卷积输出大小:
O = S ( W − 1 ) − 2 P + F + a O=S(W-1)-2P+F+a O=S(W−1)−2P+F+a
一文搞懂反卷积,转置卷积 ↩︎
反卷积(Transposed Convolution)详细推导 ↩︎
A Comprehensive Introduction to Different Types of Convolutions in Deep Learning ↩︎
ConvTranspose2d原理,深度网络如何进行上采样? ↩︎
卷积与反卷积关系超详细说明及推导(反卷积又称转置卷积、分数步长卷积) ↩︎