目标检测中的anchor-base与anchor-free

目标检测领域的发展从anchor-free到anchor-base,现在又有回到anchor-free的趋势,学术界技术的迭代更新也引导着工业界的变革。今天我们就从anchor出发,分析对比基于anchor-base和anchor-free的检测算法及优劣特性。

目标检测中究竟什么是anchor?

图像中的目标检测是如何做的?

Anchor-Base

基于单阶段的检测算法

基于两阶段的检测算法

Anchor-Free

基于关键点的检测算法

基于目标中心的检测算法

二者孰优孰劣

分类方式不同

回归方式的不同

知乎回答一(作者本人)

知乎回答二

从Faster R-CNN来理解Anchor

Faster RCNN

anchor也叫做锚,其实是一组预设的边界框用于在训练时构建真实的边框位置相对于预设边框的偏移。通俗点说就是预先设置目标可能存在的大概位置,然后再在这些预设边框的基础上进行精细化的调整。 而它的本质就是为了解决标签分配的问题。

锚作为一系列先验框信息,其生成涉及以下几个部分:

  • 用网络提取特征图的点来定位边框的位置;
  • 用锚的尺寸来设定边框的大小;
  • 用锚的长宽比来设定边框的形状;

通过设置不同尺度,不同大小的先验框,就有更高的概率出现对于目标物体有良好匹配度的先验框约束。

在传统的图像处理时期,要想检测出图像中的目标,通常先提取图像特征,然后编码成一串串特征描述子送入机器学习的分类器中进行判别。比如HOG特征提取器通过滑窗+金字塔的方式逐个抠图,这种基于区域的方式在深度学习中得到了延续。

在两阶段的目标检测分支中,暴力滑窗获得区域的思想逐步演化出锚的概念,从Faster RCNN网络开始正式基于anchor回归坐标,通过RPN的策略生成候选框。

在单阶段的目标检测分支中,从SSD到YOLOv2,v3,v4,v5都延续着基于anchor做回归的路线。

这里小伙伴们会发现怎么把YOLOv1漏了?

YOLOv1只有区域划分的思想而没有锚框的概念,虽然将图片网格化后在每个网格中预测目标,但是尺度的回归是在整个图像中,所以该网络出来时检测精度相比同期作品低了一大截,这也是为什么YOLO的后期版本均加入了锚框的思想,在锚框的约束下使模型的精准度和召回率都有了质的提升。

前几年目标检测领域一直被基于锚的检测器所统治,此类算法的流程可以分为三步:

  1. 在图像或者点云空间预设大量的anchor(2D/3D);

  2. 回归目标相对于anchor的四个偏移量;

  3. 用对应的anchor和回归的偏移量修正精确的目标位置;

基于单阶段的检测算法

在图像上滑动可能的锚点,然后直接对框进行分类。这两年单阶段的检测方法不断的扩充YOLO家族,小编接触过的就有YOLOv1—v5,Complex-YOLO,YOLO3D,YOLO-Lite Poly-YOLO,YOLOP等等,GitHub上一搜能有小几十个变形。

整体框架一般分为BackBone,Neck,Head三大块,基础特征部分其实ResNet-50就挺好了,或者采用CSP/C3等模块级联提取特征。Neck部分各个网络也都差不多,采用FPN或者PAN来融合高低层特征图信息。Head部分主要针对任务而定,如果做二维框检测就回归中心点,宽高,类别等信息;如果做三维框检测可以增加朝向角或者掩码图等等。

基于两阶段的检测算法

对每个潜在的框重新计算图像特征,然后将这些特征进行分类。这两年两阶段的新方法出现的比较少,在2D,3D或者前融合领域出现的两阶段检测算法还是依托于Faster-RCNN的理念。

两阶段检测算法主要还是RCNN系列,包括RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN等。其中RCNN和Fast-RCNN之间过渡了一个SPPNet。之后在Faster-RCNN框架的基础上出现了特征金字塔。然后Mask-RCNN融合了Faster-RCNN架构、ResNet和FPN,以及FCN里的分割方法来提升mAP。

下图是在网上找到的一张两阶段检测网络发展历程,从细分市场的角度描述的挺详细的,供小伙伴们对应学习(图片来自网络,如有侵权,联系删除):

目标检测中为什么要引入anchor?

相当于在检测网络中引入先验信息,可以想象一下在一张大图中去定位目标位置与在一个小框中修正目标位置哪个更容易些呢?

基于Anchor-Free的目标检测算法有两种方式,

  • 其一就是我们前几篇提到的关键点检测方法,通过定位目标物体的几个关键点来限定它的搜索空间;
  • 其二是通过目标物体的中心点来定位,然后预测中心到边界的距离。

最直接的好处就是不用在训练之前对当前训练数据聚类出多个宽高的anchor参数了。

基于关键点的检测算法

此类方法将目标检测问题转换成关键点定位组合来解决,下面介绍几种关键点检测算法:

首先就是CornerNet,它通过检测目标框的左上角和右下角两个关键点获得预测框。整个网络如下图所示:输入图像通过串联多个Hourglass模块做特征提取,然后输出两个分支,即左上角点预测分支和右下角点预测分支;每个分支模型经过Corner Pooling后输出三个部分:

  • Heatmaps:预测角点位置
  • Embeddings:预测的角点分组
  • Offsets:微调预测框

Grid R-CNN算法基于RPN找到候选区域,对每个ROI特征独立的提取特征图。将特征图传到全卷积网络层里面输出概率的热度图,用于定位与目标物对齐的边界框的网格点;借助网格点通过特征图级别的融合,最终确定目标物的准确边界框。

ExtremeNet算法通过串联多个Hourglass模块对每个目标预测5个关键点(上、下、左、右四个极点和一个中心点),如果五个关键点是几何对齐的,也就是说将不同热度图的极点进行组合,判断组合的几何中心是否符合中心点热图上的值的要求,再将它们分组到一个外接框中。

基于目标中心的检测算法

此类方法在构建模型时将其看作一个点,即目标框的中心点。检测器在回归中心点的同时得到它的相关属性。下面我们介绍几种基于目标中心的检测算法:

YOLO作为早期的一种anchor-free的算法,将目标检测作为一个空间分离的边界框和相关的类概率回归问题,可以直接从整张图片预测出边界框和分类分数。

但是它最后采用全连接层直接对边界框进行预测,由于图片中存在不同尺度和长宽比(scales and ratios)的物体,使得YOLO在训练过程中学习适应不同物体的形状比较困难。

上面我们也提到YOLO由于在网络中没有预先假设框的大小和宽高比,所以在训练的过程中它除了知道每个网络输出几个检测框外,其他预设框的任何信息都一无所知。

CenterNet只需要提取目标的中心点,无需对关键点分组和后处理。这篇文章的网络结构较为清晰,从开源的代码中可以看到,采用编解码的方式提取特征(Resnet/DLA/Hourglass),输出端分为三块:

  • Heatmap:预测中心点的位置;
  • wh:对应中心点的宽高;
  • reg:对应中心点的偏移;

那么目标检测领域为什么又考虑去掉anchor呢?

  1. 预先设定的anchor尺寸需要根据数据集的不同做改变,可以人工设置或对数据集聚类得到;

  2. anchor的数量相比目标的个数多很多,造成正负样本的不均衡现象;

当然为了解决去掉anchor后目标尺度变化,类别不平衡等的问题,FPN,PAN,Focal loss等技术起到了很好的作用,通过FPN,PAN对不同层级特征的融合使得预测时使用的特征图中就包含了不同尺度的目标特征,这样就不需要用不同尺度的anchor来锁定目标尺寸再进行回归。而Focal loss对正负样本求损失时的加权也在一定程度上缓解了不平衡问题。

学术界有一篇专门介绍Anchor-Base和Anchor-Free差异的文章:《Bridging the Gap Between Anchor-based and Anchor-free Detection via Adaptive Training Sample Selection》

两种方式的本质区别在于如何定义正负样本以及回归的方式。如下给出了Anchor-Base算法RetinaNet(左图)和Anchor-Free算法FCOS(右图)的两个区别:

  • 分类方式不同:正负样本的选择方式
  • 回归方式不同:基于anchor还是point做回归

分类方式不同

如图(a) RetinaNet基于anchor做回归,首先计算来自不同尺度的anchor box与gt的IoU来确定正负样本;对于每个目标在所有IoU大于阈值k的anchor box中,选择最大的作为正样本,所有IoU小于阈值q的anchor box作为负样本,其余忽略不计;最后针对正样本的anchor回归相对偏移量。

如图(b) FCOS基于center做回归,使用空间和尺度约束将anchor点分配到不同尺度上,通过判断特征图上的点是否落入gt中来确认正负样本,即将物体边框内的所有位置都定义为正样本;最后通过4个距离值和1个 中心点的分数来检测物体。

蓝色框、红色框和红色点分别代表真值,锚框和锚点。

回归方式的不同

如图(b) RetinaNet回归的是anchor box和gt的4个偏移量。

如图(c) FCOS回归的是中心点到目标四条边的距离。

从这两种算法我们可以看出,如果选择基于anchor做位置回归,那么检测精度会受限于anchor的宽高设计,如上图第一行,如果anchor设计的过小,与gt计算IoU时会因为重叠率小于阈值而被作为负样本。造成的影响不仅包括了正样本个数的减少,还有负样本噪声的增加。

经过前人的研究可以得到这样的信息:如果在训练过程中选择的正负样本保持一致,此时无论是采用基于anchor进行回归还是基于关键点进行回归,得到的检测结果是相近的。那么在训练的过程中如何选择正负样本就成了提升检测性能的关键因素!

知乎回答一(作者本人)

作者:张士峰
链接:https://www.zhihu.com/question/359595879/answer/927861326
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

感谢楼主的提问,以前都是偷偷看各位大佬们在知乎上提问和讨论的,现在有机会来回答一下。首先想跟楼主说一下,就是问题最后的那个描述”这篇论文是否说明anchor-based的方法在未来目标检测可能要被淘汰 ?”感觉描述这篇论文不是很合适,因为这个工作主要是探索anchor-based和anchor-free的区别与联系,并没有说哪个要被淘汰。

回到正题,最近anchor-free的检测出了很多优秀的论文,不少大佬都有对anchor-based和anchor-free进行分析,其中指出过说,只铺1个anchor的RetinaNet和类似FCOS的anchor-free方法非常像,这也是我们这个工作的出发点。既然两者非常像,为什么性能存在不少的差距?为了分析导致两者性能差异的本质区别,我们首先把一些实现差异排除掉,FCOS提出或使用了几点改进,这些改进在RetinaNet中也work,因此我们把这些改进都加到了只铺1个anchor的RetinaNet中。此时的RetinaNet与FCOS还有差不多1个点的性能差距,而两者的不同仅剩正负样本的选取和回归的起点。一开始我们猜想是,这两个不同都会导致最终性能的差异,但实验结果表明,回归的起点对结果影响不大,主要是正负样本的选取导致的性能差异。所以,除了提出一些通用的改进外,FCOS还提出了一个更好的正负样本选取方式,它比RetinaNet中基于固定IoU选取正负样本要有更好的表现。

受此启发,我们就对正负样本的选取进行了一些探索,提出了一个adaptive的选取方式ATSS,在几乎没有超参的情况下,对只铺1个anchor的RetinaNet涨2.3个点,对铺多个anchor的RetinaNet涨0.8个点,对FCOS涨1.4个点(FCOS不加center sampling结果是37.8,我们的center sampling是只用了ATSS的第一步,能涨到38.6,再用ATSS剩下的步骤能涨到39.2)。虽然ATSS需要借助于铺设1个anchor来选取正样本,但无论这1个anchor铺什么比例,或铺多大尺寸,ATSS提升都挺稳定,主要是因为ATSS会根据目前所铺设的anchor,自适应地根据统计信息来选取合适的正负训练样本。

另外一点,我们发现使用ATSS后,只铺1个anchor的RetinaNet和铺3~9个anchor的RetinaNet结果基本一致。铺多个anchor的目的之一是提供更多的正样本,同时解决FCOS中提到的ambiguous samples问题。但铺多个anchor会带来两个问题,一是负样本的大量增加,二是需要同一个特征点来预测多个不同的类别。这两个问题会加剧分类的难度。我们猜想,这是在使用恰当正负样本采样策略后铺一个anchor和多个anchor性能没区别的原因。因此,铺设多个anchor还需进一步研究来发挥它的作用。

以上说的都是在one-stage的anchor-based算法和center-based的anchor-free算法中验证。知乎网友也说了有些类似的实验结果或结论,感谢知乎网友的点评以及对我们的看重,着实压力很大,后面会努力,做出更solid的解决办法。

知乎回答二

作者:王剑锋
链接:https://www.zhihu.com/question/359595879/answer/927936835
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

看到这篇paper的第一反应是比较失落,因为我们组也在做很类似的事情,但走了很多惨绝人寰的弯路。等看完code之后发现和预想的有点出入,总体上是比较遗憾和失望,下面会提到为什么。

ATSS的实际motivation大概率是来自FreeAnchor。FreeAnchor告诉了我们anchor matching(或者说label assign)这个地方是有油水的。说起来我有个同事上半年就想做label assign,但是这个环节非常不好做上限分析,就一直没有开始做,也是直到FreeAnchor出来才开始做。我对FreeAnchor的评价还不错,可惜细节比较多,一些实现方式也不太好做更深的分析。(另外吐槽一下知乎上对FreeAnchor的讨论都是什么鬼。)

类似的paper其实之前也有,最像的是PISA,虽然表现形式完全不同,本质却是非常相似,都是「对于每个ground-truth,依照某种指标取top-k个sample,再在loss上进行一下re-weight」。

有了FreeAnchor之后,挪到FCOS上做一个”FreeFCOS”好像是一个非常直接的想法,毕竟FCOS就是RetinaNet的一个简单变种而已。事实上我们组在几天之内就成功跑出了一版可以跑到39.2的FreeFCOS(简单移植,没有novelty不值得写paper),我当时还立了一个半个月内做过40的flag,但再往后就像遇到了次元壁一样无论怎么做都提不上去了。

ATSS虽然基本上照搬了FreeAnchor的matching部分,但毕竟形式上比FreeAnchor简洁太多了,总体上很清爽。只是有两处问题我觉得蛮硬伤的:

这两处问题合在一起,会导致整个方法其实根本不是adaptive的,因为不管网络训练到什么程度,对于一个ground-truth,ATSS给它match到的anchor(看起来会变但)始终都没变。因为anchor不会变,anchor和ground-truth的中心点距离和iou也就不会变,根据距离算出的每层的top-k也就不会变,threshold也是根据iou算出来的,于是最终的正样本也就不会变。哪里adaptive了呢?

真正的adaptive我觉得应该做到两点:(1) 没有anchor;(2) 也不要做其他形式的hand-crafted分层。孙剑老师曾经challenge我为什么这样是有价值的?我当时的回答是,我们有很多个项目,模型本身是一模一样的,但因为数据resolution不同,ground-truth的size不同,每个项目拿过来都要重新调anchor或者调分层参数,不仅是研究员和工程师的精力成本,也是自动化的障碍,在学术上还是更好解scale问题的阻碍;这个事,能不能训练的时候自己就学了?甚至,能不能其他一些辅助训练的threshold也自己就选好了?至少目前的detection方法还做不到。

至于ATSS的另一个贡献,即bridging the gap,我觉得这个应该算是FCOS文里就该指出来但是遗憾没有指出来的东西,如果换成更老辣的人(比如FAIR)来做FCOS,可能早就没有这个问题了。(题外话,FCOS不成熟的地方有好几处,有一部分被impr版fix了,有的现在也没有)。

还有一个问题可能值得一提,就是label assign的上限问题。由于label assign没有ground-truth,我们很难做上限分析,不知道还有多少空间可以做。关注label assign的除了FreeAnchor、PISA、ATSS之外,还有一篇与ATSS几乎同时放出来的MAL,抱歉我还没怎么看它具体怎么做的,但它的ResNet-50的结果也是39.2。虽然实现方式各有差异,但都只做到39出头。我不知道是因为我们还没有找到更好的方式,还是说label assign的空间可能已经不大了,毕竟说到底label assign也只是为了网络更好地收敛而服务的。这个需要其他人来解答了。

最开始出现的是R-CNN,如下图:

从上图可以看出其框架做了很多重复的计算,在第二步之后,如果有2k个proposals,那后面就要执行2k边,太低效。于是,出现了改进的SSP-Net,如下图:

SSP-Ne框架组合了Classification和Regression,做成单个网络,并且可以Een-to-End进行训练,速度上提高许多。但是,SSP-Net还是基于Selective Search产生proposal,之后就出现了Fast R-CNN,其是融合了R-CNN和SPP-Net的创新,并且引入多任务损失函数,使整个网络的训练和测试变得十分方便。

但是Region proposal的提取还是使用了Selective Search,目标检测时间大多消耗在这上面(大约region proposal需2~3s,而提特征分类只需0.32s),这种是无法满足实时应用,而且并没有实现真正意义上的端到端训练测试(因为region proposal使用了Selective Search先提取处来)。

于是就有了直接使用CNN产生region proposal并对其分类,这就是Faster R-CNN框架,如下图:

Faster R-CNN将proposals交给了CNN去生成,这样 Region Proposal Network(RPN)应运而生。

Faster RCNN

仔细看看Faster R-CNN框架,其实还保留了Fast R-CNN的框架,其主要就是CNN+RPN。其中RPN主要就是负责生成proposals,然后与最后一层的feature map一起使用,用ROI Pooling生成固定长度的feature vector。具体如下:

那接下来开始好好的说一下RPN和Anchor!下图是我从网络copy过来的,应该更加能理解整体的流程及内容。

在上图中,红色的3×3红框是其中一个滑窗的操作过程, 注意这里的Anchor是原图像像素空间中的,而不是feature map上的。这样的话,就可以很好去知道Anchor的意思,而且Anchor对于RPN非常重要。

现在,我们假设现在的feature map尺寸为W x H x C(13x13x256就是feature map的Width=13,Height=13和Channel=256),在feature map使用滑动窗口的操作方式,当前滑窗的中心在原像素空间的映射点就称为Anchor,并且以Anchor为中心去生成K(paper中default K=9,3个尺寸和3个缩放比例)个proposals。

在feature map上滑动一次,得到一个小网络,该网络输入是3x3x256,经过3x3x256x256的卷积,就可以得到1x1x256的低维特征向量。

然后就得到上图的两个分支。

  • Classification:经过1x1x256x18的卷积核,得到1x1x18的特征向量,分别代表9个proposals的Object的概率(是或不是);
  • Regression:经过1x1x256x36的卷积核,得到1x1x36的特征向量,分别代表9个proposals的(长宽及中心点坐标)。

注意,上面只是一个小网络,也就是一个3×3滑窗的过程及结果,在网络整体运行的过程中,要将整个feature map都要滑动一遍,最终就会得到两个损失函数:

其中就是Classification(Lcls)和Regression(Lreg)两个损失。对于边界框的回归,其是采用以下4个坐标的参数化:

综上,通过滑窗和Anchor机制就可以找到固定比例、一定大小的proposals,这样RPN就可以完美替代低效的Selective Search去产生proposals。

最终,在目标检测领域中,这个框架算是一个里程碑,值得大家学习与深入探索。最后的检测结果也是不错的。

Original: https://blog.csdn.net/m0_61899108/article/details/122893551
Author: m0_61899108
Title: 目标检测中的anchor-base与anchor-free

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/680920/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球