目标检测中的感受野

article/2025/9/14 16:00:07

一、定义

  • 卷积神经网络输出特征图上的像素点 在原始图像上所能看到区域的大小,输出特征会受感受野区域内的像素点的影响

在卷积神经网络中,感受野(Receptive Field)是指特征图上的某个点能看到的输入图像的区域,即特征图上的点是由输入图像中感受野大小区域的计算得到的

  • 图像的空间联系是局部的,就像人是通过一个 局部的感受野 去感受外界图像一样,每一个神经元都不需要对全局图像做感受,每个神经元只感受局部的图像区域,然后在更高层,将这些感受不同局部的神经元 综合起来就可以得到全局的信息了

图来自[1]

神经元感受野的值越大表示其能接触到的原始图像范围就越大,也意味着它可能蕴含更为全局,语义层次更高的特征;相反,值越小则表示其所包含的特征越趋向局部和细节。因此感受野的值可以用来大致判断每一层的抽象层次.[1]

二、计算

卷积层(conv)和池化层(pooling)都会影响感受野,而激活函数层通常对于感受野没有影响,当前层的步长并不影响当前层的感受野,感受野和填补(padding)没有关系, 计算当层感受野的公式如下:

 其中,表示当前层的感受野, 表示上一层的感受野, 表示卷积核的大小,例如3*3的卷积核,则 表示之前所有层的步长的乘积(不包括本层),公式如下:

  下面来练练手,以AlexNet举个例子

AlexNet(图来自[1])

我的一部分计算过程:

 

感受野计算的是否正确可使用 此链接:Receptive Field Calculator 提供的工具进行验证

在这里插入图片描述

tf 官方感受野计算代码
 

三、作用


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

这里写图片描述

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

这里写图片描述

 

四、拓展:有效感受野

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

通常上述公式求取的感受野通常很大,而实际的有效感受野(Effective Receptive Field)往往小于理论感受野,因为输入层中边缘点的使用次数明显比中间点要少,因此作出的贡献不同,所以经过多层的卷积堆叠后,输入层对于特征图点做出的贡献分布呈高斯分布形状

在使用Anchor作为强先验区域的物体检测算法中,如Faster RCNN和SSD,如何设置Anchor的大小,都应该考虑感受野,尤其是有效感受野,过大或过小都不好,来自[2]

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 

reference

目标检测和感受野的总结和想法 - 知乎 (zhihu.com)

1、关于感受野的理解与计算:https://www.jianshu.com/p/9997c6f5c01e

2、书籍《深度学习之PyTorch物体检测实战》


http://chatgpt.dhexx.cn/article/eAhDCVdk.shtml

相关文章

感受野的理解与调研

问题来源 讲论文的时候&#xff0c;突然被别人问到感受野是个什么东东? 就百度查了一下&#xff1a; 重要知识链接总结 画深度学习的模型图方法&#xff1a;知网链接 神经网络模型图网站&#xff1a;画模型 感受野 一、感受野的概念 感受野&#xff08;Receptive Field&am…

卷积的感受野

title: 卷积的感受野 date: 2022-06-14 19:52:38 tags: 深度学习基础 卷积的感受野 文章目录 title: 卷积的感受野 date: 2022-06-14 19:52:38 tags: 深度学习基础卷积的感受野什么是感受野为什么浅层特征预测小目标&#xff0c;深层特征预测大目标深层特征检测大目标&#xf…

感受野

感受野 先图解一下啥是感受野 感受野具体就是通过卷积核扫描原始图片之后一个feature map的格子代表原始图片的范围大小。 如上图&#xff0c;这是一个55的原始图片padding11&#xff0c;卷积核33&#xff0c;步距2。卷积扫描两次的示意图。 &#xff08;2个33的卷积核扫描两次…

卷积神经网络中感受野的详细介绍

"微信公众号" 本文同步更新在我的微信公众号里面&#xff0c;地址&#xff1a;https://mp.weixin.qq.com/s/qMasyxRILzyEF3YyLvjzqQ 本文同步更新在我的知乎专栏里面&#xff0c;地址&#xff1a;https://zhuanlan.zhihu.com/p/39184237 1. 感受野的概念 在卷积神经…

感受野详解

目录 概念举例感受野的计算规律两种计算感受野的方法从前往后从后往前 推导VGG16网络的感受野结构从后往前从前往后 感受野大于图片为什么要增大感受野 概念 在卷积神经网络中&#xff0c;感受野&#xff08;Receptive Field&#xff09;的定义是卷积神经网络每一层输出的特征…

深度理解感受野(一)什么是感受野?

Introduction 经典目标检测和最新目标跟踪都用到了RPN(region proposal network)&#xff0c;锚框(anchor)是RPN的基础&#xff0c;感受野(receptive field, RF)是anchor的基础。本文介绍感受野及其计算方法&#xff0c;和有效感受野概念 什么是感受野? 感受野与视觉 感受…

感受野的含义及计算方法

1 感受野(Receptive Field)的概念 感受野(Receptive Field)的概念&#xff1a;在卷积神经网络中&#xff0c;感受野的定义是 卷积神经网络每一层输出的特征图&#xff08;feature map&#xff09;上的像素点在原始输入图像上映射的区域大小。第一层卷积层的输出特征图像素的感…

感受野是什么?

在卷积神经网络中,感受野(Receptive Field)是指特征图上的某个点能看到的输入图像的区域,即特征图上的点是由输入图像中感受野大小区域的计算得到的。神经元感受野的值越大表示其能接触到的原始图像范围就越大&#xff0c;也意味着它可能蕴含更为全局&#xff0c;语义层次更高的…

细说卷积神经网络(CNN)中所谓的“感受野”(Receptive Field)

感受野 一、感受野1.全连接网络与卷积神经网络2.进一步体验“感受野”3.计算感受野通用方式4.综合实例5.总结 一、感受野 感受野&#xff1a;卷积神经网络中每个网络层输出的特征图中的单个元素映射回原始输入特征中的区域大小&#xff0c;网络层越深&#xff0c;其输出特征的元…

【Kafka】10道不得不会的 Kafka 面试题

博主介绍&#xff1a; &#x1f680;自媒体 JavaPub 独立维护人&#xff0c;全网粉丝15w&#xff0c;csdn博客专家、java领域优质创作者&#xff0c;51ctoTOP10博主&#xff0c;知乎/掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和副业。&#x1f680; 公众号&…

Java程序员必备的50道Kafka面试题及解析,面试再也不怕问Kafka了

前言 Apache Kafka的受欢迎程度很高&#xff0c;Kafka拥有充足的就业机会和职业前景。此外&#xff0c;在这个时代拥有kafka知识是一条快速增长的道路。所以&#xff0c;在这篇文章中&#xff0c;我们收集了Apache Kafka面试中常见的问题&#xff0c;并提供了答案。因此&#…

Kafka面试题总结

1、kafka是什么? 可以用来做什么? Kafka 是一个分布式的、高吞吐量的、可持久性的、自动负载均衡的消息队列。 它不仅可以实现传统意义上MQ功能&#xff0c;异步、解耦、削峰。 还可以作为大数据的流处理平台。 2、为什么kafka安装需要依赖Zookeeper? 配置中心&#xf…

kafka面试题知识点整理

kafka-面试题整理 刚刚学了kafka&#xff0c;整理一些面试题知识点&#xff0c;帮助记忆1、什么是kafka2、什么是消息队列3、kafka通信流程4、Leader选举流程5、副本及同步原理6、消费者消费数据的方式7、分区分配策略以及原理8、如何保证消息的可靠性9、数据有序/乱序10、幂等…

kafka面试题

1.Kafka数据积压如何处理&#xff1f; 1. 实时/消费任务挂掉导致的消费滞后 a. 任务重新启动后直接消费最新的消息&#xff0c;对于"滞后"的历史数据采用离线程序进行"补漏"。b. 任务启动从上次提交offset处开始消费处理 如果积压的数据量很大&#xff0c…

Kafka 面试题,看这一篇就够了

Kafka 基础 消息系统的作用 大部分小伙伴应该都清楚&#xff0c;这里用机油装箱举个例子&#xff1a; 所以消息系统就是如上图我们所说的仓库&#xff0c;能在中间过程作为缓存&#xff0c;并且实现解耦合的作用。 引入一个场景&#xff0c;我们知道中国移动&#xff0c;中国联…

32 道常见的 Kafka 面试题

最近很多粉丝后台留言问了一些大数据的面试题&#xff0c;其中包括了大量的 Kafka、Spark等相关的问题&#xff0c;所以我特意抽出时间整理了一些大数据相关面试题&#xff0c;本文是 Kafka 面试相关问题&#xff0c;其他系列面试题后面会陆续整理&#xff0c;欢迎关注过往记忆…

Kafka面试题及答案整理 110道 (持续更新)

最新Kafka面试题【附答案解析】Kafka面试题及答案&#xff0c;Kafka最新面试题及答案&#xff0c;Kafka面试题新答案已经全部更新完了&#xff0c;有些答案是自己总结的&#xff0c;也有些答案是在网上搜集整理的。这些答案难免会存在一些错误&#xff0c;仅供大家参考。如果发…

2022 最新 Kafka 面试题

Kafka 面试题 1、如何获取 topic 主题的列表2、生产者和消费者的命令行是什么&#xff1f;3、consumer 是推还是拉&#xff1f;4、讲讲 kafka 维护消费状态跟踪的方法5、讲一下主从同步\6、为什么需要消息系统&#xff0c;mysql 不能满足需求吗&#xff1f;1.解耦&#xff1a;2…

20道常见的kafka面试题以及答案

JAVA面试宝典&#xff0c;搞定JAVA面试&#xff0c;不再是难题&#xff0c;系列文章传送地址&#xff0c;请点击本链接。 目录 1、kafka的消费者是pull(拉)还是push(推)模式&#xff0c;这种模式有什么好处&#xff1f; 2、kafka维护消息状态的跟踪方法 3、zookeeper对于ka…

VS2017安装打包插件

1、打开VS2017&#xff1a;工具-》》扩展和更新-》》 2、搜索Microsoft Visual Studio 2017 Installer Projects 3、点击下载&#xff0c;下载完成 4、按照提示&#xff0c;关闭所有VS后&#xff0c;自动安装 5、选择修改 6、安装完成