之前介绍了一篇基于关键点的Anchor-Free:CenterNet 。其实这种Anchor-Free只是将锚框换成锚点。并没有真正去除anchor。今天介绍的一篇CVPR2019的FSAF真正的是没有anchor这一概念。但是在最后作者做一些实验的时候,仍然把anhor-based模块加入进去并且做了一些loss函数优化的trick,个人觉得有些许耍赖皮。但是不妨碍这篇文章的思想牛掰!
这篇文章深入探究了在目标检测中广泛采用的特征金字塔网络 FPN(Feature Pyramid Network),并且指出了一个它存在的问题:不同尺寸的物体依据其与 FPN 每一层 Anchor 的适配程度,分配到不同分辨率的层上进行学习,期望其能够充分适配各层感受野和空间信息,从而使得检测器能够检测尺寸不一物体。这种启发式的方法虽听着合理(深层感受野大,适合检测大目标;浅层感受野小适合小目标),但是这却没有明确的证据,我们并不知道一个确切的 ground-truth 分配到哪一层上去学习是最合适的(好用但是没有明确解释)。因此,要想取代这种分配方式,就不需要人为的将anchor进行分配层(毕竟包办婚姻不幸福)。因此本文提出的模块也是就叫做 Feature Selective Anchor-Free Module(FSAF),让网络自己学习该怎么分配,为金字塔网络的每一层带去最好的样本(自由婚姻才能带来幸福)。
FPN分配流程:
之前的检测器会把 FPN 上所有层的所有 anchor 全部拿过来,和ground-truth 计算 IoU,通过设定的阈值或者是选择最大的 IoU,便可以得到这个ground-truth 的 positive anchor。由于每一层上的 anchor 都是密集设置的,层与层之间仅仅是 anchor的大小不同(随着分辨率的升高,anchor 的尺寸下降),因此这个分配过程基本就是看 ground-truth 的大小:小的ground-truth 被分配到高分辨率,大的 ground-truth 被分配到低分辨率。这样的设计作者认为它是 heuristic的,可能会使得选择的特征不是最优的,从而影响检测器的性能。
方法
很明显,要想取代上述的分配方式,那么“把 FPN 上所有层的所有 anchor 全部拿过来,和 ground-truth 计算 IoU”这一步就不能有。因此作者提出了一个 anchor-free 的 module,称为 FSAF,大体思想是在每一层都插入这个模块,尝试不用 anchor 去检测物体,而后看看哪一层的 FSAF 对于这个 instance 的损失最小,不就可以认为这一层是最适合检测这个 instance 的吗? 接着 FSAF 大喊一句“你归我了”!!!然后把这个物体安排到这个层,再用 anchor-based 的模块去检测,如下图所示:
那么我们需要关注两个问题:为了实现上述目标,有四个问题要解决:1)如何构建anchor-free的分支。2)如何训练anchor-free的分支(需要ground truth)。3)如何通过anchor-free分支选择最合适的一层。4)如何和anchor-based的分支进行联合训练。
(1)如何构建anchor-free
不借助 anchor 去检测的方法已经层出不穷了,诸如 CornerNet,ExtremeNet ,CenterNet等。在这里,实现 anchor-free detection 则简单的多,在 RetinaNet 的 box 和 cls 分支上仅仅各加了一层 conv layer,分别生成一个 W × H × K classification output 和一个 W × H × 4 的 regression output(4表示该框的左上和右下角的坐标,从而确定了框的坐标)。如下图:
其中 K 是类别数量,classification output 的 每一个 pixel 就表示这个位置应该是什么类别。
(2) GroundTruth与损失函数:
它的标签可以通过ground-truth 投影计算,并且设置一定的比例后得到,如下图,在 instance 的 0.2 倍 box 内为 positive,提供的标签即为“车”这个 class id;在 0.5 倍 box 内进行忽略;其他都设为负。而 regression output 只针对于 0.2 倍的 instance box 进行训练,回归像素点(i,j)离边界的距离。注意的是,这里框的回归采用IoU的loss,这和2019 CVPR的GIoU的loss也不谋而合。
(3)为目标确定最合适的层
再看这张图,哪一个 anchor-free branch 输出的 loss 最小,就把 ground-truth 分配去哪一个层。
也就是对于一个instance,在特征金字塔的每个层级均预测一个bbox,计算loss(loss = focal loss + IoU loss),取min loss所在bbox作为该instance对应的bbox,进行反向传播
(4)联合训练
总体损失函数可以将anchor-free和anchor-based的损失函数合并。在训练阶段,它与 anchor-based 的分支进行加权训练,通过 λ = 0.5 进行权衡。在推理的时候,还需要进行这样的selective 吗?当然不用了,不过要把 anchor-free branch 得到的 box 拿过来和 anchor-based branch 一起做 NMS。(这个我觉得有点扯淡,这个操作对速度影响也太大了吧,如果你想要精度的话,有很多别的方法,根本没必要把你的Anchor-Free分支加进去,有点画蛇添足的感觉,可能是要凑篇幅或者为了对比试验说自己的AF对效果有提升)
实验
我们首先来关注 online feature selection 是不是必要的。如果不采用 loss 决定分配层,而是采用 FPN 应用于 two-stage 中公式来选层的话,对于 anchor-free branch,AP 下降了 1.2 (35.9 → 34.7),当有 anchor-based branch 后,采用 online feature selection 可以比公式选层增加 1.1 的 AP(36.1 → 37.2)。
这里有几个细节值得留意:(1)按照公式选层+anchor-based竟然比原来一把抓 anchor 按照 IoU 选层要高出 0.4(35.7 → 36.1)(2)anchor-free branches 加上 online feature selection 可以超过原生 RetinaNet 0.2 个 AP(35.7 → 35.9)!这就很有意思了,这么简单的一个 anchor-free detector 超过了 RetinaNet。(3)可以看到相比于anchor-based的RetinaNet,如果替换为anchor-free,结果反而出现了下降(说明anchor的预设还是很重要的),如果加上feature selective,也只是和第一行效果差不多。最后,加上anchor-based,最终结果提升了1.5个点。
在不同的backbone上效果也有稳定的提升。但是可以看到如果只采用FSAF的话效果提升很有限,速度却有提升。(但是这也是难能可贵的了,毕竟以及去除了anchor),加上AB与FSAF效果不错,但是速度略有影响。
总结分析
优点:
论文提出了以往目标检测算法中被忽略的问题,目标在尺度上的匹配问题,该方法可以推广到其他目标检测算法中,效果在各个backbone上也都得到了验证,有稳定的提升。
缺点:
anchor free分支和anchor-based分支的互补性很难说明,不过未来的方向肯定是anchor-free有更大的潜力。