1. 程式人生 > >由淺入深:CNN中卷積層與轉置卷積層的關系

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

更多 deep 每次 展開 大禮包 位移 入門 ssg 得出

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

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

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

1. 卷積層和全連接層

在CNN提出之前,我們所提到的人工神經網絡應該多數情況下都是前饋神經網絡,兩者區別主要在於CNN使用了卷積層,而前饋神經網絡用的都是全連接層,而這兩個layer的區別又在於全連接層認為上一層的所有節點下一層都是需要的,通過與權重矩陣相乘層層傳遞,而卷積層則認為上一層的有些節點下一層其實是不需要的,所以提出了卷積核矩陣的概念,如果卷積核的大小是nm,那麽意味著該卷積核認為上一層節點每次映射到下一層節點都只有n

m個節點是有意義的,具體的映射方式下一節會講到。到這裏,有些初學者會認為全連接層也可以做到,只要讓權重矩陣某些權重賦值為0就可以實現了,例如假設在計算當前層第2個節點時認為上一層的第1個節點我不需要,那麽設置w01=0就可以了。其實沒錯,卷積層是可以看做全連接層的一種特例,卷積核矩陣是可以展開為一個稀疏的包含很多0的全連接層的權重矩陣,下圖就是一個由44圖片經過33卷積核生成一個大小為2*2output時,卷積核所展開的全連接層的權重矩陣。

技術分享圖片卷積核對應的全連接層權重矩陣

可以看到,上面的矩陣大小為416,比卷積核33大了不少,因此使用卷積層而不用全連接層第一個原因就是可以極大的減少參數的個數,第二個原因就是卷積核關註的是某幾個相鄰的節點之間的關系,學習了圖片的局部特征,可以說是帶有目的性的學習,例如33的卷積核學習的就是相互距離為2的節點之間的關系。這與全連接層無區別的對待所有節點進行學習有極大的差別,這樣一來就解決了前饋神經網絡不能學習位移不變性的缺點。舉個栗子,當我們在前饋神經網絡中學習一個4

4的圖片中是否有橫折圖案時,使用下圖中4個訓練數據進行訓練,那麽最終只會對5,6,9,a這四個節點的權重有所調節,然後如果出現如下圖最後一張圖片作為測試時,就會導致網絡無法識別,而由於卷積核在不同節點間權重是共享的,所以就自然而然克服了這個問題。

技術分享圖片卷積克服平移不變性

2. 卷積層的運算過程

2.1 最簡單的卷積

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

技術分享圖片no padding, no stride的卷積

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

技術分享圖片論文常見的卷積層

2.2 帶padding的卷積

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

技術分享圖片padding=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比輸入的小。

技術分享圖片no padding, stride=2的卷積

技術分享圖片padding=1, stride=2的卷積

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

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

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

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

技術分享圖片odd卷積

3. 轉置卷積層

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

技術分享圖片轉置卷積例子

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

技術分享圖片no padding, no stride的卷積

技術分享圖片轉置卷積.png

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

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

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

技術分享圖片no padding, no stride的卷積轉置

3.2 帶padding的卷積的轉置卷積

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

技術分享圖片padding為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。

技術分享圖片stride為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對該參數的描述,和我們遇到的情形一模一樣。

技術分享圖片PyTorch中轉置卷積的output_padding參數

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

4. 總結

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

5. 參考文檔

  • 知乎上對CNN的直觀解釋,平移不變性筆者是從這裏了解到的
  • 《A guide to convolution arithmetic for deep learning》的github,本文的動圖都來自於此
  • 關於轉置卷積和卷積的聯系和區別

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

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

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

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

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