現在我們看Conv2層中的一個像素塊的感受野是多少?也就是這一個像素塊代表inputs中的多少個像素塊?咱們就從這個圖分析,首先Conv2中的一個像素塊,代表Conv1中的6個像素塊;而Conv1中的一個像素塊代表Inputs中6個像素塊,那麼是不是Conv2中的一個像素塊就代表Inputs中的6*6個像素塊呢?這個回答是錯誤的,正確的回答是代表5*5個像素塊。為什麼呢?為什麼呢?因為卷積運算有一個特點就是許多像素塊是重複參見卷積運算的,比如圖中標記出①的這三個像素塊,當kernel在初始位置的時候參加一次運算,當kernel向右移動1步的時候,它仍然參加捲積運算;並且,當kernel向下移動一步時候圖中①下邊兩個像素又再一次參加了卷積運算,所以說不能看每個卷積層featuremap中一個像素塊代表上一層幾個像素塊,然後在把它們乘起來。不知道我這麼解釋大家明白了嗎?
畫的有點亂,不要慌,從Conv2中的一個像素塊出發,看看它代表Inputs多少塊像素?Conv2中的第一個像素,是通過Conv1中的編號1,2,3,5,6,7,9,10,11這9個像素塊與kernel卷積得到的,而且Conv1中的每個像素塊又是和Inputs中某9個像素塊卷積得到的,例如Conv1中的編號1像素塊是通過Inputs中的1,2,3,7,8,9,13,14,15,我們把Conv1中的編號1,2,3,5,6,7,9,10,11這9個像素塊都分析一遍,如圖中所示,可以看到Conv1中的編號1,2,3,5,6,7,9,10,11這9個像素塊共計與Inputs中編號為1,2,3,4,5,7,8,9,10,11,13,14,15,16,17,19,20,21,22,23,25,26,27,28,29這25個像素塊有不正當關係,所以我們判斷Conv2中的一個像素塊,代表了Inputs中的25個像素塊,也就是我們說的感受野為5*5。
從以上的分析來看,感受野的大小是有kernel的size決定的,但是還有一個因素就是strides的size。很好理解,strides越大,感受野越大。我也看了好多別人分析,在這裡就拿來借鑒一下,參考文章。以上說的都是簡單的、容易理解的,strides為1,padding=0。下面我們來看一篇就是關於感受野介紹的英文文章(A guide to receptive field arithmetic for Convolutional Neural Networks),原文我沒有登錄上,這是別人的資源。我英文不好,翻譯或者講解的不好大家理解。
作者說一個感受野用中心位置和大小來表徵。並且感受野中的每個像素值(pixel)並不是同等重要的。一個像素點越接近感受野中心,它對輸出特徵的計算所起的作用越大。這意味著某一個特徵不僅僅是受限在輸入圖片中某個特定的區域(感受野),並且呈指數級聚焦在區域的中心。直接上圖了,就不一一翻譯了!
先看左邊的圖,這是一個關於(i=5,p=1,s=2,k=3)和(i=3,p=1,s=2,k=3)的兩次卷積操作,這是一個正常的卷積操作圖。咱們先分析圖①,應該很簡單吧,外邊填充1圈0,然後用公式o=(i+2p-n)/s+1=(5+2-3)/2+1=3,所以輸出的featuremap是3×3的。在分析圖③,稍微有點蒙,為什麼外邊填充3圈0呢?其實這裡有個過渡,作者沒有給出。第二次卷積操作也需要在第一次輸出的featuremap的外圍填充1圈0,填充之後第一次輸出的featuremap就變成5×5了,但是如果我要得到5×5的featuremap,原圖要多大呢?用公式o=(i+2p-n)/s+1→→5=(5+2p-3)/2+1→→p=3,所以圖③外圍填充了3圈0,才能輸出size為2×2的featuremap。
圖②和圖④可能有點難理解,這是文章作者提出的一種方法叫做固定大小的CNN特徵圖可視化。就是讓所有的輸出featuremap與輸入的圖像的size一樣,並把每個輸出featuremap中的特徵(像素塊)標記在感受野的中心。
如圖②原始的featuremap時5×5的,經過卷積之變成3×3的,但是作者不想讓它是3×3,也想把它變成5×5的,並且讓卷積之後featuremap中的每個像素塊對應著原始卷積運算的中心。如果想把輸出的featuremap的size為3×3變成5×5,作者提出了一種方法就是在輸出的featuremap的每個像素塊之間插入一個值為0的像素塊,為什麼這麼做呢?因為針對某一個featuremap中的每一個feature都有相同的感受野,所以我們可以簡單地在每個feature周圍畫出邊界框,從而獲得感受野的大小。這裡提一句,我引用的圖是文章中的原圖,可能作者的原圖稍微有些錯位,應該是填充一圈0,不知道為什麼圖②的原始featuremap的右側多出一列。為什麼每個像素塊之間填充一個0呢?因為我們的strides為2,kernel也要移動2步,因此卷積之後的feature也移動2步(走兩步中間只差一步),所以卷積操作之後的每個像素塊之間填充一個0,就可以和原featuremap同樣大小。
咱們看第二次卷積,k=3,p=1,s=2,基本步驟如下圖:
從這兩個例子中我們能發現,無論輸出的featuremap的size是多少,相同kernel,相同padding,相同strides,感受野的大小都是一樣的,如上圖,第一次卷積的感受野都是3×3,第二次卷積的感受野都是7×7。也就是說感受野的大小可能只與這三個參數有關(kernel,padding,strides)。
作者給出了計算方法,我們需要了解四個公式,並要掌握各個相關參數的定義。
這個公式①,我們很熟悉,正常的卷積操作,就是這樣計算的,不用過多介紹。
這個公式②,我們第一次見到,通過上文的講解,可能大家能看明白,並且我們說過感受野有兩個重要的參數,一個是中心,一個是大小。中心是啥?
這個公式②有一句話我們要注意,間隔值是按照strides呈指數級增長,也就是說每層卷積的strides很重要,下面給出公式③,計算出感受野的大小。
從公式③可以看出,感受野大小與上一層的感受野大小、kernel的size以及輸入的featuremap的feature之間的間隔值有關。感受野也是呈指數級增加。
公式④計算輸出特徵圖的第一個特徵感受野的中心坐標,其等於第一層的中心坐標加上(k?1)/2?jin,再減去p?jin,注意兩項都要乘以前一層的間隔距離以得到實際距離。下面是利用公式計算具體實例。
對於感受野大小的計算還有一篇文章更為簡潔,上面說的都不是廢話,有助於你更好的理解感受野,但這個公式我們最好記住。
空洞卷積
上文了解了一下感受野的問題,接下來咱們言歸正傳,卷積(Convolution)、池化(Pooling)一般用於下採樣,而轉置卷積(Deconvolution)用於上採樣。空洞卷積(Dilated)是幹什麼用的呢?參考論文Multi-Scale Context Aggregation by Dilated Convolutions。它的產生是有背景的,2016年才被提出,它主要是為瞭解決圖像分割領域的問題,圖像分割需要輸入和輸出在像素的shape保持一致,但由於池化層的存在,因此導致FCN需要通過上採樣擴增size,但是上採樣並不能將丟失的信息無損的找回。這句話什麼意思?就是說池化是有缺點的,池化會帶來信息損失,那麼就把池化層去掉;但是池化去掉又產生缺點,就是感受野變小,這樣就會降低整個模型的預測精度。怎麼辦呢?如何在去掉池化下採樣操作的同時,而不降低網路的感受野呢?空洞(Dilated convolution)卷積應運而生!
空洞卷積通過在kernel的像素塊之間插入空格來產生新的空洞kernel,如下圖,而這個空格插入幾個呢?這時候就引入一個超參數d,叫膨脹率。通常在原有kernel的像素塊之間插入d-1個空格;而d=1對應一個常規卷積。大體形式還是看下圖,初次認識一下!
(a)圖:按照空洞卷積的叫法,被稱為3×3的1-dilated convolution。其中的1就是d=1,膨脹率為1的空洞卷積;但實際上也是一個常規3×3的卷積核。
(b)圖:3×3的2-dilated convolution。d=2,膨脹率為2的空洞卷積。
(c)圖:3×3的4-dilated convolution。d=4,膨脹率為4的空洞卷積。
現在我們大概知道空洞卷積長什麼樣子了,但是如果給一個輸入的featuremap,進行空洞卷積運算,怎麼得到輸出呢?或者更簡單的說,通過給定i、p、s、k、d怎麼計算出o呢?我們首先知道kernel變了,不在是原始的k×k了,變成如下:
所以outputs的size,如下:
我們可以看一個例子,原始的kernel的size為3×3,使用膨脹率為2的空洞卷積,kernel的size變為5×5(k』=k+(k-1)(d-1)=3+(3-1)(2-1)=5)。利用公式:o=(i+2p-k』)/s+1=(7+0-5)/1+1=3。利用上面的公式就可以計算了,如下圖。
但是還要繼續墨跡墨跡,空洞卷積中的洞是不參加捲積運算的,只是在幫助增大kernel的size,並且增加了感受野的大小,下面我們就說說空洞卷積感受野的問題,這時候我們就要想想上面說的感受野的相關知識點。
我們還記得感受野的計算公式嗎?
還是上邊這個圖,第一個圖代表第一層的3×3的1-dilated conv,中間的圖代表第二層的3×3的2-dilated conv,最後一個圖代表第三層的3×3的4-dilated conv,strides都為1。我們可以看到第一層的感受野為l1=3×3;第二層的感受野l2=l1+((f2-1)*1),f2就是上邊說的使用膨脹率2的kernel的變形,所以f2=5,因此第二層的感受野l2為7×7;同理第三層的感受野為l3=l2+((f3-1)*1),f3=k+(k-1)(d-1)=3+(3-1)(4-1)=9,因此第三層的感受野l3為15×15。
其實還有一種方法理解空洞卷積的感受野問題,第一個圖不用解釋了,感受野就是3×3,而第二個圖的感受野,可以這麼理解,其中的每一個紅點都是上一層3×3感受野卷積得到的,因此以每個紅點為中心,畫出3×3的區域,疊加之後為圖中7×7的感受野。第三個圖的每個紅點是7×7感受野卷積得到的,因此以每個紅點為中心,畫出7×7區域,疊加之後為圖中15×15的感受野。
不知道說明白了沒有,空洞卷積,在不使用pooling的情況下,同樣下採樣,並且感受野也明顯提高。但是它也有一定的弊端,網格效應和不利於小物體分割。解決辦法為
Understanding Convolution for Semantic Segmentation
Rethinking Atrous Convolution for Semantic Image Segmentation
推薦閱讀: