一、 前言
本篇博客主要是ATSS
部分,这部分个人认为是核心之一,毕竟正负样本的选择很重要,ATSS
论文证实,anchor-based
和anchor-free
性能差异的根本原因在于正负样本的定义,好的正负样本定义方法能在很大程度上降低模型对Anchor Num
, Anchor Size
的依赖。这点在yolo v5
上也得到了证实——“正确的正负样本定义方式能引入更多的高质量正样本,加快拟合 并 提高模型性能”。
首先推荐一个写的很好的 ATSS博客,看完它再看代码会清晰许多。以及我写的ATSS部分代码注释。
二、 正文
根据代码总结的ATSS
流程如下:
- 遍历每个
ground truth
,遍历每个输出层,找出每层前topk
(超参,nanodet
中是9
)个L2
距离(anchor
和gt box
中心点距离)最小的anchor
。nanodet
一共3
层输出层,则每个gt
会匹配到27
个候选anchor
,输出数组shape=(27, gt_num)
。这些anchor
里可能会有重复,但是没关系,下面还有筛选措施; - 计算每个
gt
和与之对应的27
个anchor
的IOU
值,shape=(27, gt_num)
(注意是与anchor
左上右下的坐标做iou
,不是和bbox
,现在是给anchor
做正负样本分类,还没到bbox
呢); - 按列计算每个
gt
对应的27
个IOU
值的均值mean_IOU
和标准差std_IOU
,两者相加得到每个gt
的自适应阈值,shape = (gt_num, )
; - 从每个
gt
的27
个anchor
中筛选出IOU
大于对应自适应阈值的anchor
; - 再计算每个
anchor
中心到其对应gt
四条边界线的距离,取四个距离中的最小值,过滤掉最小值小于0.01
的anchor
,剩下的就是挑选出的正样本; - 到这步时,可能有些
anchor
同时匹配了多个gt
,此时需选出IOU
值最大的那个gt
作为匹配对象。即一个anchor
只能匹配到一个gt
,但是一个gt
可以同时被多个anchcor
匹配。
从上面流程来看,一个anchor
要成为一个正样本,需要满足三个条件:
① 其中心要与任何一个gt
中心的距离要排在前topk
内(升序);
② 其与gt
的iou
值要大于对应的iou
阈值;
③