最近在预研一些anchor-free算法,想要把anchor给Free掉,我们总得先知道什么是anchor吧,毕竟知己知彼,百战不殆。
1.Anchor是啥?
anchor字面意思是锚,是个把船固定的东东(上图),anchor在计算机视觉中有锚点或锚框,目标检测中常出现的anchor box是锚框,表示固定的参考框。
目标检测是"在哪里有什么"的任务,在这个任务中,目标的类别不确定、数量不确定、位置不确定、尺度不确定。传统非深度学习方法和早期深度学习方法,都要金字塔多尺度+遍历滑窗的方式,逐尺度逐位置判断"这个尺度的这个位置处有没有认识的目标",这种穷举的方法非常低效。
最近SOTA的目标检测方法几乎都用了anchor技术。首先预设一组不同尺度不同位置的anchor,覆盖几乎所有位置和尺度,每个anchor负责检测与其交并比大于阈值 (训练预设值,常用0.5或0.7) 的目标,anchor技术将问题转换为"这个固定参考框中有没有认识的目标,目标框偏离参考框多远",不再需要多尺度遍历滑窗,真正实现了又好又快,如在Faster R-CNN和SSD两大主流目标检测框架及扩展算法中anchor都是重要部分。
YOLOV1作为Anchor-Free的鼻祖之一,但是作者在v2版本就替换为anchor方法;”真是刺鸡“,最近检测的方向返璞归真,又往Anchor-Free方向发展?我在YOLOv3中加入了YOLOv1的思想,实现Anchor-Free,发现效果没有下降却略有提升,这个激发了我对Anchor的一些思考。
anchor的思想有点近似SPP(spatial pyramid pooling)思想的逆向。而SPP本身是做什么的呢,就是将不同尺寸的输入resize成为相同尺寸的输出。所以SPP的逆向就是,将相同尺寸的输出,倒推得到不同尺寸的输入。首先明确anchor的位置。anchor是在原图上的区域,而不是在特征图上(也就是特征图上一个点可以对应到原图上一个n*n的区域)
但是!但是!但是!这种说法是有瑕疵的!
原因不难理解,anchor的设置,导致其在图像中对应的尺寸和长宽比例是各种各样的,有的甚至还超过了滑动窗口的 3x3 输入的感受野的范围。如果说一块 feature map 通过网络的学习,只关注感受野内某一块区域的信息,这个是合理的;而不是像SPP逆向说的那样,我们能从9块不同区域得到特征!anchor 可能比感受野大,也可能比感受野小,如果 anchor 比感受野大,就相当于只看到了我关心的区域(anchor)的一部分(感受野),通过部分判断整体,如果比感受野小,那就是我知道比我关心的区域更大的区域的信息,判断其中我关心的区域是不是物体。(这里说的是Faster—RCNN里面的anchor)
Anchor的作用:
上文说的是通过RPN网络中设置的Anchor,现在检测研究的主流方向主要在one—stage方法(毕竟我们要快快快)。one-stage里面设置anchor的方式可能与上文的不一样,但是我们只需要了解Anchor的意义就能举一反三啦。
anchor主要有两个作用:1、anchor作为回归任务中的初始框,这样网络就只需要学习初始框和GT之间的坐标偏移量和高宽缩放量,从而简化网络的回归任务。可以解决GT的平移问题,我觉得这个是anchor最大的作用,如果不用anchor而直接预测GT的绝对中心坐标和绝对高宽,或者直接预测GT的绝对左上角坐标和右下角坐标,我觉得是学不出来的,比如说,图片中有两个在不同位置,但是却具有相同类别相同高宽的GT,由于卷积是是共享权重的,所以卷积过后这两个GT对应的卷积输出应该是相同的,也就是说从这两个GT提取的特征应该是相同的,但是如果根据这两个相同的特征向量去学习不同的目标,那么就矛盾了,这样就无法学习了。2.有了 anchor,就可以把不同尺寸的目标分配到对应的 anchor 上,这样对应 anchor的网络权值就仅仅负责一个比较小的目标尺寸范围(几个值就能代表原图上的一个区域),同时学习过程中,是显式的通过不同的分支、路径来传递不同尺寸目标的loss,让网络更加符合“逻辑”的得到训练。
综上所述:anchor作用无非两点:容易是模型快速收敛,容易找到目标大小和对应的feature map。anchor本身并不会参与到网络的运算中去,影响的只会是classification和bbox regression分支的target(训练阶段)和怎样decode box(测试阶段)。换句话说,网络其实预测的是相对于anchor的offset,只有在最终从offset转换到bbox时,才会使用。这样的想法也很自然被各种One stage方法所吸收,将achor几乎成为标配!
anchor的作用非常非常神奇,在网络运算过程中它是不存在的,但是它就像一张无形的手
Anchor的思考:
(1)Anchor的匹配
目标在那个anchor是简单粗暴的,按照谁的IOU大就归谁的方法划分.而且 anchor 本身的尺寸、比例也是人工指定的,虽然与不同level的featuremap有一定的关系,但并没有和网络结构的设计有良好的耦合(虽然 anchor可以通过数据集的聚类来获得(YOLO),但是这也只是单方面的与数据集有了耦合),实际中往往一个目标适合两个或多个anchor,是不是可以用一种更加平滑的方法来加权,而非简单粗暴的0-1选择。
(2)Anchor的放置
目前FPN架构在检测网络模型中使用的很多,anchor的放置位置也需要思考。大家广泛认为网络深层因为感受野较大,通常用来检测大物体(放大anchor);浅层感受野较小,所以通常用来检测小物体(放小anchor),anchor的生成是根据feature map不同而定义的。在anchor match gt阶段,gt与anchor匹配,确定gt归属于哪些anchor,这个过程隐式的决定了gt会由哪层feature map负责预测。不管是生成anchor还是gt match 过程,都是由size这个变量决定,虽然我们会设定先验的规则来选择最好的feature map,但存在的问题是,仅仅利用size来决定哪些feature map来检测物体是一种不精确的做法。如下图所示,60x60大小的car和50x50大小的car被分在了不同feature map,50x50和40x40的被分在了同一级feature map,咱也不知道,这样好不好,那么何不让模型自动学习选择合适的feature 去做预测呢?(CVPR2019 FSAF针对这一问题)
目前的Anchor-Free算法很多就是不用锚框改成锚点了,个人感觉就是换了个形式的anchor。不管怎么说,期待效果吧,毕竟anchor用了很多年也需要换换了。