目錄git
博客:blog.shinelee.me | 博客園 | CSDNgithub
開篇先上圖,圖爲deconvolution在像素級語義分割中的一種應用,直觀感受deconvolution是一個upsampling的過程,像是convolution的對稱過程。網絡
本文將深刻deconvolution的細節,並經過以下方式展開:ide
首先要明確的是,deconvolution並非個好名字,由於它存在歧義:學習
本文談論的是deconvolution的第2個含義,後面統一使用transposed convolution這個名字。ui
什麼是transposed convolution?A guide to convolution arithmetic for deep learning中有這樣一段話:spa
看無缺像仍不是很直觀,transposed convolution到底對應的是什麼操做?等到文章的後面,這個問題的答案會逐漸清晰起來。.net
下面先以1個例子來對比convolution過程和transposed convolution過程,採用與A guide to convolution arithmetic for deep learning相同的設置:code
若令\(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,以下圖所示:blog
能夠看到,convolution過程zero padding的數量與超參數\(p\)一致,可是transposed convolution實際的zero padding的數量爲2,爲何會這樣?是爲了保持鏈接方式相同,下面具體看一下。
先看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過程,如何將長度爲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該如何進行,可是,對於更通常狀況應該怎麼作?
對於通常狀況,只需把握一個宗旨: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狀況:
可見,convolution和transposed convolution的padding也具備某種對稱性\(p'+p=k-1\);
\(k'=k\):transposed convolution的kernel size與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。
最後,總結一下,