1. 程式人生 > >徹底搞懂感受野的含義與計算

徹底搞懂感受野的含義與計算

目錄

  • 什麼是感受野
  • 約定
  • 感受野大小
  • 感受野中心
  • 小結
  • 參考

部落格:部落格園 | CSDN | blog

什麼是感受野

The receptive field is defined as the region in the input space that a particular CNN’s feature is looking at (i.e. be affected by).

—— A guide to receptive field arithmetic for Convolutional Neural Networks

感受野(Receptive Field),指的是神經網路中神經元“看到的”輸入區域,在卷積神經網路中,feature map上某個元素的計算受輸入影象上某個區域的影響,這個區域即該元素的感受野。

卷積神經網路中,越深層的神經元看到的輸入區域越大,如下圖所示,kernel size 均為\(3 \times 3\),stride均為1,綠色標記的是\(Layer 2\) 每個神經元看到的區域,黃色標記的是\(Layer 3\) 看到的區域,具體地,\(Layer 2\)每個神經元可看到\(Layer 1\) 上 \(3 \times 3\) 大小的區域,\(Layer3\) 每個神經元看到\(Layer 2\) 上 \(3 \times 3\) 大小的區域,該區域可以又看到\(Layer 1\) 上 \(5 \times 5\) 大小的區域。

所以,感受野是個相對概念,某層feature map上的元素看到前面不同層上的區域範圍是不同的,通常在不特殊指定的情況下,感受野指的是看到輸入影象上的區域。

為了具體計算感受野,這裡借鑑視覺系統中的概念,
\[ receptive \ field = center + surround \]

準確計算感受野,需要回答兩個子問,即視野中心在哪和視野範圍多大。

  • 只有看到”合適範圍的資訊”才可能做出正確的判斷,否則就可能“盲人摸象”或者“一覽眾山小”;
  • 目標識別問題中,我們需要知道神經元看到是哪個區域,才能合理推斷物體在哪以及判斷是什麼物體。

但是,網路架構多種多樣,每層的引數配置也不盡相同,感受野具體該怎麼計算?

約定

在正式計算之前,先對數學符號做如下約定,

  • \(k\):kernel size

  • \(p\):padding size

  • \(s\):stride size

  • \(Layer\):用\(Layer\)表示feature map,特別地 \(Layer \ 0\)為輸入影象;

  • \(Conv\):用\(Conv\)表示卷積,\(k\)、\(p\)、\(s\)為卷積層的超引數,\(Conv \ l\)的輸入和輸出分別為 \(Layer \ l-1\) 和 \(Layer \ l+1\);

  • \(n\):feature map size為 \(n \times n\),這裡假定\(height = width\);

  • \(r\):receptive field size為\(r \times r\),這裡假定感受野為方形;

  • \(j\):feature map上相鄰元素間的畫素距離,即將feature map上的元素與輸入影象\(Layer \ 0\) 上感受野的中心對齊後,相鄰元素在輸入影象上的畫素距離,也可以理解為 feature map上前進1步相當於輸入影象上前進多少個畫素,如下圖所示,feature map上前進1步,相當於輸入影象上前進2個畫素,\(j=2\);

  • \(start\):feature map左上角元素在輸入影象上的感受野中心座標\((start, start)\),即視野中心的座標,在上圖中,左上角綠色塊感受野中心座標為\((0.5, 0.5)\),即左上角藍色塊中心的座標,左上角白色虛線塊中心的座標為\((-0.5, -0.5)\);

  • \(l\):\(l\)表示層,卷積層為\(Conv \ l\),其輸入feature map為\(Layer \ l-1\),輸出為\(Layer \ l\)。

下面假定所有層均為卷積層。

感受野大小

感受野大小的計算是個遞推公式。

再看上面的動圖,如果feature map $Layer  2 $ 上的一個元素\(A\)看到feature map \(Layer \ 1\) 上的範圍為\(3 \times 3\)(圖中綠色塊),其大小等於kernel size \(k_2\),所以,\(A\)看到的感受野範圍\(r_2\)等價於\(Layer \ 1\)上\(3 \times 3\)視窗看到的\(Layer \ 0\) 範圍,據此可以建立起相鄰\(Layer\)感受野的關係,如下所示,其中\(r_{l}\)為\(Layer \ l\)的感受野,\(r_{l-1}\)為\(Layer \ l-1\) 的感受野,
\[ r_{l} = r_{l-1} + (k_{l} - 1) * j_{l-1} \]

  • \(Layer \ l\) 一個元素的感受野\(r_{l}\)等價於\(Layer \ l-1\) 上\(k \times k\) 個感受野的疊加;
  • \(Layer \ l-1\) 上一個元素的感受野為\(r_{l-1}\);
  • \(Layer \ l-1\) 上連續\(k\) 個元素的感受野可以看成是,第1個元素看到的感受野加上剩餘\(k-1\)步掃過的範圍,\(Layer \ l-1\) 上每前進1個元素相當於在輸入影象上前進\(j_{l-1}\)個畫素,結果等於\(r_{l-1} + (k - 1) \times j_{l-1}\)

視覺化如下圖所示,

下面的問題是,\(j_{in}\)怎麼求?

\(Layer \ l\) 上前進1個元素相當於\(Layer \ l-1\)上前進\(s_l\)個元素,轉換成畫素單位為
\[ j_{l} = j_{l-1} \times s_{l} \]
其中,\(s_l\)為\(Conv \ l\)的kernel在\(Layer \ l-1\) 上滑動的步長,輸入影象的\(s_0 = 1\)。

根據遞推公式可知,
\[ \begin{aligned}j_l &= \prod_{i=1}^{l} s_{i}\\\end{aligned} \]
\(Layer \ l\)上前進1個元素,相當於在輸入影象前進了\(\prod_{i=1}^{l} s_{i}\)個畫素,即前面所有層\(stride\)的連乘。

進一步可得,\(Layer \ l\)的感受野大小為
\[ \begin{aligned}r_{l} &= r_{l-1} + \left(k_{l}-1\right) * j_{l-1} \\&= r_{l-1}+\left(\left(k_{l}-1\right) * \prod_{i=1}^{l-1} s_{i}\right)\end{aligned} \]

感受野中心

感受野中心的計算也是個遞推公式。

在上一節中計算得\(j_l = \prod_{i=1}^{l} s_{i}\),表示feature map \(Layer \ l\)上前進1個元素相當於在輸入影象上前進的畫素數目,如果將feature map上元素與感受野中心對齊,則\(j_l\)為感受野中心之間的畫素距離。如下圖所示,

其中,各層的kernel size、padding、stride超引數已在圖中標出,右側圖為feature map和感受野中心對齊後的結果。

相鄰\(Layer\)間,感受野中心的關係為
\[ start_{l} = start_{l-1} + (\frac{k_l - 1}{2} - p_l) * j_{l-1} \]
所有的\(start\)座標均相對於輸入影象座標系。其中,\(start_0=(0.5,0.5)\),為輸入影象左上角畫素的中心座標,\(start_{l-1}\)表示\(Layer \ l-1\)左上角元素的感受野中心座標,\((\frac{k_l - 1}{2} - p_l)\)為\(Layer \ l\)與\(Layer \ l-1\)感受野中心相對於\(Layer \ l-1\)座標系的偏差,該偏差需折算到輸入影象座標系,其值需要乘上\(j_{l-1}\),即\(Layer \ l-1\)相鄰元素間的畫素距離,相乘的結果為\((\frac{k_l - 1}{2} - p_l) * j_{l-1}\),即感受野中心間的畫素距離——相對輸入影象座標系。至此,相鄰\(Layer\)間感受野中心座標間的關係就不難得出了,這個過程視覺化如下。

知道了\(Layer \ l\)左上角元素的感受野中心座標\((start_l, start_l)\),通過該層相鄰元素間的畫素距離\(j_l\)可以推算其他元素的感受野中心座標。

小結

將感受野的相關計算小結一下,
\[ \begin{aligned}j_{l} &= j_{l-1} \times s_{l} \\j_l &= \prod_{i=1}^{l} s_{i}\\r_{l} &= r_{l-1} + \left(k_{l}-1\right) * j_{l-1} \\&= r_{l-1}+\left(\left(k_{l}-1\right) * \prod_{i=1}^{l-1} s_{i}\right) \\start_{l} &= start_{l-1} + (\frac{k_l - 1}{2} - p_l) * j_{l-1}\end{aligned} \]
由上面的遞推公式,就可以從前向後逐層計算感受野了,程式碼可參見computeReceptiveField.py,線上視覺化計算可參見Receptive Field Calculator。

最後,還有幾點需要注意,

  • \(Layer \ l\)的感受野大小與\(s_l\)、\(p_l\)無關,即當前feature map元素的感受野大小與該層相鄰元素間的畫素距離無關;
  • 為了簡化,通常將padding size設定為kernel的半徑,即\(p = \frac{k-1}{2}\),可得\(start_l = start_{l-1}\),使得feature map \(Layer \ l\) 上\((x, y)\)位置的元素,其感受野中心座標為\((x j_l, y j_l)\);
  • 對於空洞卷積dilated convolution,相當於改變了卷積核的尺寸,若含有\(dilation\ rate\)引數,只需將\(k_l\)替換為\(dilation \ rate * (k_l - 1) + 1\) ,\(dilation\ rate=1\)時為正常卷積;
  • 對於pooling層,可將其當成特殊的卷積層,同樣存在kernel size、padding、stride引數;
  • 非線性啟用層為逐元素操作,不改變感受野。

以上。

參考

  • wiki-Receptive field
  • wiki-Receptive Field Calculator
  • arXiv-Understanding the Effective Receptive Field in Deep Convolutional Neural Networks
  • medium-A guide to receptive field arithmetic for Convolutional Neural Networks
  • medium-Topic DL03: Receptive Field in CNN and the Math behind it
  • ppt-Convolutional Feature Maps: Elements of Efficient (and Accurate) CNN-based Object Detection
  • SIGAI-關於感受野的總結
  • Calculating Receptive Field of CNN