R-CNN

2014年

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_02


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_03


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_初始化_04


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_05

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_06


SVM:

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_07

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_08


边界框回归:

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_09


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_10

Fast-RCNN

2015年

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_11

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_采样器_12


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_13


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_采样器_14


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_采样器_15


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_16


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_17


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_18


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_19


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_初始化_20


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_采样器_21


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_22


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_目标检测_23

Faster-RCNN

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_采样器_24


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_25


rpn head的输出是包括分类和回归,分类是二分类,只区分前景和背景;回归是仅仅对于前景样本(正样本)进行基于anchor的变换回归。rpn head的目的是提取roi,然后输入到rcnn head部分进行refine。 rcnn head的输出是包括分类和回归,分类输出是类别数+1(1是考虑背景),回归是仅仅对于前景样本不考虑分类类别进行基于roi的变换回归,rcnn head的目的是对rpn提取的roi特征进行refine,输出精准bbox。

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_26


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_采样器_27

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_28


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_29


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_30


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_初始化_31


fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_深度学习_32

fasterrcnn_resnet50_fpn输出提取的topn个目标区域特征 faster rcnn输出类别_计算机视觉_33


faster rcnn可参考:

正负样本定义

rpn和rcnn的正负样本定义都是基于MaxIoUAssigner,只不过定义阈值不一样而已。
rpn的assigner:

assigner = dict(
	type = 'MaxIouAssigner',
	pos_iou_thr = 0.7,
	neg_iou_thr = 0.3,
	min_pos_iou = 0.3,
	ignore_iof_thr = -1),

rcnn的assigner:

assigner = dict(
	type = 'MaxIouAssigner',
	pos_iou_thr = 0.5,
	neg_iou_thr = 0.5,
	min_pos_iou = 0.5,
	ignore_iof_thr = -1),

正负样本定义非常关键。MaxIoUAssigner的操作包括4个步骤:

  • 首先初始化时候假设每个anchor的mask都是-1,表示都是忽略anchor
  • 将每个anchor和所有gt的iou的最大Iou小于neg_iou_thr的anchor的mask设置为0,表示是负样本(背景样本)
  • 对于每个anchor,计算其和所有gt的iou,选取最大的iou对应的gt位置,如果其最大iou大于等于pos_iou_thr,则设置该anchor的mask设置为1,表示该anchor负责预测该gt bbox,是高质量anchor
  • 3的设置可能会出现某些gt没有分配到对应的anchor(由于iou低于pos_iou_thr),故下一步对于每个gt还需要找出和最大iou的anchor位置,如果其iou大于min_pos_iou,将该anchor的mask设置为1,表示该anchor负责预测对应的gt。通过本步骤,可以最大程度保证每个gt都有anchor负责预测,如果还是小于min_pos_iou,那就没办法了,只能当做忽略样本了。从这一步可以看出,3和4有部分anchor重复分配了,即当某个gt和anchor的最大iou大于等于pos_iou_thr,那肯定大于min_pos_iou,此时3和4步骤分配的同一个anchor。

从上面4步分析,可以发现每个gt可能和多个anchor进行匹配,每个anchor不可能存在和多个gt匹配的场景。在第4步中,每个gt最多只会和某一个anchor匹配,但是实际操作时候为了多增加一些正样本,通过参数gt_max_assign_all可以实现某个gt和多个anchor匹配场景。通常第4步引入的都是低质量anchor,网络训练有时候还会带来噪声,可能还会起反作用。

简单总结来说就是:如果anchor和gt的iou低于neg_iou_thr的,那就是负样本,其应该包括大量数目;如果某个anchor和其中一个gt的最大iou大于pos_iou_thr,那么该anchor就负责对应的gt;如果某个gt和所有anchor的iou中最大的iou会小于pos_iou_thr,但是大于min_pos_iou,则依然将该anchor负责对应的gt;其余的anchor全部当做忽略区域,不计算梯度。该最大分配策略,可以尽最大程度的保证每个gt都有合适的高质量anchor进行负责预测。

由于rcnn head预测值是rpn head的refine,故rcnn head面对的anchor(其实就是rpn输出的roi)和gt的iou会高于rpn head部分,anchor质量更高,故min_pos_iou阈值设置的比较高,由于pos_iou_thr和neg_iou_thr设置都是0.5,那么忽略区域那就是没有了,因为rcnn head面对的都是高质量样本,不应该还存在忽略区域。

正负样本采样

正负样本定义可以区分正负和忽略样本,但是依然存在大量的正负样本不平衡问题,解决办法可以通过正负样本采样或者loss上面一定程度解决,faster rcnn默认是需要进行正负样本采样的。 rpn head和rcnn head的采样器都比较简单,就是随机采样,阈值不一样而已。
rpn head采样器:

sampler=dict(
	type = 'RandomSampler',
	num = 256,
	pos_fraction = 0.5,
	neg_pos_ub = -1,
	add_get_as_proposals = False),

rcnn head采样器:

sampler=dict(
	type = 'RandomSampler',
	num = 512,
	pos_fraction = 0.25,
	neg_pos_ub = -1,
	add_get_as_proposals = True),

num表示采样后样本总数,包括正负和忽略样本,pos_fraction表示其中的正样本比例。add_gt_as_proposals是为了放在正样本太少而加入的,可以保证前期收敛更快、更稳定,属于技巧。neg_pos_ub表示正负样本比例,用于确定负样本采样个数上界,例如我打算采样1000个样本,正样本打算采样500个,但是可能实际正样本才200个,那么正样本实际上只能采样200个,如果设置neg_pos_ub=-1,那么就会对负样本采样800个,用于凑足1000个,但是如果设置为neg_pos_ub比例,例如1.5,那么负样本最多采样200x1.5=300个,最终返回的样本实际上不够1000个。默认情况neg_pos_ub=-1。 由于rcnn head的输入是rpn head的输出,在网络训练前期,rpn无法输出大量高质量样本,故为了平衡和稳定rcnn训练过程,通常会对rcnn head部分添加gt作为proposal。
对正负样本单独进行随机采样就行,如果不够就全部保留。
由于原始faster rcnn采用的loss是ce和SmoothL1Loss,不存在loss层面解决正负样本不平衡问题,故不需要分析loss。