目标检测---匹配策略

CVPR2020中的文章ATSS揭露到anchor-based和anchor-free的目标检测算法之间的效果差异原因是由于正负样本的选择造成的。而在目标检测算法中正负样本的选择是由 ground truth bbox 与 anchor bbox 之间的匹配策略决定的。因此我们研究一下目前现有的匹配策略,并根据现状给出改进思路。

Faster R-CNN、RetinaNet、SSD算法

采用的分配策略是max IOU assigner,即:对于每个ground truth bbox,将高于正样本阈值并且是最大IOU位置的 anchor bbox 设置为正样本;将低于负样本阈值的 anchor bbox 设置为负样本,考虑到有些 ground truth 和 anchor bbox 的 IOU 不高,故还设置了最小正样本阈值,当某个 ground truth bbox 和 anchor bbox 的最大IOU高于最小正样本阈值的时候,则依然将该 anchor bbox 设置为正样本。

YOLO 系列

对于每个 ground truth bbox, 将最大 IOU 位置的 anchor bbox 设置为正样本,不管阈值有多大(先要确定哪一预测层负责预测),这种操作对 anchor 设置的要求较高,因为如果 anchor 的设置不合理,就只能用大量低质量的 anchor bbox 负责回归了。对于正样本附近的 anchor bbox 预测值,它们可能和 ground truth 的 IOU 也很高,因此需要将这些位置的 anchor bbox 预测值设置为忽略样本,默认阈值是0.7,可能会滤除一些正样本。

FCOS

第一步也是和YOLO一样,要确定某个 ground truth bbox 由第几个层级负责预测(采用 min size 和 max size),第二步是需要确定在每个输出层级上面,哪些空间位置是正样本区域,哪些是负样本区域。原版的FCOS的正负样本策略非常简单粗暴:在bbox区域内的都是正样本,其余地方都是负样本,而没有忽略样本区域。可想而知这种做法不友好,因为标注本身就存在大量噪声,如果bbox全部区域都作为正样本,那么bbox边缘的位置作为正样本负责预测是难以得到好的效果的,显然是不太靠谱的(在文本检测领域,都会采用 shrink 做法来得到正样本区域),所以后面又提到了 center sampling 的做法来确定正负样本,具体是:引入了center_sample_radius(基于当前 stride 参数)的参数,用于确定在半径范围内的样本都属于正样本区域,其余区域作为负样本,依然没有定义忽略样本。

Guided Anchoring

论文思想是通过图像特征来指导 anchor 的生成。通过预测 anchor 的位置和形状,来生成稀疏而且形状任意的 anchors,并且设计了 Feature Adaption 模块来修正特征图使之与 anchor 形状更加匹配,在使用 ResNet-50-FPN 作为主干网络的情况下,Guided Anchoring 将 RPN 的 Recall(AR@100) 提高了 9.1 个点,将其用于不同的物体检测器上,可以提高 mAP 1.2 到 2.7个点不等。

论文的实现方式如下图:

目标检测---匹配策略_第1张图片

**匹配策略:**将整个特征图的区域分为物体中心区域、外围区域和忽略区域,大概思路就是将 ground truth bbox 的中心一小块对应在特征图上的区域标注为物体的中心区域,在训练的时候作为正样本,其余区域按照距离中心的远近标注为忽略或负样本,具体设计在论文中讲的比较清楚。通过位置预测,我们可以筛选出一小部分区域作为 anchor 的候选中心点位置,使得 anchor 数量大大降低。在推理的时候,预测完位置后,我们可以采用 masked conv 替代普通的卷积,只有在 anchor 的地方进行计算,可以进行加速。

ATSS

目标检测---匹配策略_第2张图片

  1. 对于每个 ground truth bbox, 找到候选的正 anchor 集合:

在每个金字塔层级(共L层)上,选择 top K 个离 ground truth 中心距离最近的 anchor bbox 作为候选 anchor,那么每个 ground truth 就会有 k × L k\times L k×L个候选正 anchor bboxes。

  1. 计算自适应阈值:

计算候选 anchor bbox 与 ground truth bbox 之间的 IOU D g D_g Dg,计算均值 m g m_g mg和标准差 v g v_g vg,其阈值为 t g = m g + v g t_g = m_g + v_g tg=mg+vg

  1. 确定最终的正 anchors:

选择 I O U > t g IOU\gt t_g IOU>tg,且中心点在 ground truth 边框内部的 anchors 作为最终的正样本,如果一个 anchor bbox 被分配给了多个 ground truth bbox,选择 IOU 最高的那个 ground truth bbox。

ATSS 的意义

  • 根据目标统计特征,自动调整正负样本的选取方式。如图(a),当 m g m_g mg越大,表示候选样本的质量很高,可以选取一个高的 IOU 阈值。如图(b), m g m_g mg越小,表示绝大多数的候选样本较差,应当选取一个较低的阈值来确保 ground truth bbox 可以匹配到 anchor bbox。如图3(a), v g v_g vg较大时,往往意味着有一个FPN层级出现了较高的IOU,说明该层非常适合这个物体的预测,因此 v g v_g vg m g m_g mg加起来得到一个较高的阈值,我们只从这一层选取正样本。如图3(b), v g v_g vg较小意味着存在多个适合该目标的金字塔层级,因此 v g v_g vg m g m_g mg加起来得到一个较低的阈值,会在这些层级上选取正样本。

目标检测---匹配策略_第3张图片

  • 每个目标匹配 anchor 的数量相对均匀

HAMBox

匹配策略

  1. 将每张脸匹配到那些与它的IOU大于某个阈值的 anchor,对于 outer face 不进行补偿。
  2. 在训练的每次前向传播之后,每个 anchor 通过回归得到的坐标计算出回归框,我们将这些回归框记做 B r e g B_{reg} Breg,异常脸 outer face 记做 F o u t e r F_{outer} Fouter。最后对于每个 outer face,我们计算它和 B r e g B_{reg} Breg的IOU值,然后对每个 outer face 补偿 N N N个 unmatched anchor。记所有的 IOU 为 I O U s e t IOU_{set} IOUset,这些补偿的 N N N个 anchors 通过下面方式选择:

a) IOU 要大于阈值 T T T(在线正 anchor 匹配阈值);

b) 对a)中得到的 anchor 进行排序,选择 IOU 最大的 top-k 个 anchor 做补偿。 k k k是一个超参数,表示每个 outer face 能匹配的最多的 anchor 数目。使用 M M M表示在步骤1中已经匹配的 anchor 数目,如果 N > k − M N > k-M N>kM,则选取 top (k-M) 个 unmatched anchors 来补偿。

T T T k k k是通过实验选择的超参数。具体算法细节见下面,该算法在训练的每次前向传播后执行一次。

/*
输入:B,X,T,K,D,L,R,A
B 是一组回归后的框,格式为(x0, y0, x1, y1)
X 是一组ground truth, 格式为(x0, y0, x1, y1)
T 是上述算法中在线anchor挖掘中定义的阈值
K 是每个outer face能匹配到的最多anchor数目
D 是一个字典,key是ground_truth, value是HAMBox第一步中
  该gt能match到的anchor数,即matched_anchor的数目
L 是一个字典,key是anchor index, value是该anchor在HAMBox中最终分配的label
R 是一个字典,key是anchor index, value是该anchor经过普通anchor matching后的编码后的坐标
A 是一个字典,key是anchor index, value是该anchor的坐标,格式为(x0, y0, x1, y1)

输出:经过HAMBox后的R和L
*/
// 伪代码见下
for x_i in x do
    if D(x_i) >= K then
        continue
    end if
    compensatedNumber = K - D(x_i)
    onlineIoU = IoU(x_i, B),AnchorIdx 
    sortedOnlineIoU = sorted(onlineIoU, key = IoU, reverse = True)
    for IoU, AnchorIdx in sortedOnlineIoU do
        if(L(AnchorIdx) = 1) then
            continue
        endif
        if(IoU < T) then
            continue
        endif
        compensatedNumber -= 1
        L(AnchorIdx) = 1
        R(AnchorIdx) = encoded(A(AnchorIdx), x_i)
        if compensatedNumber = 0 then  
            break
        endif
    endfor
endfor
return R, L

你可能感兴趣的:(目标检测)