文章目录

  • 一、理论感受野
    • 1、定义
    • 2、计算公式
    • 3、实用小工具
    • 4、作用
  • 二、有效感受野及其与 anchor 的关系
    • 1、有效感受野
    • 2、感受野和 anchor 的关系
  • 三、代码实现
  • 四、参考资料

一、理论感受野

1、定义

  • 卷积神经网络输出特征图上的像素点 在原始图像上所能看到区域的大小,输出特征会受感受野区域内的像素点的影响
  • 图像的空间联系是局部的,就像人是通过一个 局部的感受野 去感受外界图像一样,每一个神经元都不需要对全局图像做感受,每个神经元只感受局部的图像区域,然后在更高层,将这些感受不同局部的神经元 综合起来就可以得到全局的信息了

2、计算公式

  • 普通(空洞)卷积感受野的计算:

    • RFl+1=RFl+(kernel−sizel+1−1)×feature−stridel×dilationl+1R F_{l+1}=R F_{l}+\left(kernel_{-}size_{l+1}-1\right) \times {feature_{-}stride}_{l} \times dilation_{l+1}RFl+1​=RFl​+(kernel−​sizel+1​−1)×feature−​stridel​×dilationl+1​
    • RFRFRF 表示特征感受野的大小,lll 表示层数, feature−stridel=∏i=1lstridei{feature_{-}stride}_{l}=\prod_{i=1}^{l} {stride}_{i}feature−​stridel​=∏i=1l​stridei​
    • l=0l=0l=0 表示输入层,输入图像的每个单元的感受野为 RF0=1RF_{0} = 1RF0​=1,feature−stride0=1{feature_{-}stride}_{0}=1feature−​stride0​=1,因为每个像素只能看到自己
    • 普通卷积所有层的 dilation 为 1,空洞卷积某些层的 dilation 大于 1
    • Note:
      • 第一层卷积输出特征图像素的感受野大小等于滤波器的大小(dilation=1 时)
      • 计算感受野大小时,忽略了图像边缘的影响,即不考虑 padding 的大小
  • 一些结论:
    • 经过 Conv 1*1 不会改变感受野,ReLU/BN/dropout 等元素级操作不会改变感受野
    • 当经过 多路分支 时,按照 最大感受野分支 计算, short-cut 操作不会改变感受野
    • stride 为 1 的卷积层 线性增加 感受野,深度网络可以通过堆叠多层卷积增加感受野;stride 为2 的下采样层 乘性增加 感受野,但受限于输入分辨率不能随意增加;stride 为 1 的卷积层加在网络 后面位置,会比加在前面位置 获得更大感受野

3、实用小工具

  • 感受野计算的是否正确可使用 此链接:Receptive Field Calculator 提供的工具进行验证
  • tf 官方感受野计算代码:https://github.com/tensorflow/tensorflow/tree/v2.0.0-rc2/tensorflow/contrib/receptive_field

4、作用

  • 感受野的值可以用来大致判断每一层的抽象层次:

    • 感受野越大表示其能接触到的原始图像范围就越大,也意味着可能蕴含更为 全局、语义层次更高的特征
    • 感受野越小则表示其所包含的特征越趋向于 局部和细节
  • 辅助网络的设计:
    • 一般任务:要求感受野越大越好,如图像分类中最后卷积层的感受野要大于输入图像,网络深度越深感受野越大性能越好
    • 目标检测:设置 anchor 要严格对应感受野,anchor 太大或偏离感受野都会严重影响检测性能
    • 语义分割:要求输出像素的感受野足够的大,确保做出决策时没有忽略重要信息,一般也是越深越好
  • 多个小卷积代替一个大卷积层,在 加深网络深度(增强了网络容量和复杂度)的同时减少参数的个数
    • 小卷积核(如 3×33 \times 33×3)通过多层叠加可取得与大卷积核(如 7×77 \times 77×7)同等规模的感受野

    • 多层小卷积核和大卷积核具有同等感受野及减少参数的直观理解


二、有效感受野及其与 anchor 的关系

1、有效感受野

  • 实际上,上述的计算是理论感受野,而特征的有效感受野是 远小于 理论感受野的
  • 且越靠近感受野 中心 的值被使用次数 越多,靠近边缘的值使用次数越少

2、感受野和 anchor 的关系

  • 经典目标检测和最新目标跟踪中,都用到了 RPN(region proposal network)anchorRPN 的基础,感受野anchor 的基础
  • 目标检测中,anchor 大小及比例的设置应该跟该层特征的 有效感受野相匹配,anchor 比有效感受野大太多不好,小太多也不好
  • Equal-proportion interval principle: 感受野的大小设置为步长的 n(4) 倍

三、代码实现

# -*- coding: utf-8 -*-
"""
@File      : compute_receptive_field.py
@Version   : 1.0
"""import numpy as np# 需指定每层的 kernel_size, stride, pad, dilation, channel_num
net_struct = {'vgg16': {'net': [[3, 1, 1, 1, 64], [3, 1, 1, 1, 64], [2, 2, 0, 1, 64], [3, 1, 1, 1, 128], [3, 1, 1, 1, 128],[2, 2, 0, 1, 128],[3, 1, 1, 1, 256], [3, 1, 1, 1, 256], [3, 1, 1, 1, 256], [2, 2, 0, 1, 256], [3, 1, 1, 1, 512],[3, 1, 1, 1, 512],[3, 1, 1, 1, 512], [2, 2, 0, 1, 512], [3, 1, 1, 1, 512], [3, 1, 1, 1, 512], [3, 1, 1, 1, 512],[2, 2, 0, 1, 512]],'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']},'vgg16_ssd': {'net': [[3, 1, 1, 1, 64], [3, 1, 1, 1, 64], [2, 2, 0, 1, 64], [3, 1, 1, 1, 128], [3, 1, 1, 1, 128],[2, 2, 0, 1, 128], [3, 1, 1, 1, 256], [3, 1, 1, 1, 256], [3, 1, 1, 1, 256], [2, 2, 0, 1, 256],[3, 1, 1, 1, 512], [3, 1, 1, 1, 512], [3, 1, 1, 1, 512], [2, 2, 0, 1, 512], [3, 1, 1, 1, 512],[3, 1, 1, 1, 512], [3, 1, 1, 1, 512], [3, 1, 1, 1, 512], [3, 1, 6, 6, 1024], [1, 1, 0, 1, 1024],[1, 1, 0, 1, 256], [3, 2, 1, 1, 512], [1, 1, 0, 1, 128], [3, 2, 1, 1, 256], [1, 1, 0, 1, 128],[3, 1, 0, 1, 256], [1, 1, 0, 1, 128], [3, 1, 0, 1, 256]],'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','fc6', 'fc7', 'conv6_1', 'conv6_2', 'conv7_1', 'conv7_2', 'conv8_1', 'conv8_2', 'conv9_1','conv9_2']}
}# 输出特征图大小的计算(down-top calculation)
def out_from_in(img_size_f, net_p, net_n, layer_len):total_stride = 1in_size = img_size_ffor layer in range(layer_len):k_size, stride, pad, dilation, _ = net_p[layer]net_name = net_n[layer]if 'pool' in net_name:out_size = np.ceil(1.0 * (in_size + 2 * pad - dilation * (k_size - 1) - 1) / stride).astype(np.int32) + 1else:out_size = np.floor(1.0 * (in_size + 2 * pad - dilation * (k_size - 1) - 1) / stride).astype(np.int32) + 1in_size = out_sizetotal_stride = total_stride * stridereturn out_size, total_stride# 输出特征图上每个像素感受野的计算(top-down calculation)
def in_from_out(net_p, layer_len):RF = 1for layer in reversed(range(layer_len)):k_size, stride, pad, dilation, _ = net_p[layer]RF = ((RF - 1) * stride) + dilation * (k_size - 1) + 1return RFif __name__ == '__main__':img_size = 300print("layer output sizes given image = %dx%d" % (img_size, img_size))for net in net_struct.keys():print('************net structrue name is %s**************' % net)for i in range(len(net_struct[net]['net'])):p = out_from_in(img_size, net_struct[net]['net'], net_struct[net]['name'], i + 1)rf = in_from_out(net_struct[net]['net'], i + 1)print("layer_name = {:<8}  output_size = {:<4}  total_stride = {:<3}  output_channel = {:<4}  rf_size = {:<4}".format(net_struct[net]['name'][i], p[0], p[1], net_struct[net]['net'][i][4], rf))# vgg16 输出结果如下
layer output sizes given image = 300x300
************net structrue name is vgg16**************
layer_name = conv1_1   output_size = 300   total_stride = 1    output_channel = 64    rf_size = 3
layer_name = conv1_2   output_size = 300   total_stride = 1    output_channel = 64    rf_size = 5
layer_name = pool1     output_size = 150   total_stride = 2    output_channel = 64    rf_size = 6
layer_name = conv2_1   output_size = 150   total_stride = 2    output_channel = 128   rf_size = 10
layer_name = conv2_2   output_size = 150   total_stride = 2    output_channel = 128   rf_size = 14
layer_name = pool2     output_size = 75    total_stride = 4    output_channel = 128   rf_size = 16
layer_name = conv3_1   output_size = 75    total_stride = 4    output_channel = 256   rf_size = 24
layer_name = conv3_2   output_size = 75    total_stride = 4    output_channel = 256   rf_size = 32
layer_name = conv3_3   output_size = 75    total_stride = 4    output_channel = 256   rf_size = 40
layer_name = pool3     output_size = 38    total_stride = 8    output_channel = 256   rf_size = 44
layer_name = conv4_1   output_size = 38    total_stride = 8    output_channel = 512   rf_size = 60
layer_name = conv4_2   output_size = 38    total_stride = 8    output_channel = 512   rf_size = 76
layer_name = conv4_3   output_size = 38    total_stride = 8    output_channel = 512   rf_size = 92
layer_name = pool4     output_size = 19    total_stride = 16   output_channel = 512   rf_size = 100
layer_name = conv5_1   output_size = 19    total_stride = 16   output_channel = 512   rf_size = 132
layer_name = conv5_2   output_size = 19    total_stride = 16   output_channel = 512   rf_size = 164
layer_name = conv5_3   output_size = 19    total_stride = 16   output_channel = 512   rf_size = 196
layer_name = pool5     output_size = 10    total_stride = 32   output_channel = 512   rf_size = 212 # vgg16_ssd 输出结果如下
************net structrue name is vgg16_ssd**************
layer_name = conv1_1   output_size = 300   total_stride = 1    output_channel = 64    rf_size = 3
layer_name = conv1_2   output_size = 300   total_stride = 1    output_channel = 64    rf_size = 5
layer_name = pool1     output_size = 150   total_stride = 2    output_channel = 64    rf_size = 6
layer_name = conv2_1   output_size = 150   total_stride = 2    output_channel = 128   rf_size = 10
layer_name = conv2_2   output_size = 150   total_stride = 2    output_channel = 128   rf_size = 14
layer_name = pool2     output_size = 75    total_stride = 4    output_channel = 128   rf_size = 16
layer_name = conv3_1   output_size = 75    total_stride = 4    output_channel = 256   rf_size = 24
layer_name = conv3_2   output_size = 75    total_stride = 4    output_channel = 256   rf_size = 32
layer_name = conv3_3   output_size = 75    total_stride = 4    output_channel = 256   rf_size = 40
layer_name = pool3     output_size = 38    total_stride = 8    output_channel = 256   rf_size = 44
layer_name = conv4_1   output_size = 38    total_stride = 8    output_channel = 512   rf_size = 60
layer_name = conv4_2   output_size = 38    total_stride = 8    output_channel = 512   rf_size = 76
layer_name = conv4_3   output_size = 38    total_stride = 8    output_channel = 512   rf_size = 92
layer_name = pool4     output_size = 19    total_stride = 16   output_channel = 512   rf_size = 100
layer_name = conv5_1   output_size = 19    total_stride = 16   output_channel = 512   rf_size = 132
layer_name = conv5_2   output_size = 19    total_stride = 16   output_channel = 512   rf_size = 164
layer_name = conv5_3   output_size = 19    total_stride = 16   output_channel = 512   rf_size = 196
layer_name = pool5     output_size = 19    total_stride = 16   output_channel = 512   rf_size = 228
layer_name = fc6       output_size = 19    total_stride = 16   output_channel = 1024  rf_size = 420
layer_name = fc7       output_size = 19    total_stride = 16   output_channel = 1024  rf_size = 420
layer_name = conv6_1   output_size = 19    total_stride = 16   output_channel = 256   rf_size = 420
layer_name = conv6_2   output_size = 10    total_stride = 32   output_channel = 512   rf_size = 452
layer_name = conv7_1   output_size = 10    total_stride = 32   output_channel = 128   rf_size = 452
layer_name = conv7_2   output_size = 5     total_stride = 64   output_channel = 256   rf_size = 516
layer_name = conv8_1   output_size = 5     total_stride = 64   output_channel = 128   rf_size = 516
layer_name = conv8_2   output_size = 3     total_stride = 64   output_channel = 256   rf_size = 644
layer_name = conv9_1   output_size = 3     total_stride = 64   output_channel = 128   rf_size = 644
layer_name = conv9_2   output_size = 1     total_stride = 64   output_channel = 256   rf_size = 772

四、参考资料

1、关于感受野的总结
2、卷积神经网络的感受野
3、特征图尺寸和感受野计算详解
4、A guide to receptive field arithmetic for Convolutional Neural Networks
5、Convolutional Pose Machines
6、S3FD: Single Shot Scale-invariant Face Detector

感受野( Receptive Field)相关推荐

  1. 感受野-Receptive Field的理解

    之前在阅读yolov1的论文时,发现yolov1用到了Resnet,于是找到了Resnet论文,在研究Resnet的时候,发现自己对卷积的相关操作理解还不够深刻,于是研究卷积,发现其中一个比较重要的概 ...

  2. 深度学习之学习(1-2)感受野(receptive field)

    参见:原始图片中的ROI如何映射到到feature map? - 知乎 1 感受野的概念 在卷积神经网络中,感受野的定义是 卷积神经网络每一层输出的特征图(feature map)上的像素点在原始图像 ...

  3. 如何计算感受野(Receptive Field)

    一.感受野的概念 感受野指的是一个特定的 CNN 特征(特征图上的某个点)在输入空间所受影响的区域. 感受野计算时有下面的几个情况需要说明: a)第一层卷积层的输出特征图像素的感受野的大小等于滤波器的 ...

  4. 感受野(receptive field)

    学习RCNN系列论文时, 出现了感受野(receptive field)的名词, 感受野的尺寸大小是如何计算的,在网上没有搜到特别详细的介绍, 为了加深印象,记录下自己对这一感念的理解,希望对理解基于 ...

  5. 深度CNN感受野(Receptive Field)的计算

    参考 如何计算感受野(Receptive Field)--原理 FOMORO AI -> 可视化计算感受野的网站,可以用来验证自己计算的结果 Python代码 这里使用的是从后向前的计算方法,简 ...

  6. 什么是感受野 Receptive Field 感受野是什么意思

    有一个人写的很好,放上他写的文章 彻底搞懂感受野的含义与计算 - 知乎 然后嘞,如果你点进去不想看,那你就适合看我写的哈哈 比较浮躁,那就我来吧 首先我们得知道感受野的英文名字哈 洋气 感受野 Rec ...

  7. 深度学习笔记~感受野(receptive field)的计算

    以前对CNN中的感受野(receptive field)已经有了一些认识,基本上是从概念理解上得到的. 本篇文章给出了receptive field的计算过程和相应的python代码,对recepti ...

  8. 池化层(pooling layer) 感受野(Receptive Field) 神经网络的基本组成

    目录 (1)本文涉及的函数 (2)池化层 (3)感受野 (4)代码示例(含注释) 承接上两篇博客:卷积层(空洞卷积对比普通卷积).激活函数层 (1)本文涉及的函数 import torch impor ...

  9. 如何计算感受野(Receptive Field)——原理

    本文转载自知乎专栏:https://zhuanlan.zhihu.com/p/31004121 写这篇文章的初衷是自己需要计算感受野,但是在今天之前只对感受野有感性认识,并不知道如何定量计算.所以在网 ...

  10. 感受野receptive field个人理解

    先引用一种思路: 至于为什么在下式不成立: 在于我们从长度着手的处理方法,应该从下一层最多从上一层吸收的长度着手(这也是和先前的假设pad操作不能扩展信息量相对应的),用一张图解释一下: 举个例子:在 ...

最新文章

  1. 撒花!机器学习圣经 PRML 出 Python 复现代码了!
  2. 【正一专栏】贾乃亮发文后李小璐会如何回应?
  3. 4. Median of Two Sorted Arrays
  4. 62 | 测一测 | 这些软件测试题目,你都掌握了吗?
  5. NodeJS中的require和import
  6. oracle的al32utf8,oracle字符集修改(AL32UTF8-UTF8)
  7. 100+诡异的数据集,20万Eclipse Bug、死囚遗言等
  8. Linux修改本地时间
  9. 常用算法2 - 广度优先搜索 深度优先搜索 (python实现)
  10. 12月上旬全球域名总量新增1.8万 环比减少84%
  11. 动态包含与静态包含的区别
  12. PPT学习整理(八)PPT图片技巧
  13. 客户个性分析 聚类 大数据
  14. Java中继承thread类与实现Runnable接口的区别(转)
  15. 今天在XP下装SQL2000个人版MB用了两个钟
  16. 【职场心灵鸡汤】以多年来拿最佳的心路历程来复盘【如何成为优秀的5%】
  17. PyCharm运行问题:AssertionError: Torch not compiled with CUDA enabled
  18. 跨境电商人要知道的知识产权侵权防范小知识
  19. c语言程序设计if函数题目,if函数套用练习题.doc
  20. SSL协议原理(Secure Socket Layer)【转载】

热门文章

  1. 一个PPT达人的箴言:渐变并且有质地的底纹,就是“底纹填充+半透明渐变图层”
  2. 用最直白的方式告诉你 什么是前后端分离
  3. 161018、springMVC中普通类获取注解service方法
  4. 初次见面,还请多多关照
  5. Steam流的常用操作
  6. python的input函数_python利用input函数输入多个参数的方法
  7. vue 2.0 中 函数`return false` 使用
  8. matlab 局域态密度电子密度的可视化程序
  9. Zuul网关之限流实现
  10. 「CSS 3D 专题」搞懂 CSS 3D,你必须理解 perspective(视域)这个属性