当前位置: 代码迷 >> 综合 >> ECCV2018 | 论文阅读CornerNet: Detecting Objects as Paired Keypoints
  详细解决方案

ECCV2018 | 论文阅读CornerNet: Detecting Objects as Paired Keypoints

热度:1   发布时间:2023-12-06 01:08:35.0

转载于:https://blog.csdn.net/LLyj_/article/details/88900615
CornerNet论文阅读——CornerNet: Detecting Objects as Paired Keypoints

  • 前言
  • 一、背景介绍
  • 二、CornerNet算法流程
      • Corner Pooling
      • 为什么要Corner Pooling
  • 三、损失函数
      • Headmaps的损失
      • Embeddings的损失
      • Offsets的损失
  • 四、实验
  • 五、总结
  • 六、References

前言

论文地址:https://arxiv.org/abs/1808.01244

开源代码:https://github.com/umich-vl/CornerNet

CornerNet配置、训练与测试:https://blog.csdn.net/LLyj_/article/details/88900547

笔者最近一直在学习目标检测的相关内容,借此平台总结所学过的知识,当然,也借鉴过很多大佬的博客等,希望有错误的地方大家指出,互相学习。若读者还想学习目标检测经典算法Faster R-CNN,也可以看看这篇博客。

一、背景介绍

这部分内容大致分为两块,一块是简述当今主流目标检测算法的门派,另一部分是简述这篇文章的思路来源,也就是本文的idea。

  1. 当今的目标检测算法大多都是基于深度学习模型的,大致可以分为两大门派,一个叫做One-Stage系列,另一个叫做Two-Stage系列Two-Stage系列顾名思义就是两步走:是先由算法生成一系列作为样本的候选框(Region Proposal),再通过卷积神经网络对候选框进行分类回归,典型代表有R-CNN系列;而One-Stage系列则不用产生候选框,直接将目标边框定位的问题转化为回归问题处理,所以他叫一步走,典型的代表有YOLO系列、SSD系列。正是由于两种方法的差异,在性能上也有不同,前者在检测准确率上占优,后者在算法速度上占优。

  2. 上述所讲的两个门派中的一些算法,都用到了anchor这个概念,但是本文的作者认为使用anchor来做目标检测有缺点:anchor的数量太大,参数太多,也就是anchor的设置太讲究了,所以作者就发出了质问,难道一定要用anchor来做目标检测吗??这是作者的第一个思路来源。第二个思路来源是来自一篇姿态估计的文章,这篇文章的作者也是密歇根大学的,基于CNN的2D多人姿态估计方法,通常有2个思路:Top-Down framework:就是先进行行人检测,得到边界框,然后在每一个边界框中检测人体关键点,连接成每个人的姿态,代表算法RMPE(alphapose);Bottom-Up framework:就是先对整个图片进行每个人体关键点部件的检测,再将检测到的人体部位拼接成每个人的姿态,代表方法就是openpose。

    ? faster rcnn中使用到的anchor

    所以作者基于以上的两个思路,就有了本文的诞生:CornerNet:
    Detecting Objects as Paired Keypoints,重在Keypoints,作者把目标检测问题当作关键点检测问题来解决,检测目标的两个关键点——左上角(Top-left)和右下角( Bottom-right ),有了两个点之后,就能确定框了。

二、CornerNet算法流程

这块内容就是详细的讲述整个算法,同时会讲解难理解的部分模块。

首先看下整个算法的一个流程:如下图所示:

输入图片经过Hourglass主干网络后,得到特征图,然后将该特征图作为两个Prediction模块的输入,分别是Top-left corners和Bottom-right corners。在每个预测模块里面,先经过Corner Pooling,然后输出Heatmaps, Embeddings, Offsets三个分支。heatmaps预测哪些点最有可能是Corners点,embeddings的作用是分清哪些点是一组,最后的offsets用于对点的位置进行修正,因为原图到特征图分辨率已经降低了。

知道整个网络的大体流程,接下来就要从输入到输出,详细的抠细节,一步一步的理清楚:如下图:

原始图片的大小为511×511×3,但这并不是主干网络的输入,主干网络的输入是128×128×256,为什么呢?因为作者是先将512的原图进行缩小四倍,缩小四倍用的操作是先用7×7的卷积核卷积,并且步长为2,通道数为128,这样就缩小两倍了,还有两倍是用了一个残差块,并且步长为2,通道数为256.所以,主干网络真正的的输入是128×128×256,主干网络的输出是128×128×512,为什么分辨率没有变化呢?因为这个主干网络叫做沙漏网络,样子像沙漏,他是先下采样后又上采样,连续堆叠了两个这样的沙漏,过程中经过了特征融合等等,这里总共用了104层,有兴趣的同学看这里:Hourglass,所以,从输入128×128×256,到主干网络的输出就是128×128×512。

主干网络出来后,面对的就是两个Module,一个用于预测左上角点,一个用于预测右下角点。左上角的模块长这样(右下角的类似,所以下面只分析左上角那个):

这里有三幅图,都是描述左上角模块的,区别在于越来越精细,所以我们直接看下面这幅最详细的图,如下图:

首先我们再来清晰的确认下这个模块的作用:就是它需要预测左上角那个点的位置,它属于哪个类别,以及预测位置的偏移量。

过程是这样的:从主干网络出来的特征图先做了一个叫做Corner Pooling的操作(后面细节会具体讲),Corner Pooling出来后的特征图再与Backbone的特征图做融合。最终分为3个分支,分别输出Heatmaps,Embeddings,offsets。BN(Batch
Normalization)也属于网络的一层,作用是加快网络学习速率。

最后就能得到三个输出,如下图:

  • Heatmaps:128×128×80×2,128是特征图尺寸,80为coco数据集的类别,不含背景,2代表top-left和bottom-right两个。这个特征图的每个通道都是一个binary mask ,表示该点是角点的分数。

  • Embeddings:128×128×80×2,128是特征图尺寸,80为coco数据集的类别,不含背景,2代表top-left和bottom-right两个。

  • Offsets:128×128×2,128是特征图尺寸,所有类别共用一个偏移量,2代表x, y 两个偏移值。

    所以从最初的511×511×3的原图输入,到最后的三个输出就如上所述,接下来把上述没讲的细节全部理清楚:

  1. Corner Pooling

    Corner Pooling是本文提出的一种新的池化方法,不同于寻常的最大池化和平均池化,他的做法是:

    输入:主干网络输出的特征图

    过程:先对特征图做水平方向从右向左的最大池化,得到特征图,之后在做从下到上的最大池化,得到特征图,最后将这两个特征图的每个像素值直接相加(从右向左、从下到上是针对Top-Left Corner的,Bottom-Right Corner是从左向右、从上到下)

    输出:经过Corner Pooling输出后的特征图

  2. 为什么要Corner Pooling

    因为CornerNet是预测左上角和右下角两个角点,但是这两个角点在不同目标上没有相同规律可循,如果采用普通池化操作,那么在训练预测角点支路时会比较困难。考虑到左上角角点的右边有目标顶端的特征信息(第一张图的头顶),左上角角点的下边有目标左侧的特征信息(第一张图的手),因此如果左上角角点经过池化操作后能有这两个信息,那么就有利于该点的预测,这就有了corner pooling。总之就是从左上角点的角度出发:左上角角点的右边有目标顶端的特征信息,左上角角点的下边有目标左侧的特征信息。

三、损失函数

总体的损失函数如下图所示,三个输出分别对应三部分损失,每部分损失有着对应的权重。接下来分别讲述每一块的损失。

  1. Headmaps的损失

    Heatmaps也就是预测角点的位置。整体上是对focal loss的改进,具体如下图:

    几个参数的含义:pcij表示预测的heatmaps在第c个通道(类别c)的(i,j)位置的值,ycij表示对应位置的ground truth。N是图片中目标的总数。ycij=1时候的损失函数容易理解,就是focal loss,α参数用来控制难易分类样本的损失权重;ycij等于其他值时表示(i,j)点不是类别c的目标顶点,照理说此时ycij应该是0(大部分算法都是这样处理的),但是这里ycij不是0,而是用基于ground truth顶点的高斯分布计算得到,因此距离ground truth比较近的(i,j)点的ycij值接近1,这部分通过β参数控制权重,这是和focal loss的差别。

    为什么对不同的负样本点用不同权重的损失函数呢?

    因为正样本点附近的点虽然是负样本,但是他们生成的box是能够有效覆盖ground truth框的一部分。红色实线框是ground truth,绿色虚线是一个预测框,可以看出这个预测框的两个角点和ground truth并不重合,但是该预测框基本框住了目标,因此是有用的预测框,所以要有一定权重的损失返回,这就是为什么要对不同负样本点的损失函数采取不同权重值的原因。圆圈内的点的数值是以圆心往外呈二维的高斯分布。圆的半径是根据圆圈范围内的对角点生成的bounding box和ground-truth的IoU>t,论文中设置t=0.7,所以这个半径是根据不同物体不同,而不是定死的。

  2. Embeddings的损失

    Embeddings的作用就是配对,将左上角点和右下角点准确配对。简而言之就是基于不同角点的embedding vector之间的距离找到每个目标的一对角点,如果一个左上角角点和一个右下角角点属于同一个目标,那么二者的embedding vector之间的距离应该很小。公式如下图:

    具体来讲,embedding这部分的训练是通过两个损失函数实现的,etk表示属于k类目标的左上角角点的embedding vector,ebk表示属于k类目标的右下角角点的embedding vector,ek表示etk和ebk的均值。公式4用来缩小属于同一个目标(k类目标)的两个角点的embedding vector(etk和ebk)距离,公式5用来扩大不属于同一个目标的两个角点的embedding vector距离。模型训练Lpull损失函数使同一目标的顶点进行分组,Lpush损失函数用于分离不同目标的顶点。

  3. Offsets的损失

    这个值和目标检测算法中预测的offset类似却完全不一样,说类似是因为都是偏置信息,说不一样是因为在目标检测算法中预测的offset是表示预测框和anchor之间的偏置,而**这里的offset是表示在取整计算时丢失的精度信息。**在卷积神经网络中存在着下采样层,这样从原始的图像输入到最后的heatmap产生的这个过程会累计误差,特别是在对一些小目标的物体进行检测的时候,这样的误差就无法接受了,因而文章才引入了偏移修正来修正它。也就是下图的公式:

四、实验

  1. 第一个实验是验证了Corner Pooling的作用:

    可以看出Corner Pooling能提升准确率,尤其是有利于大中型目标

  2. 第二个实验是对减少对负样本惩罚做的实验:

    结果:基于物体半径>固定半径>没有惩罚;有利于大中型目标

  3. 第三个实验是对文章创新点的验证:

  4. 最后一个实验是和state of the art的比较:

五、总结

  1. CornerNet思路新颖、避免了大量anchor的问题
  2. Hourglass Network耗时较长
  3. 文章的思路是自来姿态估计,从侧面说明了知识宽度的重要性。

六、References

  • https://zhuanlan.zhihu.com/p/53407590
  • https://blog.csdn.net/u014380165/article/details/83032273
  相关解决方案