anchor
参考与部分直接摘抄:
https://zhuanlan.zhihu.com/p/138824387
有些地方纯粹自己打一遍加深记忆,如果要看原版请看上述链接~
faster-rcnn
- 初始化anchor:
设输入图像为a*b,图像到需要rpn处时缩放系数为16,即此时feature map尺寸为a/16 * b/16;stride为1,padding为2,使用3 * 3的窗口滑动遍历该feature map,对于每个3 * 3窗口,其中心点对应原图中某点,以原图中这个点为中心点生成anchor ,在该feature map上会映射anchor数量为a/16 * b/16 * 9个,每9个anchor的中心坐标点是一样的;生成这些anchor后删除不完全在图像内的anchor;将每个anchor的mask填充为-1 - 正负样本定义:
rpn:
assigner=dict(
type='MaxIoUAssigner',
pos_iou_thr=0.7,
neg_iou_thr=0.3,
min_pos_iou=0.3,
ignore_iof_thr=-1
)
以rpn为例,经过第一步后,现在有了原图中的一堆anchor,这些anchor需要分配正负样本以及忽略样本,规则如下:
1.每个anchor和所有gt取iou,发现这些iou中最大的都小于0.3(neg_iou_thr),将anchor的mask置为0,标识为负样本;
2.每个anchor和所有gt取iou,找这些iou中最大的对应哪个gt,如果这个最大iou大于等于0.7(pos_iou_thr),将该anchor的mask置为1,标识为正样本;
3.剩下的没有被分配到anchor的gt,找有没有anchor和这个gt有iou,如果最大iou大于0.3(min_pos_iou),也定义这个anchor的mask为1,标识为正样本;如果iou全部小于0.3,不做处理,也即mask依然为-1
忽略样本不进行梯度计算
- 正负样本数量均衡:
步骤2搞出了一堆正样本、负样本、忽略样本,进行学习的时候,样本的数量需要平衡一下。
采用随机采样进行均衡,其中有个小细节:
rpn:
sampler=dict(
type='RandomSampler',
num=256, # 这个地方表示正负样本的总数
pos_fraction=0.5, # 正样本占比,这个地方也就是说,128个正anchor与128个负anchor
neg_pos_ub=-1,
add_gt_as_proposals=False # 是否添加gt作为proposal
)
摘抄:neg_pos_ub表示正负样本比例,用于确定负样本采样个数上限,例如我打算采样1000个样本,正样本打算采样500个,但是可能实际正样本才200个,那么正样本实际上只能采样200个,如果设置neg_pos_ub=-1,那么就会对负样本采样800个,用于凑足1000个,但是如果设置为neg_pos_ub比例,例如1.5,那么负样本最多采样200x1.5=300个,最终返回的样本实际上不够1000个
至此有了一堆anchor,并且带标签表明哪些是正样本哪些是负样本和忽略样本。
proposal
rpn_proposal=dict(
nms_across_levels=False,
nms_pre=2000,
nms_post=2000,
max_num=2000,
nms_thr=0.7,
min_bbox_size=0)
上述的anchor经过softmax二分类,得网络预测得anchor前景/背景类别,(这里还有bbox reg回归),将前景的anchor进行分数排序,取前2k个(nms_pre),再执行NMS,根据NMS的结果进行分数排序,取前nms_post个作为最终的proposal
rcnn:
assigner=dict(
type='MaxIoUAssigner',
pos_iou_thr=0.5,
neg_iou_thr=0.5,
min_pos_iou=0.5,
ignore_iof_thr=-1
)
rcnn:
sampler=dict(
type='RandomSampler',
num=512,
pos_fraction=0.25,
neg_pos_ub=-1,
add_gt_as_proposals=True
)
这些proposal被输入到rcnn模块,筛选出pos+neg=512个去做训练。