1. 程式人生 > >深度學習:卷積神經網路物體檢測之感受野大小計算

深度學習:卷積神經網路物體檢測之感受野大小計算

1 感受野的概念

  在卷積神經網路中,感受野的定義是 卷積神經網路每一層輸出的特徵圖(feature map)上的畫素點在原始影象上對映的區域大小。

   這裡寫圖片描述

  RCNN論文中有一段描述,Alexnet網路pool5輸出的特徵圖上的畫素在輸入影象上有很大的感受野(have very large receptive fields (195 × 195 pixels))和步長(strides (32×32 pixels) ), 這兩個變數的數值是如何得出的呢?

2 感受野大小的計算

感受野計算時有下面的幾個情況需要說明:

  (1)第一層卷積層的輸出特徵影象素的感受野的大小等於濾波器的大小

  (2)深層卷積層的感受野大小和它之前所有層的濾波器大小和步長有關係

  (3)計算感受野大小時,忽略了影象邊緣的影響,即不考慮padding的大小,關於這個疑惑大家可以閱讀一下參考文章2的解答進行理解

這裡的每一個卷積層還有一個strides的概念,這個strides是之前所有層stride的乘積。

  即: strides(i) = stride(1) * stride(2) * …* stride(i-1)

  關於感受野大小的計算採用 top to down 的方式, 即先計算最深層在前一層上的感受野,然後逐漸傳遞到第一層,使用的公式可以表示如下:   

   RF = 1 #待計算的feature map上的感受野大小


  for layer in (top layer To down layer):
    RF = ((RF -1)* stride) + fsize

stride 表示卷積的步長; fsize表示卷積層濾波器的大小  

用python實現了計算Alexnet zf-5和VGG16網路每層輸出feature map的感受野大小,實現程式碼:

#!/usr/bin/env python

net_struct = {'alexnet': {'net':[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0]],
                   'name'
:['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5']}, 'vgg16': {'net':[[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1], [2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0]], 'name':['conv1_1','conv1_2','pool1','conv2_1','conv2_2','pool2','conv3_1','conv3_2', 'conv3_3', 'pool3','conv4_1','conv4_2','conv4_3','pool4','conv5_1','conv5_2','conv5_3','pool5']}, 'zf-5':{'net': [[7,2,3],[3,2,1],[5,2,2],[3,2,1],[3,1,1],[3,1,1],[3,1,1]], 'name': ['conv1','pool1','conv2','pool2','conv3','conv4','conv5']}} imsize = 224 def outFromIn(isz, net, layernum): totstride = 1 insize = isz for layer in range(layernum): fsize, stride, pad = net[layer] outsize = (insize - fsize + 2*pad) / stride + 1 insize = outsize totstride = totstride * stride return outsize, totstride def inFromOut(net, layernum): RF = 1 for layer in reversed(range(layernum)): fsize, stride, pad = net[layer] RF = ((RF -1)* stride) + fsize return RF if __name__ == '__main__': print "layer output sizes given image = %dx%d" % (imsize, imsize) for net in net_struct.keys(): print '************net structrue name is %s**************'% net for i in range(len(net_struct[net]['net'])): p = outFromIn(imsize,net_struct[net]['net'], i+1) rf = inFromOut(net_struct[net]['net'], i+1) print "Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (net_struct[net]['name'][i], p[0], p[1], rf) receptiveField.py

執行後的結果如下:
這裡寫圖片描述

4 Convolutional Feature Maps: Elements of Efficient (and Accurate) CNN-based Object Detection

5 Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition