1. 程式人生 > >一文搞懂 deconvolution、transposed convolution、sub-­pixel or fractional convolution

一文搞懂 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並不是個好名字,因為它存在歧義:

  1. deconvolution最初被定義為“inverse of convolution”或者“inverse filter”或者“解卷積”,是指消除先前濾波作用的方法。比如,我們認為原始影象是清晰的,但是通過透鏡觀測到的影象卻變得模糊,如果假設透鏡的作用相當於以某個kernel作用在原始影象上,由此導致影象變得模糊,那麼根據模糊的影象估計這個kernel或者根據模糊影象恢復原始清晰影象的過程就叫deconvolution。
  2. 後來論文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?