1. 程式人生 > >你知道如何計算CNN感受野嗎?這裡有一份詳細指南

你知道如何計算CNN感受野嗎?這裡有一份詳細指南

   作者: 葉  虎 

編輯:趙一帆

前  言


本文翻譯自A guide to receptive field arithmetic for Convolutional Neural Networks,原作者保留版權。

感受野(receptive field,RF)也許是CNN中最重要的概念之一,從文獻上來看,它應當引起足夠的重視。目前所有最好的影象識別方法都是在基於感受野理念來設計模型架構。然而,據我所知,目前並沒有一個完整的教程來介紹如何計算並可視化一個CNN的感受野。這篇文章將填補這一空白,這裡介紹CNN特徵圖視覺化的一種新方法,視覺化可以顯示感受野資訊,並且給出一個完整的感受野計算公式,它適用於任何CNN架構。我也實現了一個簡單的程式來驗證這個計算公式,任何人都可以利用該公式計算它們所設計的CNN的感受野,從而對所設計的架構有更多的認識。

要閱讀這篇文章,你必須要熟悉CNN的核心概念,特別是卷積和池化操作。你可以通過閱讀這篇論文(A guide to convolution arithmetic for deep learning)來複習CNN的基礎知識。如果你對CNN有一定的瞭解,你將用不了半個小時來看完。這篇文章實際上是在這篇論文基礎上完成的,使用相同的符號標記。

如果你想學習CNN如何應用在影象識別上,可以閱讀這篇文章。

1

固定大小的CNN特徵圖視覺化

感受野指的是一個特定的CNN特徵(特徵圖上的某個點)在輸入空間所受影響的區域。一個感受野可以用中心位置(center location)和大小(size)來表徵。然而,對於一個CNN特徵來說,感受野中的每個畫素值(pixel)並不是同等重要。一個畫素點越接近感受野中心,它對輸出特徵的計算所起作用越大。這意味著某一個特徵不僅僅是受限在輸入圖片中某個特定的區域(感受野),並且呈指數級聚焦在區域的中心。這個重要的發現會在下一篇文章中講。現在,我們關注如何計算一個特定感受野的中心位置和大小。

圖1為給出了某些感受野例項。其中輸入特徵圖大小為5X5,採用的卷積引數如下:卷積核大小k=3X3,padding大小p=1X1,步長s=2X2。經過一次卷積之後,得到大小為3X3的輸出特徵圖(綠色)。在這個特徵圖上繼續採用相同的卷積,得到一個2X2的特徵圖(橙色)。輸出特徵圖的大小可以通過如下公式計算(參考A guide to convolution arithmetic for deep learning):

640?wx_fmt=png

為了簡化講解,這裡假定CNN架構是對稱的,並且輸入圖片是方形的。因此所有的卷積層的所有引數在兩個維度上都是相同的。如果CNN架構或者輸入圖片是非對稱的,你可以為各個維度單獨計算特徵圖的屬性。

640?wx_fmt=png

圖1 CNN特徵圖的兩種視覺化方

圖1的左欄給出了CNN特徵圖視覺化最常用的方式。在這個視覺化中,我們可以看到每個特徵圖所包含的特徵數,但是很難知道每個特徵的感受野的中心位置和大小,對於深度CNN,我們沒有辦法追蹤到感受野資訊。右欄給出的是固定大小的CNN視覺化,所有的特徵圖固定大小並保持與輸入特徵圖大小一致,這可以解決前面的問題。每個特徵被標記在其感受野所在的中心(從而定位出感受野中心位置)。由於一個特徵圖中所有的特徵都有相同大小的感受野,我們可以簡單地在每個特徵周圍畫出一個邊界框,從而獲得感受野的大小。我們也沒有必要將這個邊界框向下對映到輸入層,因為特徵圖已經與輸入層具有相同的大小。圖2給出了另外一個例項,其中輸入特徵圖更大,為$7\times7$,與前面例子採用相同的卷積。圖的左欄和右欄分別給出了固定大小CNN特徵圖的3D和2D視覺化。可以看出感受野大小增加迅速,以至於第二個特徵層的中心特徵的感受野已經覆蓋了整個輸入特徵圖。這在深度CNN中是一個很重要的設計理念以提升效能。

640?wx_fmt=png

圖2 7x7大小的輸入特徵圖的可視

2

感受野計算公式

為了計算CNN每一層的感受野,除了要知道特徵圖每個維度的特徵數n,還需要記錄每一層的其他資訊,這包括當前層的感受野大小r,兩個相鄰特徵的距離(跳躍的距離,如前面視覺化所示)j,和左上角特徵(第一個特徵)的中心座標start。注意感受野(其實是特徵圖第一個特徵的感受野)的中心座標就等於這個特徵的中心座標,就如前面視覺化中所示。當採用的卷積其核大小為k,padding大小為p,步長為s,輸出特徵圖的感受野可以按照如下公式計算:

640?wx_fmt=png

  • 第一個式子根據輸入特徵圖大小以及卷積引數計算輸出特徵圖大小,前面已經說過。

  • 第二個式子計算輸出特徵圖的特徵間的間隔,其等於上一層的間隔值乘以卷積的步長,所以間隔值將是按照步長呈指數級增長。

  • 第三個式子計算輸出特徵圖的感受野大小,其等於前一層感受野大小加上(k-1) * j_in,所以感受野是呈指數級增加,並且還有一個因子k-1。

  • 第四個式子計算輸出特徵圖的第一個特徵感受野的中心座標,其等於第一層的中心座標加上(k-1) / 2 * j_in,再減去p j_in,注意兩項都要乘以前一層的間隔距離以得到實際距離。

對於第一層,一般是輸入圖片,其各項值為:n=image_size, r=1, j =1, start=0.5。圖3給出了一個如何計算感受野的例項,圖中的座標系統中,輸入層的第一個特徵中心位置記為0.5。通過利用上面公式迭代地進行計算,你可以計算出CNN中所有特徵圖的感受野資訊。

640?wx_fmt=png

我也寫了一個簡單的Python程式來計算某個特定CNN架構的各個層的感受野資訊。它可以通過輸入某一個特徵圖的姓名或者索引值,給出相應的感受野大小和位置資訊。下面的圖給出了在AlexNet上的計算結果:

640?wx_fmt=png

3

附文

對於感受野大小的計算,另外有一個部落格(Calculating Receptive Field of CNN)給出一個更簡潔的計算公式,對於第k層的感受野大小計算如下:

640?wx_fmt=png

其中l_k-1是第k-1層的感受野大小,而f_k是當前層的卷積核大小,s_i是第i層的步長。從這個公式可以看到,相比前一層,當前層的感受野大小在兩層之間增加了

640?wx_fmt=png

如果stride大於1的話,這是一個指數級增加。這個公式也可以這樣理解,對於第k層,其卷積核為f_k,那麼相比前一層需要計算 f_k個位置(或者神經元,意思是k層的一個位置在k-1層的視野大小是f_k),但是這些位置要一直向前擴充套件到輸入層。對於第一個位置,擴充套件後的感受野為l_k-1,正好是前一層的感受野大小,但是對於剩餘的f_k-1 個位置就要看stride大小,你需要擴充套件到前面所有層的stride(注意不包括當前層的stride,當前層的stride只會影響後面層的感受野),所以需要乘以

640?wx_fmt=png

這樣剩餘f_k-1個位置的感受野大小就是

640?wx_fmt=png

和第一個位置的感受野加到一起就是上面的公式了。。其實這個公式算是整合了前面的公式2和公式3(第一層的j=1$),兩個本質上是一致的,不過如果你僅想計算感受野大小可以用這個公式更方便。


小結

在CNN中,感受野應該是一個很重要的東西,但是往往被大家忽略,在我看到的文獻中,影象分割模型DeepLab就提到了感受野大小的問題,但是那裡並沒有給出計算公式,如果採用上面的公式就可以快速得到結果。對於影象分割,感受野大小對分割效果是有很大影響的,所以DeepLab採用了擴展卷積(Atrous Convolution, Dilated Convolution)來增加感受野大小。對於空洞卷積來說,你可以將其轉化為普通卷積(卷積核大小增加)來計算特徵圖的感受野。另外,上面的公式同樣適用於池化層,因為其在結構上與卷積層是類似的。

end

機器學習演算法工程師

                            一個用心的公眾號

640?wx_fmt=jpeg

長按,識別,加關注

進群,學習,得幫助

你的關注,我們的熱度,

我們一定給你學習最大的幫助