一文搞懂 deconvolution、transposed convolution、sub-pixel or fractional convolution
目錄
- 寫在前面
- 什麼是deconvolution
- convolution過程
- transposed convolution過程
- transposed convolution的計算
- 整除的情況
- 不整除的情況
- 總結
- 參考
部落格:blog.shinelee.me | 部落格園 | CSDN
寫在前面
開篇先上圖,圖為deconvolution在畫素級語義分割中的一種應用,直觀感覺deconvolution是一個upsampling的過程,像是convolution的對稱過程。
本文將深入deconvolution的細節,並通過如下方式展開:
- 先回答 什麼是deconvolution?為什麼會有transposed convolutionon、subpixel or fractional convolution這樣的名字?
- 再介紹 各種情形下 transposed convolution是如何進行的,並提供一種統一的計算方法。
什麼是deconvolution
首先要明確的是,deconvolution並不是個好名字,因為它存在歧義:
- deconvolution最初被定義為“inverse of convolution”或者“inverse filter”或者“解卷積”,是指消除先前濾波作用的方法。比如,我們認為原始影象是清晰的,但是通過透鏡觀測到的影象卻變得模糊,如果假設透鏡的作用相當於以某個kernel作用在原始影象上,由此導致影象變得模糊,那麼根據模糊的影象估計這個kernel或者根據模糊影象恢復原始清晰影象的過程就叫deconvolution。
- 後來論文Adaptive Deconvolutional Networks for Mid and High Level Feature Learning和Visualizing and Understanding Convolutional Networks又重新定義了deconvolution,實際上與transposed convolution、sub-pixel or fractional convolution指代相同。transposed convolution是一個更好的名字,sub-pixel or fractional convolution可以看成是transposed convolution的一個特例。對一個常規的卷積層而言,前向傳播時是convolution,將input feature map對映為output feature map,反向傳播時則是transposed convolution,根據output feature map的梯度計算出input feature map的梯度,梯度圖的尺寸與feature map的尺寸相同。
本文談論的是deconvolution的第2個含義,後面統一使用transposed convolution這個名字。
什麼是transposed convolution?A guide to convolution arithmetic for deep learning中有這樣一段話:
看完好像仍不是很直觀,transposed convolution到底對應的是什麼操作?等到文章的後面,這個問題的答案會逐漸清晰起來。
下面先以1個例子來對比convolution過程和transposed convolution過程,採用與A guide to convolution arithmetic for deep learning相同的設定:
- 2-D transposed convolutions (\(N=2\))
- square inputs (\(i_1=i_2=i\))
- square kernel size (\(k_1=k_2=k\))
- same strides along both axes (\(s_1=s_2=s\))
- same zero padding along both axes (\(p_1=p_2=p\))
- square outputs (\(o_1=o_2=o\))
若令\(i=4\)、\(s=1\)、\(p=0\)、\(k=3\),輸出尺寸\(o=2\),則convolution過程是將\(4\times 4\)的map對映為\(2\times 2\)的map,而transposed convolution過程則是將\(2\times 2\)的map對映為\(4\times 4\)的map,兩者的kernel size均為3,如下圖所示:
可以看到,convolution過程zero padding的數量與超引數\(p\)一致,但是transposed convolution實際的zero padding的數量為2,為什麼會這樣?是為了保持連線方式相同,下面具體看一下。
convolution過程
先看convolution過程,連線方式 如下圖所示,綠色表示輸出,藍色表示輸入,每個綠色塊具與9個藍色塊連線。
令卷積核\(\mathbf{w} = \left(\begin{array}{ccc} {w_{0,0}} & {w_{0,1}} & {w_{0,2}} \\ {w_{1,0}} & {w_{1,2}} & {w_{1,2}} \\ {w_{2,0}} & {w_{2,1}} & {w_{2,2}} \end{array}\right)\),為了便於理解,將卷積寫成矩陣乘法形式,令\(\mathbf{x}\)為\(4\times 4\)輸入矩陣以行優先方式拉成的長度為16的向量,\(\mathbf{y}\)為\(2\times 2\)輸出矩陣以同樣方式拉成的長度為4的向量,同時將\(\mathbf{w}\)表示成\(4\times 16\)的稀疏矩陣\(\mathbf{C}\),
\[ \left(\begin{array}{cccccccccccccccc}{w_{0,0}} & {w_{0,1}} & {w_{0,2}} & {0} & {w_{1,0}} & {w_{1,1}} & {w_{1,2}} & {0} & {w_{2,0}} & {w_{2,1}} & {w_{2,2}} & {0} & {0} & {0} & {0} & {0} \\ {0} & {w_{0,0}} & {w_{0,1}} & {w_{0,2}} & {0} & {w_{1,0}} & {w_{1,1}} & {w_{1,2}} & {0} & {w_{2,0}} & {w_{2,1}} & {w_{2,2}} & {0} & {0} & {0} & {0} \\ {0} & {0} & {0} & {0} & {w_{0,0}} & {w_{0,1}} & {w_{0,2}} & {0} & {w_{1,0}} & {w_{1,1}} & {w_{1,2}} & {0} & {w_{2,0}} & {w_{2,1}} & {w_{2,2}} & {0} \\ {0} & {0} & {0} & {0} & {0} & {w_{0,0}} & {w_{0,1}} & {w_{0,2}} & {0} & {w_{1,0}} & {w_{1,1}} & {w_{1,2}} & {0} & {w_{2,0}} & {w_{2,1}} & {w_{2,2}}\end{array}\right) \]
則convolution過程可以描述為\(\mathbf{C} \mathbf{x} = \mathbf{y}\),若\(\mathbf{C}_{i,j}=0\)表示\(\mathbf{x}_j\)和\(\mathbf{y}_i\)間沒有連線。
transposed convolution過程
再看transposed convolution過程,如何將長度為4的向量\(\mathbf{y}\)對映為長度為16的向量且保持連線方式相同?只需將\(\mathbf{C}\)轉置,令\(\mathbf{C}^T \mathbf{y} = \mathbf{x}'\),同樣地,\(\mathbf{C}^T_{j,i}=0\)表示\(\mathbf{x}'_j\)和\(\mathbf{y}_i\)間沒有連線。
此時,\(\mathbf{C}^T\)對應的卷積操作恰好相當於將kernel中心對稱,FULL zero padding,然後卷積,此時,1個藍色塊與9個綠色塊連線,且權重與Convolution過程相同
需要注意的是,transposed convolution的kernel與convolution的kernel可以有關,也可以無關,需要看應用在什麼場景,
- 在特徵視覺化、訓練階段的反向傳播中應用的transposed convolution,並不是作為一個真正的layer存在於網路中,其kernel與convolution共享(但要經過中心對稱後再卷積,相當於上面的 $ \mathbf{C} ^T $)。
- 在影象分割、生成模型、decoder中使用的transposed convolution,是網路中真實的layer,其kernel經初始化後需要通過學習獲得(所以卷積核也就無所謂中心對稱不對稱了)。
- 前向傳播為convolution/transposed convolution,則反向傳播為transposed convolution/convolution。
在上面舉的簡化的例子中,我們可以通過分析得知transposed convolution該如何進行,但是,對於更一般情況應該怎麼做?
transposed convolution的計算
對於一般情況,只需把握一個宗旨:transposed convolution將output size恢復為input size且保持連線方式相同。
對於convolution過程,我們知道其output map與input map的尺寸關係如下:
\[o=\left\lfloor \frac{i+2p-k}{s} \right\rfloor + 1\]
若要將\(o\)恢復為\(i\),需考慮2種情況,\(\frac{i+2p-k}{s}\)整除以及不整除,先看整除的情況。
整除的情況
如果\(\frac{i+2p-k}{s}\)可以整除,則由上式可得
\[i = so-s+k-2p = [o+(s-1)(o-1)]+(k-2p-1)\]
因為transposed convolution也是卷積,為了符合上面卷積操作尺寸關係的數學形式,可進一步整理成
\[i = \frac{[o+(s-1)(o-1)] + [(k-1)+(k-2p-1)] - k}{1} + 1\]
令\(i'=o+(s-1)(o-1)\)、$p'=\frac{(k-1)+(k-2p-1)}{2} = k-p-1 \(、\)s'=1\(、\)k'=k$,即transposed convolution實際卷積時使用的超引數,可以這樣理解:
\(i'=o+(s-1)(o-1)\):convolution的輸出為\(o\times o\),每行每列都是\(o\)個元素,有\(o-1\)個間隔,transposed convolution時在每個間隔處插入\(s-1\)個0,整體構成transposed convolution的input map;
$p'=\frac{(k-1)+(k-2p-1)}{2} = k-p-1 $:在上一步input map的基礎上再進行padding,考慮convolution常用的幾種padding情況:
- VALID:\(p=0\),transposed convolution則需padding \(p'=k-1\),即FULL padding
- SAME:\(p=\frac{k-1}{2}=r\),這裡考慮\(k=2r+1\)為奇數的一般情況,此時\(p'=r\),即SAME padding
- FULL:\(p=k-1\),則\(p'=0\),即VALID padding
可見,convolution和transposed convolution的padding也具有某種對稱性\(p'+p=k-1\);
\(k'=k\):transposed convolution的kernel size與convolution相同;
- \(s'=1\):transposed convolution的stride均為1,但也可以換個角度理解,如果認為\(o\times o\)相鄰元素間的距離為1個畫素,那麼在間隔處插入\(s-1\)個0後(\(s > 1\)),得到的input map相鄰元素間的距離就是亞畫素的(sub-pixel),所以此時也可以稱之為 sub-pixel or fractional convolution;
\(o'=i=\frac{i'+2p'-k'}{s'}+1\):transposed convolution的輸出與convolution的輸入具有相同尺寸。
不整除的情況
接下來再看\(\frac{i+2p-k}{s}\)不整除的情況,此時再按上面的方式計算得到的\(o'=\frac{i'+2p'-k'}{s'}+1\)將小於\(i\),小多少呢?不難得出少\(a = [(i+2p-k) \mod s]\),即
\[o'=\frac{i'+2p'-k'}{s'}+1=i-a\]
為了讓\(o'=i\),可寫成
\[o'= \frac{i'+2p'+a-k'}{s'}+1\]
只需在padding後,在下邊和右邊再擴充套件\(a\)行和列0,然後進行卷積即可。注意,因為\(s'=1\),我們可以將\(a\)放在分母也可以放在外面,之所以放在分母,是因為convolution過程中input map下邊和右邊的\(a\)行或列中的元素可能參與了運算,即與output map間存在連線,所以在transposed convolution時,為了保持同樣的連線,最後擴充套件的\(a\)行和列也要參與卷積,所以放在分母。
至此,再看transposed convolution的各種情況,就很容易推算了,更多例子可參見A guide to convolution arithmetic for deep learning。
總結
最後,總結一下,
- convolution和transposed convolution互為對稱過程,存在一個convolution,就存在一個與之對應的transposed convolution,反之亦然;
- convolution是將input size的map對映為output size的map,transposed convolution是將output size的map對映為input size的map——旨在將尺寸恢復;
- 兩者均使用卷積操作,為了方便,兩者使用同樣的stride、padding、kernel size超引數,但實際執行時的操作不同,一般情況下,transposed convolution與convolution實際超引數關係為:\(i'=o+(s-1)(o-1)\)、$p'=\frac{(k-1)+(k-2p-1)}{2} = k-p-1 \(、\)s'=1\(、\)k'=k$。
- 之所以做這樣的操作,是為了保證map間的連線方式相同(權重不一定相同),權重的設定需根據應用的場景,可能通過學習得到,也可能與convolution共享(但需要中心對稱後再使用)。
參考
- vdumoulin/conv_arithmetic
- A guide to convolution arithmetic for deep learning
- winter1516_lecture13.pdf
- Is the deconvolution layer the same as a convolutional layer?
- What are deconvolutional layers?