点击上方
“
小白学视觉
”,选择加"
星标
"或“
置顶
”
重磅干货,第一时间送达

文章将目标检测中正负样本的区分策略进行汇总。为了能将主要篇幅集中在不同算法生成正负样本的策略上,
文中将
不对每个算法完整结构进行详细介绍。
前言
由于在学习和应用目标检测算法时,不可避免的接触到正负样本的生成策略等知识点,并且正负样本的区分策略对算法最终效果至关重要。因此,通过参考他人的文章资料,本文将目标检测中正负样本的区分策略进行汇总。为了能将主要篇幅集中在不同算法生成正负样本的策略上,本文不对每个算法完整结构进行详细介绍。本文涉及了不同种类的anchor-based和anchor-free的相关算法(共5个)。
一、正负样本的概念
目前,许多人在看相关目标检测的论文时,常常误以为正样本就是我们手动标注的GT(ground truth),这个理解是错误的,正确的理解是这样的:
首先
,正样本是想要检测的目标,比如检测人脸时,人脸是正样本,非人脸则是负样本,比如旁边的窗户、红绿灯之类的其他东西。
其次
,在正负样本选取时,要注意:正样本是与GT的IOU值大于阈值时的取值,负样本是小于阈值的,其他的则把它去除即可。
总之,正负样本都是针对于程序生成的框而言,非GT数据[^1]。
二、为什么要进行正负样本采样?
-
需要处理好正负样本不平衡问题
:在ROI、RPN等过程中,整个图像中正样本区域少,大部分是负样本[^2]。
-
提高网络收敛速度和精度
:对于目标检测算法,主要需要关注的是对应着真实物体的
正样本
,在训练时会根据其loss来调整网络参数。相比之下, 负样本对应着图像的背景,如果有大量的负样本参与训练,则会淹没正样本的损失,从而降低网络收敛的效率与检测精度。
三、anchor-free和anchor-based
二者的区别在于是否利用anchor提取候选框[^2]
-
从anchor回归属于anchor-based类,代表如faster rcnn、retinanet、YOLOv2 v3、ssd等,
-
从point回归属于anchor-free类,代表如cornernet、extremenet、centernet等,
-
二者融合代表如fsaf、sface、ga-rpn等。
四、典型算法
1、MTCNN
论文:Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks
PNet的输入尺寸为
, RNet的输入尺寸为
, ONet的输入尺寸为
。
由于PNet输入是一个
大小的图片,所以训练前需要把生成的训练数据(通过生成bounding box,然后把该bounding box 剪切成
大小的图片),转换成
的结构。其他网络输入尺寸如下图所示:
1)正负样本的定义
训练数据可以通过和GT的 IOU 的计算生成一系列的 bounding box。可以通过滑动窗口或者随机采样的方法获取训练数据,训练数据分为三种正样本,负样本,中间样本[^4]。
正样本:IOU > 0.65
部分样本:0.4 < IOU < 0.65
负样本: IOU < 0.3
如下图所示,为依据图片中人脸框的坐标信息生成
正样本
和
部分样本
:由于篇幅原因,下图中IOU的计算过程没有截图,可以参考[^4]的源码。
此处生成正样本的脚本,除了对生成的矩形框尺度进行约束,还约束了矩形框的中心点坐标范围。笔者认为,这样做主要是为了提高生成正样本的效率:因为一张图片中正样本的数量是非常有限的,要确保生成的矩形框与GT的IOU大于一定阈值才能成为正样本。
如下图所示,使用随机采样的方式生成负样本:红色框为crop_box计算方法,相对正样本的生成方式更简单。
注意:代码中的 width、height 分别是原始图像的尺度。
训练样本包含:正样本,负样本,部分样本,关键点样本。比例为 1 : 3 : 1 : 2
-
-
-
-
1、首先整张图像经过金字塔,生成
多个尺度的图像(图像金字塔)
,然后输入PNet,PNet由于尺寸很小,所以可以很快的选出候选区域。但是准确率不高,不同尺度上的判断出来的人脸检测框,然后采用NMS算法,合并候选框。
2、根据候选框提取图像,之后缩放到
的大小,作为RNet的输入,RNet可以精确的选取边框,一般最后只剩几个边框。
3、最后缩放到
的大小,输入ONet,判断后选框是不是人脸,ONet虽然速度较慢,但是由于经过前两个网络,已经得到了高概率的边框,所以输入ONet的图像较少,然后ONet输出精确的边框和关键点信息,只是在第三个阶段上才显示人脸特征定位;前两个阶段只是分类,不显示人脸定点的结果。
2、Faster rcnn
论文:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
1)Anchor概念
-
Anchor本质上是在原图上
预先定义好
(这个预先定义十分关键)的一系列大小不一的矩形框[^5]。
-
这是因为之前的目标检测都是模型直接回归边框的位置,而通过引入Anchor相当于加入了强先验信息,然后通过锚框再去筛选与修正,最后再得到预测框。这样做的好处在与是在Anchor的基础上做物体检测,这样要比从无到有的直接拟合物体的边框容易一些。
具体的做法就是:让模型去预测Anchor与真实边框的偏移值,而不是直接预测边框的坐标[^5]。
-
特征图(feature map)上的
每一个点
都
生成一组锚点
。注意:即使我们是在特征图上生成的锚点,这些锚点最终是要映射回原始图片的尺寸(参考下图感受野的相关概念[^7])。
因为我们只用到了卷积和池化层,所以特征图的最终维度与原始图片是呈比例的。数学上,如果图片的尺寸是
,那么特征图最终会缩小到尺寸为
和
,其中 r 是次级采样率。如果我们在特征图上每个空间位置上都定义一个锚点,那么最终图片的锚点会相隔 r 个像素,在 VGG 中,
,此处可以参考文章最后的文献[^6]。 所以,
feature map上一点对应到原图的大小为
的区域。
在目标检测中,需要检测的目标形态大小各异,如果统一以固定大小的窗口进行检测,肯定会影响检测效果,降低精度。因此Faster R-CNN算法为每个滑动窗口位置配置了
9个基准矩形框
来适配各种目标。即,对于每张输入的特征图像的每一个位置,使用
9种尺度的候选窗口
:三种面积{
,
,
},三种比例{1 : 1, 1 : 2, 2 : 1},目的是尽可能的将尺度大小不一的特定目标区域特征检测出来,并判断候选窗口是否包含感兴趣的目标。
左侧:锚点、中心:特征图空间单一锚点在原图中的表达,右侧:所有锚点在原图中的表达(如上图所示)
2)正负样本的定义[^8]
faster rcnn中正负样本是根据anchors的标定规则来生成的。
-
如果某个anchor和其中一个GT的最大iou大于pos_iou_thr,那么该anchor就负责对应的GT;
-
如果某个GT和
所有anchor
的iou中最大的iou会小于pos_iou_thr,但是大于min_pos_iou,则依然将该anchor负责对应的gt。通过本步骤,可以最大程度保证每个GT都有anchor负责预测,
如果还是小于min_pos_iou,那就没办法了,只能当做忽略样本
了;
-
如果anchor和GT的iou低于neg_iou_thr的,那就是负样本,其应该包括大量数目;
-
该最大分配策略,可以尽最大程度的保证每个GT都有合适的高质量anchor进行负责预测。
3)
正负样本的采样
虽然上文中的最大分配策略可以区分正负样本和忽略样本,但是依然存在大量的正负样本不平衡问题。
解决办法可以通过正负样本采样或者loss上面一定程度解决
,faster rcnn默认是需要进行正负样本采样的。 rpn head和rcnn head的采样器都比较简单,就是随机采样,阈值不一样而已。
注意:RPN中的add_gt_as_proposals=False
注意:rcnn中的add_gt_as_proposals=True
neg_pos_ub表示正负样本比例,用于确定负样本采样个数上界,例如我打算采样1000个样本,正样本打算采样500个,但是可能实际正样本才200个,那么正样本实际上只能采样200个,如果设置neg_pos_ub=-1,那么就会对负样本采样800个,用于凑足1000个,但是如果设置为neg_pos_ub比例,例如1.5,那么负样本最多采样
个,最终返回的样本实际上不够1000个。默认情况neg_pos_ub=-1。
由于rcnn head的输入是rpn head的输出,在网络训练前期,rpn无法输出大量高质量样本,故为了平衡和稳定rcnn训练过程,通常会对
rcnn head
部分添加gt作为proposal。因此,上述两个采样器还有一个参数add_gt_as_proposals。
3、SSD
论文:SSD: Single Shot MultiBox Detector
SSD是最典型的多尺度预测结构,是非常早期的网络。
可以通过如下网络结构对比图,大致理解SSD解决多尺度问题的思路与其他网络的区别。
左侧:仅在一种尺度的特征图上进行检测,例如Faster rcnn。右侧:在多种尺度特征上进行检测,例如SSD。
1)SSD核心设计思路[^9]:
(1)采用多尺度特征图用于检测
所谓多尺度采用大小不同的特征图(feature map),CNN网络一般前面的特征图比较大,后面会逐渐采用
stride=2
的卷积或者
pool
来降低特征图大小。
下图所示,一个比较大的特征图和一个比较小的特征图,他们
都用来做检测
。这样做的好处是:
比较大的特征图用来检测相对较小的目标,而小的特征图负责检测大目标
,
的特征图可以划分更多的单元,但是其每个单元的default box尺度比较小。
左侧:
的特征图上设置尺寸小的先验框。右侧:
的特征图上设置尺寸大的先验框
特别注意:
上述两个特征图尺寸是不一样的,
的尺寸比
的尺寸大,但是,
的特征图中每个小格子,即feature map cell的感受野都比
小,即,每个小格子映射回原图时对应的图片区域。一块区域就可以看做一组特征。然后对这些特征进行分类和回归。
(2)采用卷积进行检测
SSD直接采用卷积对不同的特征图来进行提取检测结果。对于形状为
的特征图,只需要采用
这样比较小的卷积核得到检测值。此处主要是与yolo最后采用全连接层的方式进行对比。
(3)设置先验框(default boxes)
SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框(default boxes),预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。
一般情况下,每个单元会设置多个先验框,其尺度和长宽比存在差异,如下图所示,可以看到
每个单元使用了4个不同的default boxes
(SSD中不同尺度的特征图可以设置不同个数的先验框),图片中猫和狗
分别采用最适合它们形状的先验框
来进行训练,后面会详细讲解训练过程中的先验框匹配原则。
如上图所示,在不同尺度的特征图上设置不同尺度和长宽比的先验框
每一个feature map中的每一个小格子(cell)都包含多个default box,同时每个box对应loc(位置坐标)和conf(每个种类的得分)。
default box长宽比例默认有
四个
和
六个:
四个default box是长宽比(
aspect ratios
)为(1:1)、(2:1)、(1:2)、(1:1);六个则是添加了(1:3)、(3:1)。
这时候就要讲下论文中
Choosing scales and aspect ratios for default boxes
这段内容了。作者认为
不同的feature map应该有不同的比例
(一个大框一个小框,长宽比相同,但是不同feature map 相对于原图的尺寸比例不同)。这是什么意思呢?代表的是
default box中这个1在原图中的尺寸是多大的
。
(4)计算先验框min_sizes和max_sizes的方式
对于
先验框的尺度
,其遵守一个线性递增规则:随着特征图大小降低,先验框尺度线性增加。计算公式如下所示:
**
**即代表在300*300输入中的比例,表示第k层feature map上生成的先验框大小相对于图片的比例。
为当前的网络结构中可以生成先验框的feature map层数。
特别注意:
,因为一共有6个feature map,但是第一层(Conv4_3层)是单独设置的。
和
代表的是第一层和最后一层所占的比例,比例的最小值和最大值,在
ssd300中为0.2-0.9。
实际上是:对于第一个特征图Conv4_3,其先验框的尺度比例一般设置为
,故第一层的
。输入是300,故conv4_3的min_size=30。对于从第二层开始的特征图,则利用上述公式进行线性增加,然后再乘以图片大小,可以得到各个特征图的尺度为60、111、162、213、264。最后一个特征图conv9_2的size是直接计算的,
。 以上计算可得每个特征的min_size和max_size,如下:
具体实现代码:ssd_pascal.py
下图注释中提到的博客:关于SSD默认框产生的详细解读
接下来,补充回答为什么default box的size有两个(1:1)[^9]?
作者在这有引入了一个
,也就是每个特征图都设置了两个长宽比为1大小不同的正方形default box。有的小伙伴可能会有疑问,这有了
则需要多出来一部分的
啊,是的没错,最后一个特征图需要参考
来计算
,因此每个特征图(的每个cell)都有6个default box
(
aspect ratios
),但是在实现时, Conv4_3,Conv10_2,Conv11_2仅仅使用4个先验框(default box),不使用长宽比为
的先验框(default box)。作者的代码中就添加了两层,
第一层取0.1
,
最后一层取1
。
那么S怎么用呢?按如下方式计算先验框的宽高(这里的Sk是上面求得的各个特征图的先验框的实际size,不再是尺度比例):
ar代表的是之前提到的先验框default box(
aspect ratios
)比例,即
对于先验框default box中心点的值取值为:
其中i,j代表在feature map中的水平和垂直的第几格。
(5)计算先验框的大小的方式
下图所示为每个cell生成4个先验框的方法,生成6个先验框的方式类似,只需要增加1:3和3:1两个比例的矩形框即可。
2)
正负样本的定义
SSD采用的正负样本定义器依然是MaxIoUAssigner,但是由于参数设置不一样,故有了不同的解释。
-
anchor和某个GT的最大iou大于0.5,则认为是正样本。
-
GT和所有anchor的最大iou值,如果大于0.0,则认为该最大iou anchor是正样本。
-
anchor和所有GT的iou都小于0.5,则认为是负样本。
-
没有忽略样本,即每个GT一定会和某个anchor匹配上,不可能存在GT没有anchor匹配的情况。
3)
正负样本的采样
尽管一个ground truth可以与多个先验框匹配,但是ground truth相对于先验框还是太少了,所以负样本会很多。为保证正负样本尽量均衡,SSD采用了
hard negative mining
,先将每一个物体位置上对应 predictions(default boxes)是 negative 的 boxes 进行排序,按照先验框的confidence的大小。 选择最高的几个,保证最后 negatives、positives 的比例接近3:1。
4、FPN
论文:Feature Pyramid Networks for Object Detection
下图展示了4种利用特征的形式:
(a)图像金字塔,即将图像做成不同的scale,然后不同scale的图像生成对应的不同scale的特征。这种方法的缺点在于增加了时间成本。有些算法会在测试时候采用图像金字塔。
(b)像SPPnet,Fast RCNN,Faster RCNN是采用这种方式,即仅采用网络最后一层的特征。
(c)像SSD(Single Shot Detector)采用这种多尺度特征融合的方式,没有上采样过程,即从网络不同层抽取不同尺度的特征做预测,这种方式不会增加额外的计算量。作者认为SSD算法中没有用到足够低层的特征(在SSD中,最低层的特征是VGG网络的conv4_3),而在作者看来足够低层的特征对于检测小物体是很有帮助的。
(d)本文作者是采用这种方式,顶层特征通过上采样和低层特征做融合,而且每层都是独立预测的。
FPN主要解决的是物体检测中的多尺度问题,通过简单的网络连接改变,在基本不增加原有模型计算量的情况下,大幅度提升了小物体检测的性能。通过高层特征进行上采样和低层特征进行自顶向下的连接,而且每一层都会进行预测。
FPN算法大致结构:
一个自底向上的线路,一个自顶向下的线路,横向连接(lateral connection)
。下图中放大的区域就是横向连接,这里
的卷积核的主要作用是减少卷积核的个数,也就是减少了feature map的个数,并不改变feature map的尺寸大小。
在横向连接中,采用
的卷积核进行连接(减少特征图数量)。
将FPN和RPN结合起来,那RPN的输入就会变成多尺度的feature map,那我们就需要在金字塔的每一层后边都接一个RPN head(一个
卷积,两个
卷积),如下图所示.其中,P6是通过P5下采样得到的。
1)设置先验框(default boxes)
在生成anchor的时候,因为输入是多尺度特征,就不需要再对每层都使用3种不同尺度的anchor了,所以在每一个scale层,都定义了不同大小的anchor。对于P2,P3,P4,P5,P6这些层,定义anchor的大小为