由淺入深:CNN中卷積層與轉置卷積層的關係

歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~

本文由forrestlin發表於雲+社區專欄

導語:轉置卷積層(Transpose Convolution Layer)又稱反捲積層或分數卷積層,在最近提出的卷積神經網絡中越來越常見了,特別是在對抗生成神經網絡(GAN)中,生成器網絡中上採樣部分就出現了轉置卷積層,用於恢復減少的維數。那麼,轉置卷積層和正卷積層的關係和區別是什麼呢,轉置卷積層實現過程又是什麼樣的呢,筆者根據最近的預研項目總結出本文。

1. 卷積層和全連接層

在CNN提出之前,我們所提到的人工神經網絡應該多數情況下都是前饋神經網絡,兩者區別主要在於CNN使用了卷積層,而前饋神經網絡用的都是全連接層,而這兩個layer的區別又在於全連接層認爲上一層的所有節點下一層都是需要的,通過與權重矩陣相乘層層傳遞,而卷積層則認爲上一層的有些節點下一層其實是不需要的,所以提出了卷積核矩陣的概念,如果卷積核的大小是nm,那麼意味着該卷積核認爲上一層節點每次映射到下一層節點都只有nm個節點是有意義的,具體的映射方式下一節會講到。到這裏,有些初學者會認爲全連接層也可以做到,只要讓權重矩陣某些權重賦值爲0就可以實現了,例如假設在計算當前層第2個節點時認爲上一層的第1個節點我不需要,那麼設置w01=0就可以了。其實沒錯,卷積層是可以看做全連接層的一種特例,卷積核矩陣是可以展開爲一個稀疏的包含很多0的全連接層的權重矩陣,下圖就是一個由44圖片經過33卷積核生成一個大小爲2*2output時,卷積核所展開的全連接層的權重矩陣。

img卷積覈對應的全連接層權重矩陣

可以看到,上面的矩陣大小爲416,比卷積核33大了不少,因此使用卷積層而不用全連接層第一個原因就是可以極大的減少參數的個數,第二個原因就是卷積核關注的是某幾個相鄰的節點之間的關係,學習了圖片的局部特徵,可以說是帶有目的性的學習,例如33的卷積核學習的就是相互距離爲2的節點之間的關係。這與全連接層無區別的對待所有節點進行學習有極大的差別,這樣一來就解決了前饋神經網絡不能學習位移不變性的缺點。舉個栗子,當我們在前饋神經網絡中學習一個44的圖片中是否有橫折圖案時,使用下圖中4個訓練數據進行訓練,那麼最終只會對5,6,9,a這四個節點的權重有所調節,然後如果出現如下圖最後一張圖片作爲測試時,就會導致網絡無法識別,而由於卷積核在不同節點間權重是共享的,所以就自然而然克服了這個問題。

img卷積克服平移不變性

2. 卷積層的運算過程

2.1 最簡單的卷積

卷積層的運算其實就是將多個卷積核作用於輸入上,如下圖所示,是最簡單的一個卷積核所做的運算,no padding,no stride,底下藍色方塊看做是輸入的圖片,陰影部分就是33的卷積核(一般卷積核是個正方形,且邊長爲奇數),卷積核掃過時便與輸入相乘再相加,最終得到22的輸出,對應青色區域。

imgno padding, no stride的卷積

通常一層卷積層會包含多個卷積核,代表着卷積層的輸出深度,例如下圖就是我們經常在論文中看到的深度網絡的架構,其中第一層就是卷積層+最大池化層,先不管最大池化層,至少我們可以明確卷積核的大小是55,卷積核個數是16,該層輸出的size是1818。

img論文常見的卷積層

2.2 帶padding的卷積

從最簡單的卷積動圖中我們可以看到,經過卷積操作,輸出會比輸入要小,但是有時候我們希望輸出的size要與輸入保持一致,而padding就是爲了這個而引入的,而這種爲了讓輸入和輸出size保持一樣的padding,我們會稱之爲"same padding",可參考下面的動圖,卷積核大小是3*3,padding是1,padding實際的表現就是在輸入的四周補0,padding是多少就補多少層,且上限是卷積核大小-1,正如下圖中虛線區域,一般來說,論文中是不會給出padding的大小,需要我們自己推導,推導公式可見下文。

imgpadding=1的卷積

根據padding大小不同,我們可以分爲三種padding:

  • same padding: 爲了讓輸出和輸入的size一樣而補上的padding,例如33的核,same padding = 1,55的核,same padding = 2。
  • full padding: padding = kernel size - 1
  • valid padding: padding = 0

2.3 stride大於1的卷積

stride就是步長,表示卷積核兩次卷積操作的距離,默認是1,上述講的兩個例子步長都是1,而下面兩個動圖展示的是stride爲2的情況,分別是無padding和有padding的情況。通常stride大於1時我們稱爲等距下采樣,因爲這樣輸出肯定會丟失信息,size比輸入的小。

imgno padding, stride=2的卷積

imgpadding=1, stride=2的卷積

2.4 卷積核輸入輸出size與卷積核的關係

上文中我們提到padding通常需要我們自己算出來,那麼我們該怎麼算呢,其實就是根據輸入輸出size和卷積核大小的關係算出來的,上面提到的幾種卷積,其實就是卷積操作的三個參數,核大小(F)、padding(P)和stride(S),如果細心的讀者在看動圖時就會發現輸出size是可以根據輸入size和那三個參數計算出來的,公式如下,這裏只給出寬度的計算,高度也是一樣的。

W2=(W1−F+2P)÷S+1

這裏我們注意到上面的公式是有除法的,所以就會存在除不盡的情況,這時候我們需要向下取整,這種情況我們稱爲odd卷積,其過程可參考下面動圖。

imgodd卷積

3. 轉置卷積層

講完卷積層後,我們來看CNN中另一個進行卷積操作的層次轉置卷積層,有時我們也會稱做反捲積層,因爲他的過程就是正常卷積的逆向,但是也只是size上的逆向,內容上不一定,所以有些人會拒絕將兩者混爲一談。轉置卷積層最大的用途就是上採樣了,剛剛我們說到在正常卷積中stride大於1時我們進行的是等距下采樣,會讓輸出的size比輸入小,而轉置卷積層我們就會用stride小於1的卷積進行上採樣,使輸出的size變大,所以轉置卷積層還有個別稱就是分數卷積層。上採樣最常見的場景可以說就是GAN中的生成器網絡,如下圖所示,雖然論文作者使用的是conv,但由於它的步長爲1/2,所以代表的就是轉置卷積層。

img轉置卷積例子

爲了理解轉置卷積層,我們需要明白什麼叫做正常卷積的逆向,這通常也是新手難以理解的地方,下面筆者通過兩個圖來更好的解釋,第一個圖是正常卷積的過程,第二個圖就是其對應的轉置卷積,在第一個圖中,大的正方形中數字1只參與小正方形中數字1的計算,那麼在轉置卷積中,大正方形的1也只能由小正方形的1生成,這就是逆向的過程。

imgno padding, no stride的卷積

img轉置卷積.png

和講述正常卷積的過程一樣,筆者下面也會一一給出相對應的轉置卷積。

3.1 no padding no stride的卷積對應的轉置卷積

上面用作解釋轉置卷積的逆向過程時用到的圖其實就是最簡單(no padding, no stride)卷積以及其對應的轉置卷積,這裏給出它的動圖。

imgno padding, no stride的卷積轉置

3.2 帶padding的卷積的轉置卷積

在正卷積中如果是有padding,那麼在轉置卷積中不一定會有padding,其計算公式下文會給出,這裏先給出2.2對應的轉置卷積動圖。

imgpadding爲1的卷積轉置

3.3 stride大於1的卷積的轉置卷積

在本節一開始就講到,stride大於1的卷積是下采樣,那麼其對應的轉置卷積便是stride小於1的上採樣,但是不管是在pyTorch還是TensorFlow中,convTranspose函數的參數都是整數,不可能將stride設置爲小於1的浮點數,那麼我們會依然給convTranspose函數傳入正卷積的stride,而convTranspose是怎麼做的呢,可見下面的動圖,它是2.3中無padding卷積對應的轉置卷積,我們先不看轉置卷積中的轉置padding,也就是動圖中外部的虛線區域,然後會發現每兩個藍色塊之間都插入了白色塊,也就是0,這樣一來,卷積核每移動一步不就相當於是隻移動了1/2步嘛,所以我們可以得出每兩個藍色塊之間需要插入stride -1個0。

imgstride爲2的卷積轉置

3.4 正卷積和轉置卷積的換算關係

3.4.1 轉置卷積的padding

從上面3個例子的轉置卷積中我們可以發現,如果用正卷積實現轉置卷積時,卷積核的大小是保持不變的,而stride是爲正卷積stride的倒數(只是我們插入0來模擬分數移動),最後,轉置卷積的padding要怎麼算呢,雖然如果我們調用pyTorch或TensorFlow時不需要管,傳入正卷積的padding即可,但是理解convTranspose是怎麼做的也有助於我們理解轉置卷積。說了這麼多,其實在我們爲了讓轉置卷積保證是正卷積的逆向時,我們就不得不補充轉置padding,我們用PT表示,其計算公式爲:PT=F−P−1,其中F爲正卷積的核大小,P爲正卷積的padding。

3.4.2 轉置卷積的輸出size

這個其實很好算,因爲我們都說轉置卷積的逆向,所以我們只需在2.4給出公式中轉換下求出W1即可,公式如下:

W1=(W2−1)×S−2P+F

其中S是正卷積的stride,P是正卷積的padding,F是正卷積的核邊長。

3.4.3 odd卷積的轉置卷積

這個可以說是轉置卷積中最難理解的一種情況,在2.4中我們提到在除以stride時可能會除不盡要向下取整,那麼我們在求W1時就會有不確定性,舉個栗子,還是第3節一開始給出的圖,我們是希望將W/4的圖放大到W/2的程度,這是一個轉置卷積的過程,我們先算一遍正卷積,從W/2下采樣到W/4,k代表核邊長爲3,s是stride爲1/2的倒數,即2,padding根據2.4的公式推導爲1,所以正卷積的計算公式是:(W2−3+2)÷2+1=W4+12,然後向下取整就是W4,和圖上顯示的是一樣,但是如果我們通過3.4.2的公式反過來計算,就是(W4−1)×2−2+3=W2−1,這就是odd轉置卷積的不確定性,我們再回頭看2.4給出的動圖,會發現右邊和下邊的填充區域我們並沒有進行卷積運算,因爲向下取整而忽略了,所以我們在轉置卷積時需要將這部分加回來,因此,在PyTorch中convTranspose函數還有一個參數output_padding就是負責處理這個的,TensorFlow應該也有相應的參數,筆者不太熟悉,下面就是PyTorch對該參數的描述,和我們遇到的情形一模一樣。

imgPyTorch中轉置卷積的output_padding參數

至於output_padding的值,應該爲(W1−F+2P)%S,在上面提到的例子中就應該是1。

4. 總結

本文先是介紹了卷積神經網絡和傳統的前饋神經網絡的聯繫和區別,然後再通過不同參數的卷積過程闡述卷積運算,最後再介紹剛入門深度學習時晦澀難懂的轉置卷積,給出不同參數下正卷積所對應的轉置卷積,最後總結出在卷積運算中所用到的公式。希望筆者上述的分析和解釋能對剛入門CNN的同學有所幫助,而且筆者是從事iOS開發的,對於CNN和深度學習也是剛剛入門,希望各位AI大牛們不吝指教。

5. 參考文檔

相關閱讀
【每日課程推薦】機器學習實戰!快速入門在線廣告業務及CTR相應知識

此文已由作者授權騰訊雲+社區發佈,更多原文請點擊

搜索關注公衆號「雲加社區」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!

海量技術實踐經驗,盡在雲加社區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章