卷积神经网络传播过程中感受野的理解以及feature map size 、receptive field size的计算(代码)

候补:以下介绍的是理论感受野;其实有效感受野因训练方式有关(一般比理论感受野小)

今天看论文时偶然提到了感受野这个名词,这个词在初学卷积神经网络时就已经解除了,但是还没有对其有深入的了解 ,因此在网上百度了一些有关感受野的相关的资料,并自己亲自跑了下计算网络传播过程中感受野大小和feature map大小的代码,感觉理解的更加深入了,下面记录下过程:

这里感谢http://blog.csdn.net/gzq0723/article/details/53138430   博主共享出来的代码!并且本文部分引用了其博文。

以下分三个方面进行整理:

一、感受野的解释

最近在组会讲解框架时,在感受野这个小知识点,大家开始产生歧义,今天我就简单的给大家讲解下这个小知识点,也给初学者带来一个对Receptive Field崭新的认识,如果对只是有深入了解的你,就可以直接跳过O(∩_∩)O~~! 
现在开始进入正题!!!

以前我的理解就是,感受野嘛,其实那就是一个视觉感受区域大小。对于单层网络来说,下一层的一个像素点其感受野大小也就是卷积层滤波器的大小,想想其实很明了的就理解了,但对于多层,那就有一点点(也就那么一点点复杂而已)!

正式定义:

在神经网络中,感受野的定义是: 
卷积神经网络的每一层输出的特征图(Feature ap)上的像素点在原图像上映射的区域大小。 
这里写图片描述

自己随便画了一个例图,主要看内容,O(∩_∩)O谢谢! 
链接: 百度网盘-链接不存在 密码: 2ehd 
有读者说有动图就好了,我就截取了一个,请大家欣赏!

这里写图片描述

现在就开始来说怎么计算吧!(看点来了)其实很简单! 
首先可以简单知道(前面也提及到了),第一层卷积层的输出特征图像素的感受野的大小就等于等于卷积层滤波器的大小;然后其继续进行前向传播,这样的话,后面深层的卷积层感受野大小就和之前所有网络层的滤波器大小和步长有关系了,在计算的时候,忽略图像Padding的大小。网络中的每一个层有一个strides,该strides是之前所有层stride的乘积,即: 
这里写图片描述

查资料知,感受野大小的计算采用从深层到前层的方式计算, 即先计算最深层在前一层上的感受野,然后逐渐反馈到第一层,公式具体记如下: 
这里写图片描述 
其中V^{‘} {receptive field} 为得的感受野大小, V{receptive field} 为最后层在前一层的感受野大小,Size_{Conv} 为卷积层滤波器大小。

二、相关代码

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

三、结果截图(在Linux 下Python 2.7.6下运行)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值