【深度学习】卷积神经网络中感受野(Receptive Field)的计算方法

【深度学习】卷积神经网络中感受野(Receptive Field)的计算方法

  • 转载来源
  • 卷积神经网络中感受野(Receptive Field)的计算方法
  • 感受野计算器:
  • python实现的感受野计算器
  • 结语

转载来源

  1. https://zhuanlan.zhihu.com/p/28492837
  2. https://www.cnblogs.com/objectDetect/p/5947169.html

感谢原作者的工作

卷积神经网络中感受野(Receptive Field)的计算方法

在机器视觉领域的深度神经网络中有一个概念叫做感受野,用来表示网络内部的不同位置的神经元对原图像的感受范围的大小。神经元之所以无法对原始图像的所有信息进行感知,是因为在这些网络结构中普遍使用卷积层和pooling层,在层与层之间均为局部相连(通过sliding filter)。

神经元感受野的值越大表示其能接触到的原始图像范围就越大,也意味着他可能蕴含更为全局、语义层次更高的特征

而值越小则表示其所包含的特征越趋向于局部和细节

因此感受野的值可以大致用来判断每一层的抽象层次。


感受野大小的计算采用,Top To Down的方式即先计算最深层在前一层上的感受野,然后逐渐传递到第一层,使用的公式可以表示如下:

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

for layer in (top layer to down layer):
	RF = ((RF - 1) * stride) + kernel size
	# stride 为每一层kernel stride的累乘
	# kernel size为当前层的kernel size

感受野计算器:

https://fomoro.com/research/article/receptive-field-calculator

python实现的感受野计算器

# -*- coding:utf-8 -*-

net_struct = {
     '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],[5,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']}
       }

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))

输出如下:

layer output sizes given image = 224x224
************net structrue name is vgg16**************
Layer Name = conv1_1, Output size = 224, Stride = 1, RF size = 3
Layer Name = conv1_2, Output size = 224, Stride = 1, RF size = 5
Layer Name = pool1, Output size = 112, Stride = 2, RF size = 6
Layer Name = conv2_1, Output size = 112, Stride = 2, RF size = 10
Layer Name = conv2_2, Output size = 112, Stride = 2, RF size = 14
Layer Name = pool2, Output size = 56, Stride = 4, RF size = 16
Layer Name = conv3_1, Output size = 56, Stride = 4, RF size = 24
Layer Name = conv3_2, Output size = 56, Stride = 4, RF size = 32
Layer Name = conv3_3, Output size = 56, Stride = 4, RF size = 40
Layer Name = pool3, Output size = 28, Stride = 8, RF size = 44
Layer Name = conv4_1, Output size = 28, Stride = 8, RF size = 60
Layer Name = conv4_2, Output size = 28, Stride = 8, RF size = 76
Layer Name = conv4_3, Output size = 26, Stride = 8, RF size = 108
Layer Name = pool4, Output size = 13, Stride = 16, RF size = 116
Layer Name = conv5_1, Output size = 13, Stride = 16, RF size = 148
Layer Name = conv5_2, Output size = 13, Stride = 16, RF size = 180
Layer Name = conv5_3, Output size = 13, Stride = 16, RF size = 212
Layer Name = pool5, Output size = 6, Stride = 32, RF size = 228

结语

如果您有修改意见或问题,欢迎留言或者通过邮箱和我联系。
手打很辛苦,如果我的文章对您有帮助,转载请注明出处。

你可能感兴趣的:(深度学习)