1. 概念

經典的目標檢測如Faster R-CNN, YOLOv3等都用到了Anchor, 怎麼設計Anchor每個目標檢測方法各不相同。Faster R-CNN中的Anchor有三種形狀,三種長寬比,比如形狀有[128, 256, 512]三個,長寬比有[1:1, 1:2, 2:1]三種,這樣組合就是9個anchor。YOLOv3中的Anchor是透過K-Means聚類得到的。這些基於anchor的方法的目的是學習一個從Anchor到GT Box的轉換函式,下邊我們瞭解一下

理論感受野、Anchor、實際感受野

三者之間的關係。

先看一張圖:

目標檢測和感受野的總結和想法

圖源Medium

一個kernel size=3的卷積核,透過在原feature map上劃窗,然後計算得到的是一個值,這個值是透過計算原來feature map上3×3面積上的值得到的結果,那就說經過這個3×3卷積以後,這一層feature map的感受野就是3×3。如果是兩個kernel size=3的卷積核堆疊起來,那麼上圖黃色的feature map每個值對應最下面的5×5的感受野。

理論感受野

:某一層feature map中的某一個位置,是由前面某一層固定區域輸入計算出來的,那這個固定區域就是這個位置的感受野。

實際感受野:

實際感受野要小於理論感受野,是在NIPS2016中的

Understanding the Effective Receptive Field in Deep Convolutional Neural Networks

提出的。

文章主要貢獻有以下幾點:

並不是感受野內所有畫素對輸出向量的貢獻相同,實際感受野是一個高斯分佈,有效感受野僅佔理論感受野的一部分

目標檢測和感受野的總結和想法

以上就是不同層下的不同的感受野。

目標檢測和感受野的總結和想法

目標檢測和感受野的總結和想法

使用不同的啟用函式與不同的卷積取樣方法,產生的實際感受野也不盡相同。其中ReLU的高斯分佈沒有另外兩個平滑,建立了一個較少的高斯分佈,ReLU導致很大一部分梯度歸零。

另外就是非常關心的問題,實際感受野是如何變化的?實際感受野和理論感受野的關係是什麼樣的?

目標檢測和感受野的總結和想法

文章中也給出了答案,見上圖,隨著網路層數的加深,

實際有效的感受野是程#FormatImgID_11#級別增長

。而右圖展示了隨著網路層數的加深,

有效感受野佔理論感受野的比例是按照#FormatImgID_12#級別進行縮減的

。其中需要注意的是實際感受野的計算方式:若畫素值大於(1-96。45%)的中心畫素值,就認為該畫素處於實際感受野中。

訓練的過程中,感受野也會發生變化。

目標檢測和感受野的總結和想法

可以看出分類和分割任務經過訓練後的感受野都有提升,不過提升幅度不太一樣。這也說明了神經網路透過學習,擴大了感受也,能夠自適應把越來越大的權重放在感受野之外的畫素上。也在一定程度上說明更大感受野的必要性。

2. 計算

2.1 一種簡單的感受野計算方法

以下內容整理自:zhihu@YaqiLYU

規定一下:k代表kernel size, s代表stride, r代表感受野

第一個feature map(也就是原始圖片)的感受野預設為1

經過kernelSize=k, s=1 的卷積層, 感受野計算方法如下:

r = r +(k-1) \\

經過kernelSize=k, s=2 的卷積層, 感受野計算方法如下:

r = (r\times2)+(k-2) \\

經過s=2的maxpool或avgpool層,感受野計算方法如下:

r = r \times 2 \\

經過kernelSize=1的卷積層不改變感受野

經過全連線層和Global Average Pooling層的感受野就是整個輸入影象

經過多路分支的網路,按照感受野最大支路計算

shortcut層不改變感受野

ReLU、BN、Dropout不改變感受野

全域性Stride等於所有層Stride的累乘

全域性Padding需要透過以下公式計算(透過feature map反推即可):

P=\frac{(f_{out}-1)\times stride -f_{in}+ kernelSize}{2} \\

出個計算題,計算VGG16最後一層感受野, 代入公式:

目標檢測和感受野的總結和想法

VGG16對應D系列,來計算這一列的感受野(從上往下):

R=(((((1+2+2)x2+2+2)x2+2+2+2)x2+2+2+2)x2+2+2+2)x2=308

S=2x2x2x2x2=32

P=138

實際上tensorflow和pytorch已經有人開發出了計算CNN感受野的模型,實際上VGG16感受野沒有那麼大,下圖是視覺化一個416x416大小輸入圖片的感受野,RF實際上只有212x212,也就是下邊黃色和藍色的正方形。

PS:提供一下pytorch和tensorflow計算感受野的庫:

Tensorflow:

Pytorch:

目標檢測和感受野的總結和想法

以上的計算方式是國內認可度比較高的一種計算方式,在知乎上獲得了400+的高贊,但是與谷歌計算出來的結果不一樣,所以我就去讀了一下谷歌發在Distill上的一篇論文:Computing Receptive Fields of Convolutional Neural Networks,裡邊非常豐富的講解了如何計算感受野,包含的情況非常廣。先說結論,實際上以上計算方法應該是從下往上進行的,而不是從上往下,另外以上規則只能適合比較有限範圍的卷積,而沒有一個詳細的公式。在講解下一節以後,我們嘗試重新計算VGG的感受野

2.2 自下而上的計算方法

首先也來規定一下預設的符號意義,規定L代表網路的層數

l=1,2,...,L

, 定義feature map:

f_l\in R^{h_l\times w_l\times d_l}

, 代表第

l

層的輸出,高寬深度分別為

h_l,w_l,d_l

。規定輸入的圖片為

f_0

,最後一層feature map輸出為

f_l​

目標檢測和感受野的總結和想法

l

代表第幾層;

f

代表feature map;

p

代表left padding;

q

代表right padding;

s

代表stride,

k​

代表kernel size。

在這裡,定義元素級操作的kernel size=1,比如加法,filter concatenation、relu等操作。

下圖是一個四層的網路的感受野示意圖:

目標檢測和感受野的總結和想法

經過了兩個3x3卷積和一個stride=2的maxpooling層,如果按照原來的方法從上往下進行計算,那最後一層每個點的感受野應該是:(1+2+2)x2=10, 要比上圖的6要大很多,所以就知道為啥計算的感受野偏大了(沒有處理重疊部分),而且也可以發現感受野中間集中更多資訊,兩邊資訊處理較少。

單路網路中的計算方法

單路網路就是沒有分支的網路,比如VGG。

規定

r_l​

是第

l​

層feature map相對於

r_L​

的感受野。說人話,就是最後一層

f_L​

的一個畫素值是由第

l​

層feature map的

r_l​

個值計算出來的,注意

r_L=1​

。所以整個計算過程是從後往前進行的。

目標檢測和感受野的總結和想法

上圖是一個簡單例子,

kernel size=2, padding=0, stride=3​

的情況下,下邊這層每個值只受上一層2個值的影響,所以第

l-1​

層的感受野就是2。

然後我們要考慮更加一般的情況,也就是透過

r_l

能計算出

r_{l-1}

,這樣就能透過類推,得到最終結果。具體推導過程推薦去原文看一下,非常詳細,在這裡不多贅述,否則篇幅會太大。直接給出結論:

遞推公式:

r_{l-1}=s_l\times r_l+(k_l-s_l) \\

通項公式:

r_0=\sum_{l=1}^{L}((k_l-1)\prod_{i=1}^{l-1}s_i)+1 \\

建議自己推導的時候使用遞推公式,非常方便,程式碼實現的時候考慮使用通項公式。

觀察一下通項公式,可以發現,如果每一層kernel size都是1,那麼最終的感受野就是1。如果所有的stride=1,那麼最終感受野之和就是

\sum(k_l-1)+1

。並且可以發現,影響感受野最大的引數應該是stride,如果stride>1,那將成倍的影響之後的層。

補充一下知道感受野以後的,如何計算有效stride和有效padding。

Effective Stride:

遞推公式:

S_{l-1}=s_l\times S_l \\

通項公式:

S_l=\prod_{i=l+1}^{L}s_i \\

Effective Padding:

遞推公式:

P_{l-1}=s_l\times P_l+p_l \\

通項公式:

P_l=\sum_{m=l+1}^{L}p_m\prod^{m-1}_{i=l+1}s_i \\

下面我們來重新計算VGG16整個模型的感受野:

目標檢測和感受野的總結和想法

(上圖之前有計算上的疏忽,已更正,感謝評論區kevin的指正。)

多路網路

以上講解了單路情況下的感受野計算方法,但是現在STOA的卷積網路通常都是擁有多分支的,比如說ResNet、Inception、DenseNet等網路。

多路網路不得不提到對齊問題,

感受野是不具有平移不變性

,下圖就是一個例子:

目標檢測和感受野的總結和想法

可以看到,最後一層透過兩條不同路徑後對應到第一層feature map的感受野的中心是不重合的。這是感受野的一個性質,不過好在大多數現代的網路設計是對齊的,對很多計算機視覺任務來說,都需要對其輸出特徵,包括目標檢測、語義分割、邊緣檢測、著色等。

在網路對齊時候,所有不同路徑都會導致感受野的中心是重合的,所以

不同路徑必須保持相同的stride

。這一點可以觀察Inception系列的網路,兩條路的Stride是不可能不同的。

在網路對齊的情況下,

多路網路的感受野應該是所有分支中最大感受野

,比如下邊是一個對齊的網路,中心是重合的,感受野的大小就是3。

目標檢測和感受野的總結和想法

有了以上的計算方法,我們可以很方便計算所有卷積網路的感受野:

目標檢測和感受野的總結和想法

上圖是常用分類模型對應的感受野的結果,我們可以發現,

隨著模型的不斷進化,感受野在不增大

,在比較新提出的網路中,感受野已經能夠覆蓋整個輸入影象了,這就意味著最終特徵圖中每個點都會使用到整個影象所有得上下文資訊。

目標檢測和感受野的總結和想法

目標檢測和感受野的總結和想法

上圖是感受野大小和在ImageNet上top-1準確率的關係,其中圓圈的大小代表每個網路的浮點運算數量。

分類的準確率和感受野大小大體程對數關係

,也就是說雖然感受野可以無限增長,越往後,帶來的準確率上的提升也就越小,而需要的計算代價會變得更大。

上圖MobileNet和VGG16準確率相當,但是MobileNet所需計算量卻非常小(約為VGG16的27分之1),這是由於MobileNet使用了大量depth-wise Convolution,這樣可以以較小的計算代價來增加模型感受野。這個對比可以表明

生成更大感受野的網路可以有更好的識別準確率

注意:

感受野並不是唯一影響準確率的因素

,其他因素,比如網路的深度,寬度,殘差連線,BatchNorm等也起著非常重要的作用。也就是說,感受野是我們在設計網路的時候需要考慮的一個因素,但還是要綜合其他方法。

補充:

除了最普通的卷積,還有空洞卷積、上取樣、BatchNorm、Separable Conv的感受野計算需要補充。

空洞卷積:引入空洞率

\alpha

, 經過空洞卷積,kernel size有原來的

k

變為

\alpha \times (k-1)+1

,所以只要替換原來的公式中的k即可。

上取樣:一般透過插值來實現,假如

\alpha

透過2倍上取樣得到

\beta

,上取樣的感受野相當於為了生成

\beta

的一個pixel,參與的

\alpha

的pixel的數目。(經評論區 @Kevin)英文原文也附在下邊供參考。

Upsampling.

Upsampling is frequently done using interpolation (e。g。, bilinear, bicubic or nearest-neighbor methods), resulting in an equal or larger receptive field — since it relies on one or multiple features from the input。 Upsampling layers generally produce output features which depend locally on input features, and for receptive field computation purposes can be considered to have a kernel size equal to the number of input features involved in the computation of an output feature。

可分離卷積: 等價於普通卷積,並沒有變化。

BatchNorm:推理過程中BN不改變感受野,而訓練過程中,BN的感受野是整個輸入影象。

轉置卷積: 會增加感受野,和普通計算方法類似

3. 作用

1。

目標檢測:像SSD、RPN、YOLOv3等都使用了anchor,而anchor的設計正是依據感受野,如果感受野太小

,只能觀察到區域性的特徵,不足以得到整個目標的資訊。如果

感受野過大

,則會引入過多噪聲和無效資訊。Anchor太大或太小均會影響效能。

2。

語義分割

:最終預測的畫素的感受野越大越好,涉及網路一般也是越深越好,這樣才能捕獲更多的上下文資訊,預測才會更準。

3。

分類任務

:影象分類中最後卷積層的感受野要大於輸入影象,網路深度越深,感受野越大,效能越好。

為了更合適的感受野,各種多尺度的模型架構被提出,可以分為影象金字塔和特徵金字塔,具體實現方面可以是:1。 採用多尺度輸入,如yolov3的multi scale機制。2。 多尺度特徵融合,最經典的是FPN。3。 多尺度特徵預測融合,如SSD。4。 以上方法的多種組合。

4. 關係

在論文 Single Shot Scale-invariant Face Detector 中,說明了目標檢測中

Anchor, 理論感受野,實際感受野

三者的關係。這篇論文主要針對的是中小目標,密集人臉情況下的anchor設定。

Anchor一般是透過先驗進行指定的,Anchor與目標的大小和位置越匹配(IOU>0。5or0。7),迴歸效果就會越好。如果小人臉和anchor的IOU過小,就會造成anchor很難迴歸到GT上,從而導致Recall過低。

目標檢測和感受野的總結和想法

文章中指出了Anchor、理論感受野、實際感受野三者的關係。(a)圖中,整個黑色的box是理論感受野,中間的白點是一個高斯分佈的實際感受野。(b)圖中舉了一個例子,黑色點狀的框代表是理論感受野的面積,藍色的代表實際感受野位置,而最合適的anchor就是紅色的框,所以關係為:

Anchor大小<實際感受野<理論感受野

SFD是基於SSD進行改進的,SSD中使用了6個層來進行檢測,以下是文章中設定內容:

目標檢測和感受野的總結和想法

為了探究Anchor和RF的關係,這裡使用MATLAB的工具箱來擬合兩者關係:

目標檢測和感受野的總結和想法

設anchors=x, RFs=y則有如下關係:

y=9.421\times \sqrt{12.44\times x}-46.92 \\ R^2=0.989 \\

所以y和

\sqrt{x}​

大體上是正比例關係。其實這裡只是探索一下他們之間的關係,實際感受野實際上依然是一個超引數,我們不可能明確計算出來,然後設定對應的anchor,不過我們瞭解了這個之後,最起碼

anchor的限制範圍應該是小於理論感受野

的。

作者在論文中說明了Anchor設定的理由,

Anchor=stirde\times 4

, 這樣就跟上(c)圖一樣,這樣設定可以保證不同尺度的anchor在圖片上取樣的密度是一樣的。將鋪設的anchor的scale值設為大致覆蓋到有效感受野的size。這一點並不是特別理解

SFD效果可以說是非常好了,以下是mAP對比圖:

目標檢測和感受野的總結和想法

5. 總結

首先,許多經典的網路結構中的這些卷積不是隨便決定的,在修改網路的時候不能隨便刪除。比如在yolov3中,backbone後邊的幾個卷積再接yolo層這個當時就覺得很隨意,但是他是有一定道理的。

假如出於對小目標的考慮,想要降低下采樣率,那麼直接刪掉一個maxpool層,或者刪掉stride=2的卷積層都是不可取的。透過公式我們知道,stride對一個網路的感受野影響非常大,而且會對後邊的網路層的感受野都進行影響,所以要透過使用stride=1的maxpool或者空洞卷積來彌補對感受野帶來的損失。

實際感受野依然是一個超引數,他是會隨著訓練的過程發生變化,我們無法準確計算出來實際感受野,但是透過分析anchor,實際感受野和理論感受野,我們知道了anchor<實際感受野<理論感受野,所以anchor還是會被理論感受野的大小所限制。

自己嘗試過使用kmeans演算法聚類自己資料集的Anchor,之前兩個資料,兩次聚類,都出現了自己聚類得到的Anchor不如預設的Anchor得到的結果。之前一直不知道原因在哪裡。在總結了感受野以後,我覺得可以合理推測,Anchor應該和實際感受野儘量匹配,但是實際感受野實際上是一個超引數,透過聚類得到的anchor有一定代表性,但是效果反而不如預設的anchor,這是因為我們自己聚類得到的Anchor的範圍實際上沒有預設的廣。

比如yolov3-tiny裡邊的anchor最小是【10,14】最大是【344,319】,經過計算理論感受野是382,按照SFD裡邊推導得到的公式計算,對應的anchor大小應該為159,如果按照理論感受野的三分之一來計算,大概是127。3。大概在這個範圍,自己聚類得到的最大anchor也就是20左右,所以網路如果想要適應(迴歸)20左右的anchor需要網路更長時間的訓練。

最後想推薦一下以上涉及到的三篇文章,都特別有價值,值得多看幾遍:

(1)S3FD

(2)Computing Receptive Fields of Convolutional Neural Networks

(3)Understanding the Effective Receptive Field in Deep Convolutional Neural Networks

另外,以上內容是基於論文以及自己的理解表述的,如果有問題,歡迎評論,互相交流。

6. 參考文獻

SFD論文:

YaqiLYU:

感受野計算論文:

感受野推導: “Computing Receptive Fields of Convolutional Neural Networks”, Distill, 2019。

一個用來計算感受野的網站: