目标检测中的Anchor Free方法(一)
最近大致梳理了下最近一些Anchor Free方法的发展脉络,不考虑早期的YOLO和DenseBox等算法的话,SOTA的应该是18年CVPR提出的CornerNet,而进入2019年之后,Anchor Free方法颇有点井喷的感觉。今天将总结一下CornerNet/CenterNet/ExtremeNet这一基于keypoint启发的Anchor Free思路,而FCOS/FSAF/FoveaBox这一完全不同的Anchor Free会放在下次,总结不会涉及太多细节,主要介绍一些Motivation和整体网络思想,细节将在之后具体谈论文的时候给出介绍。
1. 从Anchor Based方法谈起
目前主流的目标检测算法,包括多阶段的各种RCNN和单阶段的SSD、RetinaNet上都是基于Anchor来做的。Anchor的本质是候选框,在设计了不同尺度和比例的候选框后,DNN学习如何将这些候选框进行分类:是否包含object和包含什么类别的object,对于postive的anchor会学习如何将其回归到正确的位置。它扮演的角色和传统检测算法中的滑动窗口等机制比较类似。但是,这种设计思路有很多问题:
- 大部分object是不规则的,所以Bounding Box涵盖了大量非object的区域,从而引入比较多的干扰
- Anchor的设置需要手动去设计,对不同数据集也需要不同的设计,相当麻烦,也不符合DNN的设计思想
- Anchor的匹配机制使得极端尺度(特别大和特别小的object)被匹配到的频率相对于大小适中的object被匹配到的频率更低,DNN在学习的时候不太容易学习好这些极端样本
- Anchor的庞大数量使得存在严重的不平衡问题,这里就涉及到一个采样的过程,实际上,类似于Focal loss的策略并不稳定,而且采样中有很多坑,今年的Libra R-CNN有个改进点就是采样时候的iou是不平衡的,实际上这种平衡广泛存在,例如不同的类别、尺度等等,有着很多隐藏问题
基于上述原因,很多人做出了改进,提出了Anchor Free的方法
2. 基于Keypoint的解决方案
CornerNet
抛弃Anchor之后,一个比较核心的问题是怎么描述Box,这方面CornerNet提出了一个比较有意思的思路,就是将Box转化为关键点描述,即用box左上角和右下角两个点去确定一个box,将问题转化为对top-left和bottom-right两个点的检测与匹配问题。
关于CornerNet的详细原理,可以查看我之前的博客,这里只介绍大概:
- 基础网络也就是Backbone使用的是Hourglass网络,这也是从人体姿态估计处借用来的灵感。这是一个在keypoint检测中非常流行的骨干网络,不熟悉的同学可以去了解下
- 关于输出,网络有两个分支,一个分支预测Top-left Corners,另一个预测Bottom-right corners
每个分支又有三个子分支,heatmaps输出的是feature map上每个点可能是Corners点的概率、预测哪些点最有可能是Corners点;embeddings输出的是每个位置属于某个object的概率,例如如果feature map上两个点分别是0.9和1.1,它们可能都属于object1,如果是1.7和2.2,可能都属于object2,这个分支主要用于分别在heatmaps上提去出了可能的top-left和bottom-right对它们进行匹配;最后的offsets用于对点的位置进行修正,因为由于下采样率的存在,heatmaps上的(x,y)映射回原图都是(kx,ky),k是下采样率,这就有一定的偏差,这个分支预测的是映射回(kx,ky)后,还要做怎么样的偏移,从而让位置更精准
我们可以发现,实际上heatmaps和offset解决的是keypoint点在哪里的问题,这两个子分支在后面的两个网络中也有用到;而embeddings分支解决的是找到点后,怎么把属于同一个Object的点从候选里找出来的问题
CenterNet
CenterNet的Motivation其实很简单:CornerNet只能提供边缘信息,实际上对于obj来说,最有辨识度的信息应该是它们内部的区域。过于关注边缘很容易引入大量的误检和错检。CenterNet增加了对中心点的检测,来帮助筛选候选框。
CenterNet同样有top-left和bottom-right两条分支,而且和之前的CornerNet是相同的,它的网络的创新点在于,新增了一条没有embeddings的分支,用于预测feature map上每个位置是中心点的概率。那么,在找出中心点以后要怎么用呢?作者的思路是找出匹配的top-left和bottom-right之后,按照下图所示,把box画成3x3个格子(如果box比较大可以划分成5x5的),最中间的格子就被认为是中心区域。然后根据新增的预测center的分支找出来的中心点,看中心区域里面有没有中心点,如果有就检测成功,否则就失败;这一思路可以有力地筛去误检
ExtremeNet
ExtremeNet的Motivation似乎来源于一篇和标注相关的文章,它的观点是,CornerNet的描述方式本质上还是画框,是box的另一种描述形式,没有改善box引入了大量干扰的问题;而且Corner点基本在Obj外,实际上这样检测效果是不好的,所以它采用了另一种点描述方式(top-most,bottom-most,left-most,right-most,center),如下图所示,最上、最下、最左和最右的四个点提供了另一种描述box的方法,而补充的center点可以帮助判断box的真实性:
剩下就没什么好说的了,检测点的思路基本和Corner相同,只不过extremenet检测的点不同,而匹配方法的话,extrmeNet和centernet有点类似,但是它是没有embedding分支的,组合点的时候用的是穷举加center点辅助判断的方式,具体来说,从四张heatmaps选出所有候选点后,采用穷举而不是embedding的方法,对于任意一组点,也是计算它们的中心,然后到center的heatmaps上看中心位置的响应值是否大于阈值,具体步骤如下所示: