【问题标题】:How to calculate receptive field size? [closed]如何计算感受野大小? [关闭]
【发布时间】:2016-06-05 14:01:05
【问题描述】:

我正在阅读有关使用 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 计算感受野的边界矩形?

【问题讨论】:

标签: deep-learning computer-vision receptive-field


【解决方案1】:

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

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

3) 您不需要使用库来执行此操作。对于每 2x2 池化,输出大小沿每个维度减少一半。对于跨步卷积,您还可以将每个维度的大小除以步幅。根据您是否对卷积使用填充,您可能需要削减一些尺寸。最简单的情况是使用 padding = floor(kernel size/2),这样卷积不会对输出大小产生任何额外的变化。

【讨论】:

    【解决方案2】:

    这是计算除步幅和输出大小之外的 RF 大小的 Python 脚本。

        # [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
    
        RFsize = isz - (outsize - 1) * totstride
    
        return outsize, totstride, 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)
            print "Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (layer_name[i], p[0], p[1], p[2])
    

    【讨论】:

    • 我认为是错误的。
    • 哪一部分?请具体点。如果有任何错误报告,我将不胜感激
    【解决方案3】:

    如上所述,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】:

      这是另一种直接计算感受野的方法。 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)。直观地说,$k$ 层中的 RF 覆盖了 $(f_k - 1) * s_{k-1}$ 个像素 相对于层 $k-1$。但是,增量需要转换为 第一层,所以增量是阶乘 --- $k-1$ 层的步幅是 低层的步幅呈指数级增长。

      希望这有帮助。

      【讨论】:

      • 链接失效
      • 感谢您的指出。它现在应该可以工作了。
      【解决方案5】:

      2019 年 12 月 11 日更新:

      TF 库已移至https://github.com/google-research/receptive_field

      另请参阅 Distill 论文“计算卷积神经网络的接收域”:https://distill.pub/2019/computing-receptive-fields/

      旧:

      Tensorflow 现在支持接受域计算,只需使用 tf.contrib.receptive_field

      详情请见https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/receptive_field

      【讨论】:

      【解决方案6】:

      假设我们有一个由多个卷积层组成的网络架构。对于每个卷积层,我们定义了一个方形内核大小和一个膨胀率。另外,假设步长为 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] 张凯,等。 “超越高斯去噪器:深度 cnn 的残差学习用于图像去噪。” IEEE 图像处理汇刊 26.7 (2017): 3142-3155。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-25
        • 1970-01-01
        • 1970-01-01
        • 2020-03-26
        • 2020-03-27
        • 2019-01-13
        • 1970-01-01
        相关资源
        最近更新 更多