目标检测论文阅读:CornerNet

CornerNet: Detecting Objects as Paired Keypoints

论文链接:https://arxiv.org/abs/1808.01244
代码链接: https://github.com/umich-vl/CornerNet
ECCV 2018的paper list已经更新,想要下载的可以去这儿找。本周介绍的正是ECCV 2018上的CornerNet,这篇文章借鉴了人体关键点检测的思路来做detection,还是有些想法和创新的,不过个人更喜欢IoUnet一点,因为在我看来这篇文章的创新实际上并不是非常本质上的东西,但是借鉴其它类似问题的思路非常值得关注。

1. 背景介绍

这篇文章的Motivation我个人感觉应该是从Keypoint那边出发的,但是如果从一般的目标检测算法来出发也可以得到一些启发。
目前的检测算法主要思路还是设置大量Anchor+分配正负样本+训练的一个思路,Anchor的本质是目标的候选框,因为目标的形状和位置的多种可能性,Anchor的数量往往非常庞大,否则会出现遗漏的情况,这种情况对于one-stage的检测算法更加突出。因此会带来两个问题:

  1. 大量的Anchor中只有少部分和gt的重合比较大,可以作为正样本训练,其它都是负样本,换而言之,正负样本均衡问题,这几乎是所有检测算法都要考虑的问题,不同算法往往也会有不同的策略
  2. Anchor的设置本身也是需要超参数的(形状、个数怎么设置),在multi-scale的时候会更加明显,YOLOv2曾经用5个anchor达到了faster rcnn中9个anchor的效果,说明这方面确实也是有很多可以做的地方

基于上述两点原因,再加上keypoint问题的启发,作者就想到用关键点检测的思路来处理detection问题,只要找到top-left和Bottom-right两个点,就可以准确框出一个目标了。

作者的第一个贡献是设计了一个针对top-left和bottom-right的heatmap,找出那些最有可能是top-left和bottom-right的点,并使用一个分支输出embedding vector,帮助判断top-left与bottom-right之间的匹配关系。第二个贡献是提出了Corner Pooling,因为检测任务的变化,传统的Pooling方法并不是非常适用该网络框架,这一点我们在第二部分再详细解释。

2. 算法框架与实现细节

算法框架

算法整体结构如下图所示:
目标检测论文阅读:CornerNet_第1张图片
说下需要注意的几个地方:

  1. 基础网络也就是Backbone使用的是Hourglass网络,这也是从人体姿态估计处借用来的灵感。顾名思义,这个网络的形状非常像沙漏,网络前半部分通过下采样不断减少feature map,后面则通过上采样增大feature map,并且中间还有类似fpn那样将前后网络相加的操作。沙漏网络在关键点检测上已经证明了其有效性。
  2. 网络有两个分支,一个分支预测Top-left Corners,另一个预测Bottom-right corners
  3. 每个分支有三个线路,heatmaps预测哪些点最有可能是Corners点,embeddings主要预测每个点所属的目标,最后的offsets用于对点的位置进行修正,下面进行详细介绍

Heatmaps与Reduce penalty策略

每个Heatmaps都有C个Channels,其中C是类别数量,不含BG类。理论上讲,Heatmaps的收敛目标应该是一个binary mask,其中非零点代表是Corners,零点代表不是Corners点,但这样会带来一个问题。以下图为例:
目标检测论文阅读:CornerNet_第2张图片
绿色点是gt,橙色是检测到的corners,红色代表检测出来的框;那么,如果heatmap是binary mask,很明显红色框的结果并不好,因为corners和gt的位置并不吻合,这很明显违背我们的认知。退一步考虑,如果我此时,有一个框出了整个图片的超级错误的框,在heatmap上,它和红色框是一样的,都属于错误的框。所以,正确的思路应该是,heatmap在gt位置处的值最大,其它位置,越靠近gt值越大,换而言之,用和gt位置的距离来代替是否处于gt位置上。
围绕这个思路,作者提出了reduce penalty策略,基本思想就是构造高斯函数,中心就是gt位置,离这个中心越远衰减得越厉害,即:
这里写图片描述
怎么确定高斯函数的参数作者也给出了方法,有兴趣的可以去论文里查找。最后是heatmap这条路线的loss函数计算:
这里写图片描述
其中p是预测值,y是真实值,这个函数是在focal loss的基础上修改的来的。

Offsets

作者预测出来的featmap和原图的输入尺寸是不同的,假设下采样因子是n,那么原来的位置(x, y)到feature map上对应的位置是([x/n], [y/n]),其中[ ]代表取整操作,在remap回原图位置时候,无疑会产生一定误差,offsets路线正是在这个基础上修正位置的,收敛目标表示为:
这里写图片描述
损失函数表示为:
这里写图片描述

Embeddings

这个分支的主要作用是用来group corners,作者使用的是1维的embeddings……换而言之,给不同的目标分配不同的id,比如1,2,3……然后在预测的时候,如果top-left的corner和bottom-right的corner的embedding值特别接近,比如一个是1.2另一个是1.3,那么这两个很有可能属于一个目标;如果是1.2和2.3这样差距很大的,则一般就是两个不同的目标。要想实现这样的预测,必须做到两点:

  1. 同一个目标的两个corners预测出来的embedding值应当尽可能地接近
  2. 不同目标预测出来的embedding值应当尽可能地远
    和类内最小、类间最大的原则其实有一些相似,基于这个原因,作者设计了如下loss:
    目标检测论文阅读:CornerNet_第3张图片
    其中etk和ebk是top-left和bottom-right两个分支预测出来的embeddings,ek是两者的平均值,Lpull起到的作用就是把同一个目标的预测值拉近,而Lpush起到的作用就是把不同目标的embeddings值推远。

Corner Pooling

corner检测的原理和通常的检测不同,因此常规意义的pooling对corner检测的效果也存在一定的问题。
例如,我们常用的max pooling一般以当前位置为中心,大小是3x3的kernel,感受野自然也是以当前位置为中心的。但是corner的检测相对于这样一个方形的感受野,更关心单一方向的……以top-left为例,它更关心的是水平向右和垂直向下这两个方向上的信息,考虑到这个原因,作者提出了一种Corner Pooling,原理如下:
目标检测论文阅读:CornerNet_第4张图片
例如feature map的大小是10x10,现在的一个点是(2,1),那么top-left corner pooling就是计算(2,1)到(2,10)这条线上的最大值和(2,1)到(10,1)这条线上的最大值,并将它们进行叠加。实际计算的时候,可以通过反向计算来实现,示意图如下:
目标检测论文阅读:CornerNet_第5张图片
以上图2,1,3,0,2这一行为例,最后的2保持不变,倒数第二个是max(0,2)=2,因此得到2,2。然后倒数第三个为max(3,2)=3……依次类推。另外,作者在Backbone和最后的predict的预测结构上使用了resnet的残差结构作为基础进行更改,具体做法是改了第一个3x3卷积操作,最后的预测结构为:
目标检测论文阅读:CornerNet_第6张图片

3. 实验结果

关于训练设置这里不详细赘述,在测试的时候,会使用3x3的max pooling对heatmap进行非极大值的抑制,并取heatmap上的前100个结果,然后按照L1距离进行匹配;注意的是匹配是在每个类别之间的,不同类别或者L1距离过大的一般都会不考虑在内,作者最后的实验结果如下:
目标检测论文阅读:CornerNet_第7张图片
在single-stage方法中算是非常好的结果了,和很多two-stages方法也有一战之力。应该说这篇文章做了一件非常有意思的探索工作,尝试了检测的不同思路,也避免了大量anchor的问题。作者认为他的思路的优势是corner只关注两条边缘上的信息,而object的中心准确定位需要的信息非常多,应该也算是有一定的启发性吧。

你可能感兴趣的:(目标检测(Anchor,Based))