paper:https://arxiv.org/abs/1808.01244
code:https://github.com/princeton-vl/CornerNet
首先,这篇paper的代码我是没有跑通的(训练自己的数据集),但是是一篇非常具有开创性的paper,后面的centernet(object as points)等都是基于这个工作来做的,backbone用的是hourglass,讲道理,这个backbone实在是太重了,在以point为核心的one-stage检测算法中hourglass广泛应用,但实在是难以落地,不仅模型太重,难以剪枝,只能直接量化,并且这么复杂的模型量化在芯片端也许比不量化还要慢(不停的量化反量化),等等一些原因,我觉得该算法在目标检测界落地的情况比较少,不像他的下一代算法-centerNet(见我的上一篇文章),此篇博文按照paper的顺序展开写(因为我没有跑通过代码),感觉其实有很多细节没有理解到位,毕竟没有深入理解代码,因此论文尽可能的解读详细。
1、摘要:
提出一种新的目标检测方法,将单个目标的框检测变成了一对关键点检测(左上角和右下角),同时引入corner pooling帮助网络更好地定位角点。并且该模型是基于hourglass做的,可以从头开始训练,不需要预训练模型
2、介绍:
anchor-based的缺点:
1、之前重复提到的,参数量非常大,每个像素点多级预测,且每点有多个anchors;
2、训练时利用预测的bbox与anchor的IOU判定正负样本,但大多数都是easy-negative example,容易造成正负样本不均衡(focal loss改善-见我前面的博文retinanet)
3、anchor 的超参数设计,理论上来说,只要训练时间足够,模型会慢慢的学习到适合当前anchor参数的权重,但实际上,嗯 ,还是效果有差异的,非常吃超参数的定义
cornernet的设计:
利用一对角点来定义目标的位置,使用单个cnn网络来预测同一类别的所有实例的左上角热图,所有右下角热图,以及检测到的角点的embedding vector,embedding vector用于对同一目标进行grouping,整体流程如下(看上去相当简单,实际上细节理解的时候太难了,坑):
我们将一个目标定义为一对组合在一起的边界框角点。 卷积网络输出一个左上角热图和一个右下角热图,并输出每个检测到的角点的embedding vector。 训练网络用它来预测是否属于同一目标的角点
CornerNet的另一个新颖组件是corner pooling,corner pooling是一种新型的池化层,可帮助卷积网络更好地定位边界框的角。 边界框的一个角通常在对象的外部-考虑圆的情况以及图2中的示例。在这种情况下,不能根据本地证据确定角的位置。 相反,要确定像素位置是否存在左上角,我们需要朝右水平方向看物体的最上边界,并垂直看向底部底端的最左边界。 这将激励我们的corner pooling层:它包含两个要素图; 在每个像素位置,它最大池化从第一个特征映射到右侧的所有特征向量,最大池化从第二个特征映射下面的所有特征向量,然后将两个合并的结果相加。 一个例子如图3所示。
全文就这2段我最难理解,看半天,通俗讲解一下,角点通常不在物体本身,在目标之外,如图2所示,那我们怎么确定一个目标的左上角点?需要水平向右看目标的最上面边界,垂直向底看物体的最左边边界(这就是人眼定位左上角的流程),那corner pooling就利用人眼这一流程,它最大池化从第一个特征映射到右侧的所有特征向量,最大池化从第二个特征映射下面的所有特征向量,然后将两个池化结果一起添加,如图3所示( 其实这个地方真的难以理解,我看的时候边界最大,你提取特征就选最大池化,貌似也有道理,后面的某一个算法提到了这样没有考虑到中心点的特征,然后又加上了中点的特征)。
图3.Corner pooling: 对于每个通道,我们采用两个方向(红线)的最大值(红点),每个方向都来自一个单独的特征图,并将两个最大值加在一起(蓝点)。
cornetnet比anchor-based方法好的原因:
1、anchor的中心更加难以定位,它取决于目标的4个边,而角取决于2个边,更容易被定位,而且还有corner pooling提供更多的关于角点的先验信息
2、角点提供了一种更有效的方式来密集离散anchor空间,只需要用O(wh)角点来表示可能的anchor boxes。
3、CornerNet详细
3.1 概述
在cornernet中,利用一对关键点来表示物体的bbox,全卷积网络通过预测两组热图来表示不同物体类别的角点的位置,一组用于左下角,一组用于右下角。网络同时还预测每个检测到的角点的embedding vector,然后利用embedding vector来grouping,使得同一组的embedding vector距离很小,更进一步的,为了产生更加紧凑的边界框,网络还预测了偏移用来调整角的位置,最后,通过预测的heatmap、embedding vector和offsets,再使用一个简单的后处理算法来获得最终的目标框。
上图为cornernet的概述,backbone之后是两个预测模块,一个用来预测左上角,一个用来预测右上角。
3.2 检测角点
预测两组heatmap后,每组heatmap具有c个通道,c是class数量,大小为H*W,没有背景通道,每一个通道都是二进制掩码,用于表示该类别的角点位置。
对于每一个角点,理论上只有bbox中的左上角和右上角才是真正的ground-truth,其他位置都是negative example,但是,我们考虑到如下情况:
如上图所示,当绿色的预测框偏移一定位置时,与红色的标注框IOU如果小于一定的范围,绿色的框仍然可以认为是对的,则这种情况下我们对绿色框的角点可以少一些惩罚。我们通过确保绿色框的角点组成的bbox与gt的IOU>t(0.7)来确定物体的大小,然后确定角点的范围半径,给定半径以后,对半径圆内这些非标准的gt点和圆心的真实gt点分别进行惩罚(圆心当然损失为0),将真正的gt点作为圆心,利用非标准的2d高斯函数对圆心进行离散,变成2d高斯圆,其中心位于真正的gt,即为正样本,其他在高斯圆内部的点按照focal loss来惩罚,
半径的1/3.
Pcij 为预测热图中c 类位置( i , j ) 的得分,Ycij为用非标准化高斯增强的“ground-truth”heatmap。我们设计了一个局部损失(focal loss)的变体:
简单理解一下这个focal loss,α和β 是控制每个点的贡献的超参数,当距离gt附近越近的点(i,j),则Yij的值越接近于1,(1-Yij)就越小,整个otherwise情况下的损失函数值就越小,即意味着减少了正样本附近的负样本的惩罚,也可以理解为在gt附近以高斯函数离散的点(形状为高斯圆)的惩罚将被减轻,因为这些点也能够组成与背景IOU较大的bbox,实验证明减少这些位置的惩罚极大地提升了性能。除去(1-Yij),其他部分就是一个正常的focal loss。至于如何求取高斯圆的半径然后离散,请看我上一篇cenetrnet的介绍。
更进一步的,由于全卷积网络进行下采样时,图像中的位置( x , y ) 被映射到heatmap中的位置时,n是下采样的倍数,由于存在取证的问题,会丢失精度,这个极大的影响了小目标与gt的IOU,因此预测位置偏移,以调整角的位置,然后将结果重新映射回输入法分辨率:
Xk,Yk是角点的坐标,Ok是偏移量,特别的,所有类别的左上角共享一组偏移,右上角共享另一组偏移。在训练时,在gt的角点处,我们是用平滑的L1损失:
3.3 分组角点
简单来说就是同一个目标的左上角和右上角的grouping过程,如果他们来自同一组,则他们的embedding vector的距离应该很小,embedding vector的实际值不重要,只需要关注embedding vector之间的距离。本文使用的是1-D的embeding vector。在训练时,损失函数如下:
etk代表目标k左上角的embeding,ebk代表右下角的embeding,L_pull函数用于组合角点,L_push函数用于分离角点,ek为etk和ebk的平均值,我们在所有实验中将Δ设为1,与偏移类似,尽在gt焦点位置应用损失 。
3.4 corner pooling
如上文的figure3所示,如前面解释的,根据人眼定位的角点的流程,我们提出corner pooling通过编码显式的先验知识来更好的定位角点。
假设判断(i,j)是否为左上角的点,Ft和Fl为两个输入corner pooling的feature maps,Ftij和Flij分别为(i,j)位置中的ft和fl的特征向量,对于H*W的feature-map,corner pooling首先最大池化Ft中在(i,j)与(W,j)之间所有的特征向量,使之成为特征向量Lij,最后将Tij和Lij加在一起,这个计算可以用以下公式表示:
这个地方我们要稍微白话一下,啥叫从左往右扫描,简单来说,跟我们常见的max-pool完全不一致,本文的最大池化扫描意思是,从右往左,首先将自己设为最大值,遇到比自己小的就将小值替换成最大,遇到比自己大的就不变,同时最大值变更为新的最大值,然后继续往下走,遇到比大值小的就把小值替换,如果遇到比大值更大,则保留这个大值,同时替换最大值为这个大值,持续扫描,效果图见上图figure6,更简单的来说就是逐元素比较大小,比较完就替换最值。
corner pooling的结果将在预测模块中使用,用于预测featmap、embeding vector和offsets。
预测模块的详细结构图如下图所示:
预测模块的结构如上图所示,第一部分是残差模块的修改版本,将第一个3*3的卷积替换成corner pooling,corner pooling的结构是通过2个3*3的卷积和来处理backbone的feature-map,然后接一个corner pool层,将max pooled然后相加的feature map送到3*3*256的conv-BN层中,同时增加一个shortcut,修正后的残差模块再接一个3*3*256的卷积,然后再利用3个conv-relu模块用于预测heatmap(H*W*C)、embedings,offsets。
3.5 hourglass模块
由人体姿态引入的backbone,由2个沙漏组成,没有使用最大池化,而是使用步长为2来降低分辨率,本文减少了5倍的分辨率,但是逐次增加channels至[256,384,384,384,512],。。。。。这个地方不写了,hourglass我觉得是目标检测里面最不可能用到的网络,这结构有毒:
注意:本文只是用了最后一层来进行预测,centernet与cornernet都是一样的,因为他们都是利用backbone提取heatmap,然后找峰值点,再回归参数,首先下采样次数不大,保留了更多的细节特征,然后基于像素点当做positive example,没有bbox那么容易丢失目标或者丢失特征。
4、训练细节
1、图像增强:随机水平翻转、随机缩放、随机裁剪和随机色彩抖动,其中包括调整图像的亮度,饱和度和对比度
2、输入分辨率:512*512 -> 输出特征图 128*128
3、损失函数:
将γ 设置为1
4、测试细节
1、左上角和右下角嵌入之间的L1距离。距离大于0.5或包含不同类别的角点对将被剔除。 左上角和右下角的平均得分用作检测分数。
2、TITIAN 244ms 1张
5、SOTA数据对比
参考: