如何计算感受野大小?

时间:2016-02-23 16:11:45

标签: computer-vision deep-learning

我正在阅读有关使用CNN(卷积神经网络)进行物体检测的论文。

Rich feature hierarchies for accurate object detection and semantic segmentation

以下是关于接受性字段的引用:

The pool5 feature map is 6x6x256 = 9216 dimensional. Ignoring boundary effects, each pool5 unit has a receptive field of 195x195 pixels in the original 227x227 pixel input. A central pool5 unit has a nearly global view,
while one near the edge has a smaller, clipped support.

我的问题是:

  1. 接受领域的定义是什么?
  2. 他们如何计算感受野的大小和位置?
  3. 我们如何使用caffe / pycaffe计算感受野的边界矩形?

6 个答案:

答案 0 :(得分:6)

1)影响最后一个卷积输出的像素区域的大小。

2)对于每个卷积和池化操作,计算输出的大小。现在找到导致输出大小为1x1的输入大小。这就是感受野的大小

3)您不需要使用库来执行此操作。对于每个2x2池,每个维度的输出大小减少一半。对于跨步卷积,您还可以按步幅划分每个维度的大小。您可能需要削减一些尺寸,具体取决于您是否使用填充进行卷积。最简单的情况是使用padding = floor(内核大小/ 2),因此卷积不会对输出大小产生任何额外的变化。

答案 1 :(得分:5)

这是另一种直接计算感受野的方法。 Stackoverflow不支持数学公式,对于更易读的版本,请参阅Calculating Receptive Field of CNN

$ k $层的感受野(RF)$ l_k $是:

$$ l_k = l_ {k-1} +((f_k - 1)* \ prod_ {i = 1} ^ {k-1} s_i)$$

其中$ l_ {k-1} $是图层$ k-1 $的接收字段,$ f_k $是过滤器大小 (高度或宽度,但假设它们在这里相同),$ s_i $是步幅 层$ i $。

上面的公式从下到上(从图层)计算感受野 1)。直观地说,RF in layer $ k $覆盖$(f_k - 1)* s_ {k-1} $ more像素 相对于图层$ k-1 $。但是,增量需要转换为 第一层,所以增量是一个阶乘---层$ k-1 $中的步幅是 在较低层中指数级更多。

希望这有用。

答案 2 :(得分:5)

Tensorflow现在只需使用tf.contrib.receptive_field

即可支持感知字段计算

有关详细信息,请参阅https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/receptive_field

答案 3 :(得分:4)

如上所述,可能正确计算RF:

#Compute input size that leads to a 1x1 output size, among other things   

# [filter size, stride, padding]

convnet =[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0],[6,1,0]]
layer_name = ['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5','fc6-conv']
imsize = 227

def outFromIn(isz, layernum = 9, net = convnet):
    if layernum>len(net): layernum=len(net)

    totstride = 1
    insize = isz
    #for layerparams in net:
    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( layernum = 9, net = convnet):
    if layernum>len(net): layernum=len(net)
    outsize = 1
    #for layerparams in net:
    for layer in reversed(range(layernum)):
        fsize, stride, pad = net[layer]
        outsize = ((outsize -1)* stride) + fsize
    RFsize = outsize
    return RFsize

if __name__ == '__main__':

    print "layer output sizes given image = %dx%d" % (imsize, imsize)
    for i in range(len(convnet)):
        p = outFromIn(imsize,i+1)
        rf = inFromOut(i+1)
        print "Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (layer_name[i], p[0], p[1], rf)

答案 4 :(得分:2)

这里是除了步幅和输出大小之外还计算RF大小的python脚本。

gst-launch-1.0 playbin video-sink="videoconvert ! videoscale ! aasink" uri=file://<path/to/some/file>

答案 5 :(得分:0)

假设我们有一个的网络架构,其中包含多个卷积层。对于每个卷积层,我们定义一个平方核大小和一个膨胀率。另外,假设步幅为1。因此,您可以通过以下python代码计算网络的接收场:

K=[3,3]   # Kernel Size
R=[1,2]  # Dilation Rate

RF=1
d=1 # Depth
for k,r in zip(K,R):
    support=k+(k-1)*(r-1) # r-dilated conv. adds r-1 zeros among coefficients
    RF=support+(RF-1)
    print('depth=%d, K=%d, R=%d, kernel support=%d'%(d,k,r,support))
    d=d+1
print('Receptive Field: %d'%RF)

作为一个例子,让我们计算众所周知的DnCNN(去噪卷积神经网络)[1]的感受野(RF)。 将上面的代码与以下输入配合使用,以计算该网络的RF。 (您将获得RF = 35)。

# In DnCNN-S, the network has 17 convolution layers.
K=[3]*17  # Kernel Size
R=[1]*17  # Dilation Rate

[1] Zhang Kai Kai等。 “除了高斯降噪器之外,还可以对深度cnn进行残差学习以进行图像降噪。” IEEE Transactions on Image Processing 26.7(2017):3142-3155。