参考博客:https://blog.csdn.net/u014380165/article/details/83032273
目前的目标检测大多数都是基于anchor boxes(锚框)的,如faster r-cnn,yolov2,yolov3等,但这一类检测有两个缺点:
一,我们需要一大堆锚框。因为检测器需要判断锚框和真实框是否很大程度的重叠,因此需要大量的锚框。这样会导致有很多用不着的锚框,致使正负样本不均衡,减缓训练速度。
二,每个锚框都会有很多参数。当针对多尺度训练的时候,每个尺度都会使用不同的一组锚框,这样会使网络产生大量参数,如yolov3。
本文中,我们通过预测目标的左上角和右下角两个关键点来预测边界框,摒弃了锚框的思想。其次,整个网络并没有使用到预训练模型,整个训练从头开始。
网络先输出两组热图,用来代表不同种类物体边角的位置信息,一组是左上角,一组右下角。
同时网络预测嵌入向量来评价一组角点是否属于同一个目标,若属于,则嵌入向量的距离则比较小。
为了使预测的边界框更紧凑,网络预测了偏移量来调整角点的定位。
2.1 检测角点
该部分包括两个损失:
一,对于某一个角点属于c类得分的损失,使用focal loss;
对于每一个角点,有一个真实值的正定位,其他的都是负值。在训练阶段,我们减少对正定位半径内负位置的惩罚,因为会存在负值的角点位置距离真实值很近,并且预测出来的边界框与真实框重叠度很高。如下图。预测的绿色边界框左上角位置在真实框左上角点的半径范围内,并且重合度也很高。
pcij为在预测出的热图中第 ij 位置属于第c类的得分。ycij则为非标准化高斯增强的真实值热图。
二,对输出特征图中偏移量的损失,使用平滑L1。
目前多数网络使用全卷积,对原图进行32倍或多少倍降采样,预测出特征图的坐标后再反映射到原图上。比如,原图上的 (x,y)映射到特征图上是这样会丢失掉一些精度,尤其是小物体。
为了解决该问题,我们将在反映射前调整角偏移。
ok是位移量,xk,yk是k个角点的坐标信息。
对于训练,我们在ground-truth角点位置应用平滑的L1损失。
2.2 分组角点
由于一张图片中会有多个物体,网络会检测到多组左上和右下的角点。我们需要判断两个角点是否属于同一组,即同一个物体的回归框。
方法:使用人体姿态估计中的嵌入向量方法,如果左上点和右下点属于同一个回归框,那么他们之间的嵌入距离就会比较小。
etk是目标k的左上角点, ebk是目标k的右下角点。
pull损失:将角点分为一组;push损失:将角点分离。
(此部分感觉有点像类内类间损失。)
2.3 角点池化
为了确定一个焦点是否为左上角,需要水平向右看物体的上边边界,垂直向下看物体的左边边界。
对上图先确定上边界,过程是对于每一个像素点,取向右看的最大的像素点,并替换;左边界则是对于对于每一个像素点,取下看的最大的像素点,并替换。然后把每一个像素点相加得到输出结果。
预测的整个过程如下图所示。第一部分是修改过后的resnet单元,将3x3卷积改为角池化模块。首先对骨干网络的输出经过两个3x3/128卷积,在通过池化层。
最后的三个模块为3个卷积,relu,卷积预测热图,嵌入以及偏移。
首先通过7x7卷积提取特征,由原图的511x511得到128x128;
然后,经过一个骨干网络--Hourglass Network(沙漏网络),特征图的大小不变,还是原来的128x128;(文中的沙漏网络包括两个下采样上采样过程。)
对沙漏网络的输出有两个分支模块,分别表示左上角点预测分支和右下角点预测分支。每个分支模块包含一个corner pooling层和3个输出:heatmaps、embeddings和offsets。
heatmaps是输出预测角点信息。
embeddings用来对预测的corner点做group。
offsets用来对预测框做微调。