动手学CV-目标检测入门教程3:锚框(anchor)

3.3 锚框 or 先验框

本文来自开源组织 DataWhale 🐳 CV小组创作的目标检测入门教程。

对应开源项目 《动手学CV-Pytorch》 的第3章的内容,教程中涉及的代码也可以在项目中找到,后续会持续更新更多的优质内容,欢迎⭐️。

如果使用我们教程的内容或图片,请在文章醒目位置注明我们的github主页链接:https://github.com/datawhalechina/dive-into-cv-pytorch

3.3.1 关于先验框

在众多经典的目标检测模型中,均有先验框的说法,有的paper(如Faster RCNN)中称之为anchor(锚点),有的paper(如SSD)称之为prior bounding box(先验框),实际上是一个概念。

那么,为什么要有先验框这个概念呢?按理说我们的图片输入模型,模型给出检测结果就好了,为什么还要有先验框?那么关于它的作用,我们不妨回顾一下前面在2.1节所说的那个目标检测最初的解决方案,我们说,我们要遍历图片上每一个可能的目标框,再对这些框进行分类和微调,就可以完成目标检测任务。

你脑中目前很可能没有清晰的概念,因为这个描述很模糊,本节介绍的先验框就是在解决如何定义哪些位置是候选目标框的问题。

接下来需要介绍3个概念:

  • 设置不同尺度的先验框
  • 先验框与特征图的对应
  • 先验框类别信息的确定

设置不同尺度的先验框

通常,为了覆盖更多可能的情况,在图中的同一个位置,我们会设置几个不同尺度的先验框。这里所说的不同尺度,不单单指大小,还有长宽比,如下面的示意图所示:

在这里插入图片描述

同一位置设置多个不同尺度先验框的可视化

可以看到,通过设置不同的尺度的先验框,就有更高的概率出现对于目标物体有良好匹配度的先验框(体现为高IoU)。

先验框与特征图的对应

除了不同尺度,我们肯定要将先验框铺洒在图片中不同位置上面。

但是遍历原图每个像素,设置的先验框就太多了,完全没必要。如图3-13所示。一个224x224的图片,假设每个位置设置3个不同尺寸的先验框,那么就有224x224x3=150528个,但是如果我们不去遍历原图,而是去遍历原图下采样得到的feature map呢?以vgg16的backbone为例,下采样了5次,得到7x7的feature map,那就只需要得到7x7x3=147个先验,这样的设置大大减少了先验框的数量,同时也能覆盖大多数情况。

在这里插入图片描述

图3-13 先验框数量对比

因此,我们就将先验框的设置位置与特征图建立一一对应的关系。而且,通过建立这种映射关系,我们可以通过特征图,直接一次性的输出所有先验框的类别信息以及坐标信息,而不是想前面一直描述的那样,每个候选框都去独立的进行一次分类的预测,这样太慢了(阅读后面的章节后,你将会深刻理解这段话的含义,以及建立这种一一映射的重要意义)。

先验框类别信息的确定

我们铺设了很多的先验框,我们先要给出这些先验框的类别信息,才能让模型学着去预测每个先验框是否对应着一个目标物体。

这些先验框中有很多是和图片中我们要检测的目标完全没有交集或者有很小的交集,

我们的做法是,设定一个IoU阈值,例如iou=0.5,与图片中目标的iou<0.5的先验框,这些框我们将其划分为背景,Iou>=0.5的被归到目标先验框,通过这样划分,得到供模型学习的ground truth信息,如图3-14所示:

在这里插入图片描述

图3-14 先验框划分

3.3.2 先验框的生成

这里,我们来结合代码介绍先验框是如何生成的,更加具体的先验框的使用以及一些训练技巧如先验框的筛选在后面的章节会进一步的介绍。

model.py 脚本下有一个 tiny_detector 类,是本章节介绍的目标检测网络的定义函数,其内部实现了一个 create_prior_boxes 函数,该函数便是用来生成先验框的。

"""
设置细节介绍:
1. 离散程度 fmap_dims = 7: VGG16最后的特征图尺寸为 7*7
2. 在上面的举例中我们是假设了三种尺寸的先验框,然后遍历坐标。在先验框生成过程中,先验框的尺寸是提前设置好的,本教程为特征图上每一个cell定义了共9种不同大小和形状的候选框(3种尺度*3种长宽比=9)生成过程:
0. cx, cy表示中心点坐标
1. 遍历特征图上每一个cell,i+0.5是为了从坐标点移动至cell中心,/fmap_dims目的是将坐标在特征图上归一化
2. 这个时候我们已经可以在每个cell上各生成一个框了,但是这个不是我们需要的,我们称之为base_prior_bbox基准框。
3. 根据我们在每个cell上得到的长宽比1:1的基准框,结合我们设置的3种尺度obj_scales和3种长宽比aspect_ratios就得到了每个cell的9个先验框。
4. 最终结果保存在prior_boxes中并返回。需要注意的是,这个时候我们的到的先验框是针对特征图的尺寸并归一化的,因此要映射到原图计算IOU或者展示,需要:
img_prior_boxes = prior_boxes * 图像尺寸
"""def create_prior_boxes():"""Create the 441 prior (default) boxes for the network, as described in the tutorial.VGG16最后的特征图尺寸为 7*7我们为特征图上每一个cell定义了共9种不同大小和形状的候选框(3种尺度*3种长宽比=9)因此总的候选框个数 = 7 * 7 * 9 = 441:return: prior boxes in center-size coordinates, a tensor of dimensions (441, 4)"""fmap_dims = 7 obj_scales = [0.2, 0.4, 0.6]aspect_ratios = [1., 2., 0.5]prior_boxes = []for i in range(fmap_dims):for j in range(fmap_dims):cx = (j + 0.5) / fmap_dimscy = (i + 0.5) / fmap_dimsfor obj_scale in obj_scales:for ratio in aspect_ratios:prior_boxes.append([cx, cy, obj_scale * sqrt(ratio), obj_scale / sqrt(ratio)])prior_boxes = torch.FloatTensor(prior_boxes).to(device)  # (441, 4)prior_boxes.clamp_(0, 1)  # (441, 4)return prior_boxes

根据上面的代码,我们得到了先验框,那么接下来进行一下可视化吧,为了便于观看,仅展示特征图中间那个cell对应的先验框。

这里为了对比,我们设置两组obj_scales尺度参数。

  1. obj_scales = [0.1, 0.2, 0.3]

这里的参数是归一化的,0.1代表anchor的基准大小为原图长/宽的0.1那么大。

在这里插入图片描述

图3-15 obj_scales = [0.1, 0.2, 0.3]的先验框可视化

可以看到,我们在图片中心得到了各个尺度和宽高比的先验框。

  1. obj_scales = [0.2, 0.4, 0.6]

在这里插入图片描述

图3-16 obj_scales = [0.2, 0.4, 0.6]的先验框可视化

这里对比两组不同的尺度设置,是想展示一个需要注意的小问题,那就是越界,可以看到第二组可视化部分蓝色和绿色的先验框都超出图片界限了,这种情况其实是非常容易出现的,越靠近四周的位置的先验框越容易越界,那么这个问题怎么处理呢?这里我们一般用图片尺寸将越界的先验框进行截断,比如某个先验框左上角坐标是(-5, -9),那么就截断为(0,0),某个先验框右下角坐标是(324,134),当我们的图片大小为(224,224)时,就将其截断为(224,134)。

对应于代码中是这行,prior_boxes.clamp_(0, 1),由于进行了归一化,所以使用0-1进行截断。

3.3.3 小结

以上就是关于先验框生成的全部内容,先验框是目标检测中一个非常非常重要的概念,因此单独拿出来一小节进行介绍。

关于先验框,在训练时,还有一些技巧需要掌握,后面的章节中会有所提及。

下一节将要进入最重点的部分了,模型设计以及结构的讲解。愿各位能够耗子尾汁,再接再厉,好好学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动手学CV-目标检测入门教程4:模型结构

3.4 模型结构 本文来自开源组织 DataWhale &#x1f433; CV小组创作的目标检测入门教程。 对应开源项目 《动手学CV-Pytorch》 的第3章的内容&#xff0c;教程中涉及的代码也可以在项目中找到&#xff0c;后续会持续更新更多的优质内容&#xff0c;欢迎⭐️。 如果使用我们…

PID控制器开发笔记之十二:模糊PID控制器的实现

在现实控制中&#xff0c;被控系统并非是线性时不变的&#xff0c;往往需要动态调整PID的参数&#xff0c;而模糊控制正好能够满足这一需求&#xff0c;所以在接下来的这一节我们将讨论模糊PID控制器的相关问题。模糊PID控制器是将模糊算法与PID控制参数的自整定相结合的一种控…

动手学CV-目标检测入门教程5:损失函数

3.5 损失函数 本文来自开源组织 DataWhale &#x1f433; CV小组创作的目标检测入门教程。 对应开源项目 《动手学CV-Pytorch》 的第3章的内容&#xff0c;教程中涉及的代码也可以在项目中找到&#xff0c;后续会持续更新更多的优质内容&#xff0c;欢迎⭐️。 如果使用我们…

Modbus协议栈开发笔记之四:Modbus TCP Client开发

这一次我们封装Modbus TCP Client应用。同样的我们也不是做具体的应用&#xff0c;而是实现TCP客户端的基本功能。我们将TCP客户端的功能封装为函数&#xff0c;以便在开发具体应用时调用。 对于TCP客户端我们主要实现的功能有两个&#xff1a;其一是生成访问TCP服务器的命令&…

动手学CV-目标检测入门教程6:训练与测试

3.6、训练与测试 本文来自开源组织 DataWhale &#x1f433; CV小组创作的目标检测入门教程。 对应开源项目 《动手学CV-Pytorch》 的第3章的内容&#xff0c;教程中涉及的代码也可以在项目中找到&#xff0c;后续会持续更新更多的优质内容&#xff0c;欢迎⭐️。 如果使用我…

PC软件开发技术之一:在WinCC中通过VBS操作SQL Server2005

在项目中需要在一定条件满足时&#xff0c;保存一些数据到数据库中&#xff0c;并可根据条件查询。考虑到WinCC6.2以后采用的就是SQL Server2005数据库&#xff0c;所以直接利用该数据库即可&#xff0c;通过SQL Server Management Studio&#xff08;SSMS&#xff09;可以创建…

K 近邻算法(KNN)与KD 树实现

KD树节点 /// <summary>/// &#xff2b;&#xff24;树节点/// /2016/4/1安晟添加/// </summary>[Serializable]public class KDTreeNode{/// <summary>/// 获取或设置节点的空间坐标/// </summary>public double[] Position { get; set; }/// <…

PC软件开发技术之二:用C#开发基于自动化接口的OPC客户端

OPC全称是Object Linking and Embedding&#xff08;OLE&#xff09; for Process Control&#xff0c;它的出现为基于Windows的应用程序和现场过程控制应用建立了桥梁。OPC作为一整套接口、属性和方法的协议标准集&#xff0c;与具体的开发语言没有关系。 1、OPC客户端接口方…

标记符控制的分水岭算法原理及matlab实现

-------------------------------------------------------------------------------------------------------------------- 附录A 教程【3】给出的matlab源码&#xff0c;附详细注释 function [ ] MarkerControlled_Watershed_tutorial( ) %标记符控制的分水岭算法教程 …

PC软件开发技术之三:C#操作SQLite数据库

我们在开发应用是经常会需要用到一些数据的存储&#xff0c;存储的方式有多种&#xff0c;使用数据库是一种比较受大家欢迎的方式。但是对于一些小型的应用&#xff0c;如一些移动APP&#xff0c;通常的数据库过于庞大&#xff0c;而轻便的SQLite则能解决这一问题。不但操作方便…

自动搜索数据增强方法分享——fast-autoaugment

前言 简短的介绍下分享fast-autoaugment的原因 毫无疑问数据增强对于训练CNN非常有效&#xff0c;大家也在不断发明新的数据增强方法 拿到一份数据集&#xff0c;我们凭借之前的经验组合不同的增强方法形成一个数据增强策略&#xff0c;通常可以得到一个还不错的baseline。但…

SSD之硬的不能再硬的硬核解析

本文是对经典论文 SSD: Single Shot MultiBox Detector 的解析&#xff0c;耗时3周完成&#xff0c;万字长文&#xff0c;可能是你能看到的最硬核的SSD教程了&#xff0c;如果想一遍搞懂SSD&#xff0c;那就耐心读下去吧~ 一句话总结SSD效果就是&#xff1a;比YOLO快一点且准很…

C语言学习及应用笔记之五:C语言typedef关键字及其使用

在C语言中有一个typedef关键字&#xff0c;其用来定义用户自定义类型。当然&#xff0c;并不是真的创造了一种数据类型&#xff0c;而是给已有的或者符合型的以及复杂的数据类型取一个我们自己更容易理解的别名。总之&#xff0c;可以使用typedef关键字定义一个我们自己的类型名…

Modbus协议栈开发笔记之五:Modbus RTU Slave开发

Modbus在串行链路上分为Slave和Master&#xff0c;这一节我们就来开发Slave。对于Modbus RTU从站来说&#xff0c;需要实现的功能其实与Modbus TCP的服务器端是一样的。其操作过程也是一样的。首先接收到主站的访问命令&#xff0c;对该命令报文进行解析&#xff0c;这里我们也…

Modbus协议栈开发笔记之六:Modbus RTU Master开发

这一节我们来封装最后一种应用&#xff08;Modbus RTU Master应用&#xff09;&#xff0c;RTU主站的开发与TCP客户端的开发是一致的。同样的我们也不是做具体的应用&#xff0c;而是实现RTU主站的基本功能。我们将RTU主站的功能封装为函数&#xff0c;以便在开发具体应用时调用…

PID控制器开发笔记之十三:单神经元PID控制器的实现

神经网络是模拟人脑思维方式的数学模型。神经网络是智能控制的一个重要分支&#xff0c;人们针对控制过程提供了各种实现方式&#xff0c;在本节我们主要讨论一下采用单神经元实现PID控制器的方式。 1、单神经元的基本原理 单神经元作为构成神经网络的基本单位&#xff0c;具…

基于STM32L476的锂电池SOC检测

便携式设备由于使用需求而配备了锂电池&#xff0c;但使用过程中需要掌握电源的状态才能保证设备正常运行。而且在电池充放电的过程中&#xff0c;监控电池的充放电状态也是保证设备安全的需要。 1、硬件设计 电池SOC检测是一个难题&#xff0c;有很多的模型和检测电路。但对…

C语言学习及应用笔记之六:C语言extern关键字及其使用

在C语言中&#xff0c;修饰符extern用在变量或者函数的声明前&#xff0c;用来以标识变量或者函数的定义在别的文件中&#xff0c;提示编译器遇到此变量或者函数时&#xff0c;在其它文件中寻找其定义。extern关键字的用法有几种&#xff0c;我们下面对其进行说明。 1、extern…

TCP/UDP 常用端口列表

计算机之间依照互联网传输层TCP/IP协议不同的协议通信&#xff0c;都有不同的对应端口。所以&#xff0c;利用短信&#xff08;datagram&#xff09;的UDP&#xff0c;所采用的端口号码不一定和采用TCP的端口号码一样。以下为两种通信协议的端口列表链接&#xff1a; 目录 1端…

C语言学习及应用笔记之七:C语言中的回调函数及使用方式

我们在使用C语言实现相对复杂的软件开发时&#xff0c;经常会碰到使用回调函数的问题。但是回调函数的理解和使用却不是一件简单的事&#xff0c;在本篇我们根据我们个人的理解和应用经验对回调函数做简要的分析。 1、什么是回调函数 既然谈到了回调函数&#xff0c;首先我们…