CenterNet: Objects as Points论文解读 目标检测、语义分割论文及代码

目录

  • 概论
  • 损失函数
    • 1 Focal Loss如何使用
    • 2 中心的偏置损失
      • 为什么用绝对像素?
    • 3 目标wh的损失函数
    • 读完之后待解决问题
        • 5小节training时固定输入512x512,test时保持原分辨率,pading 0
        • two-stage中一个目标输出多个大IOU的框因而需要NMS,以heatmap热度图作为目标,难道一个目标不会输出多个峰值嘛?如果多个峰值不是也需要NMS嘛?

论文https://arxiv.org/pdf/1904.07850.pdf
代码https://github.com/xingyizhou/CenterNet

概论

2019年有两个CenterNet网络,都是在目标检测领域,Anchor-free方向有较好效果。其中个人观察本篇更受欢迎一些。因而写下论文梗概及代码解读。
一般two-stage检测器,先给出一些region proposals,分类回归,因而效率较低。 Objects as Points把目标当做一个关键点来估计,再回归到其他属性。 检测任务回归到包围框,还可以跟姿态估计,3D位置等任务。且不需要NMS。模型端到端可微,又快又准。COCO上快的28.1AP,142fps,慢的45.1AP,1.4fps。COCO上姿态估计也达到GPU实时。

数据增强:flip , random scaling , cropping , color jittering颜色抖动

模型又快又准,还可通用语检测,姿态估计,3D检测,模型有三个创新点:

  1. 仅使用目标中心点训练,(也算一个anchor吧)无须two-stage的二分类阈值
  2. 一个目标仅有一个正样本 , 无须NMS
  3. 有更大的输出分辨率,因而无须多尺度anchor(下采样因子是4,SSD是16)

第一部分,使用backbone得到heatmap热度图
使用的Resnet,DLA,Hourglass三个不同规模的网络都是**编码解码(encoder-decoder)**的结构。
在模型的最后都是加了三个网络构造来输出预测值,默认是80个类、2个预测的中心点坐标、2个中心点的偏置。
用官方的源码(使用Pytorch)来表示一下最后三层,其中hm为heatmap、wh为对应中心点的width和height、reg为偏置量,这些值在后文中会有讲述。

(hm): Sequential(
(0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace)
(2): Conv2d(64, 80, kernel_size=(1, 1), stride=(1, 1))
)
(wh): Sequential(
(0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace)
(2): Conv2d(64, 2, kernel_size=(1, 1), stride=(1, 1))
)
(reg): Sequential(
(0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace)
(2): Conv2d(64, 2, kernel_size=(1, 1), stride=(1, 1))
)

损失函数

1 Focal Loss如何使用

预测中心点的那部分loss(系统一共三个loss)
CenterNet: Objects as Points论文解读 目标检测、语义分割论文及代码_第1张图片
Y= 1时,(1-Y ^)是区分难易样本,Y ^ 越大,预测的越准,这一项就越小。
otherwise时,
A部分: Y ^ α 应该预测为0 ,预测越大说明越不对,损失函数就越大
B:部分 (1-Y )β 对应周围位置,和中心点位置越近的点 Y越接近1 , 这一项越接近0.即损失函数中间位置小,从正确位置向外越来越大
otherwise的两部分如何协同:
情况1:距离中心点越近,Y接近1(如0.9)预测出这个点接近0.99,但是实际应该为0 ,用A惩罚一下,加大其loss。但由于距离很近了预测错很正常,用B减小其loss,使模型别纠结在这儿了,二者有一个trade-off
情况2:距离中心点较远。Y接近0,如0.1,如果预测出来接近1则非常不对,用A惩罚,加大loss,如果预测出来接近0则比较对,A就会减小loss。既然比较远了,B会加大所占loss。相当于处理正负样本的不平衡
B主要处理正负样本不平衡(正样本只有一个,其他全是负样本)
(以上说的增大,减小loss是相对而言的,乘以一个小数,绝对数值肯定变小,5 x 0.3变成了1.5 ,但是在都会乘以小数的情况下,系数变为0.001与系数变为0.7相比,前者0.001算是减小loss;后者0.7算是不那么过分减小loss,也就是上文指的,增大loss,增大的是那个位置的loss相对大小)

2 中心的偏置损失

这块TM用的是像素绝对值作为loss,不是比例
R=4使得512变128,量化肯定会带来损失。这块也需要回归一个参数(整个目标回归一个共享的x,y,即便是姿态估计N个点也回归一个共享的x,y)
local offset
L o f f = 1 N ∑ p ∣ O ^ p ~ − ( p R − p ~ ) ∣ L_{o f f}=\frac{1}{N} \sum_{p}\left|\hat{O}_{\tilde{p}}-\left(\frac{p}{R}-\tilde{p}\right)\right| Loff=N1pO^p~(Rpp~)
O是我们预测出来的, ( p R − p ~ ) \left(\frac{p}{R}-\tilde{p}\right) (Rpp~) , 是训练过程提前算出来的
官方代码

# ct 即 center point reg是偏置回归数组,存放每个中心点的偏置值 k是当前图中第k个目标
reg[k] = ct - ct_int
# 实际例子为
# [98.97667 2.3566666] - [98  2] = [0.97667, 0.3566666]

不用偏置损失也行,但是损失一些精度。

为什么用绝对像素?

个人暂时的解释我感觉可能是:既然整个图像尺寸比较固定512 , 那么像素值和比例差别就不是很大了,而且,整个目标的偏移量是统一的。

3 目标wh的损失函数

也用像素差值来预测,而不是比例
回归到 s k = ( x 2 ( k ) − x 1 ( k ) , y 2 ( k ) − y 1 ( k ) ) s_{k}=\left(x_{2}^{(k)}-x_{1}^{(k)}, y_{2}^{(k)}-y_{1}^{(k)}\right) sk=(x2(k)x1(k),y2(k)y1(k))
预测值 S ^ ∈ R W ′ R × H R × 2 \hat{S} \in \mathcal{R} \frac{W^{\prime}}{R} \times \frac{H}{R} \times 2 S^RRW×RH×2

L s i z e = 1 N ∑ k = 1 N ∣ S ^ p k − s k ∣ L_{s i z e}=\frac{1}{N} \sum_{k=1}^{N}\left|\hat{S} p_{k}-s_{k}\right| Lsize=N1k=1NS^pksk
综合三个损失函数:
L d e t = L k + λ s i z e L s i z e + λ o f f L o f f L_{d e t}=L_{k}+\lambda_{s i z e} L_{s i z e}+\lambda_{o f f} L_{o f f} Ldet=Lk+λsizeLsize+λoffLoff
入size = 0.1 入off=1
论文中所使用的backbone都有三个head layer,分别产生[1, C ,128,128]、[1,2,128,128]、[1,2,128,128],也就是每个坐标点产生C+4个数据,分别是类别以及、长宽、以及偏置。

读完之后待解决问题

5小节training时固定输入512x512,test时保持原分辨率,pading 0

具体如何固定的呢? crop裁剪?还是resize?
答:
长边resize到512,短边padding 0

two-stage中一个目标输出多个大IOU的框因而需要NMS,以heatmap热度图作为目标,难道一个目标不会输出多个峰值嘛?如果多个峰值不是也需要NMS嘛?

模型通过FocalLoss就能保证一个目标只输出一个峰值嘛? 我在github上提了issue,不过我看issue好久没人回答了,只能坐等了。
https://github.com/xingyizhou/CenterNet/issues/716
有解答的小伙伴可以在github评论解答
————————————
作者在github里部分回应了问题,他说个别大目标里确实存在一个目标预测出多个框的情况,因而加上NMS之后可以提高0.5mAP . 然后作者就没说别的了
但总的来说正常大部分情况为什么真的就能一个目标预测出一个框,我个人觉得最主要功劳就是Focal Loss类似的损失函数,对groundTruth周围的点有抑制作用,且在最终那个比较小的feature map上能做到8邻域极值,确实也就是该目标了。尺寸比较固定,512或者384,因而合适的尺寸上得到合适的结果。

少量关键代码细节:
src/lib/models/decode.py文件中
inference时模型输出结果是多维数据,要通过centerface_decode函数进行解码,得出检测物体具体位置,或者关键点检测具体坐标
在multi_pose.py中调用:

dets = centerface_decode(
        output['hm'], output['wh'], output['landmarks'],
        reg=reg, K=self.opt.K)

其中output是model输出,一个类别的检测+关键点检测时维度是

output['hm'].shape:torch.Size([1, 1, 96, 96])   
output['hm_offset'].shape:torch.Size([1, 2, 96, 96])  
output['wh']:torch.Size([1, 2, 96, 96])
...等
两个类别时
output['hm'].shape:torch.Size([1, 2, 96, 96])   (分别是batch,catagery,width,height)

然后就进到centerface_decode函数中
首先将hm即heatmap进行python版本的NMS

def _nms(heat, kernel=3):
    # python nms,
    pad = (kernel - 1) // 2

    hmax = nn.functional.max_pool2d(
        heat, (kernel, kernel), stride=1, padding=pad)
    keep = (hmax == heat).float()
    # print("nms: heat:{}   keep{}".format(heat.shape, len(keep[0]))) #heat[1, 2, 96, 96]  keep 1,2...
    return heat * keep

用一个max_pool代替了传统NMS,但是并不使得map变小(且有padding),只是max pool后在原图上保留8邻域最大值
然后再_topk函数在每个heatmap上(即每个类别中取topK),看作者最后基本都是top100(真的需要这么多吗,一般前5取个top40不好吗,有时间再试了,作者我信你100)

CornerNet由于只关注了边缘信息,因而,虚检较多.
而CenterNer关注中心点特征,无须NMS

参考资料
全文翻译比较精致的一个网站https://blog.csdn.net/weixin_42464187/article/details/105198771

你可能感兴趣的:(目标检测,深度学习,论文翻译笔记)