CornerNet Detecting Objects as paired keypoints
(一)Title
- CornerNet: Detecting Objects as Paired Keypoints论文翻译
- CornerNet: Detecting Objects as Paired Keypoints论文笔记
(二)Summary
作者提出CornerNet,一种新的目标检测方法,使用单个卷积神经网络将目标的边界框看作一对关键点,即左上角和右下角。通过将物体检测看成关键点对估计问题,消除了在one-stage目标检测任务中需要设计a set of anchor boxes的需要。此外还提出corner pooling,能够帮助网络更好定位角点。
检测过程:
实验上,CornerNet在COCO数据集上取得了42.1%的AP值,超过了现存的单阶段detectors。
(三)Problem Statement
当前目标检测中start-of-art的方法就是使用不同大小以及长宽比的anchor boxes,并在one-stage方法上取得了和two-stage相当的成绩,不过使用anchor boxes存在的两个问题是:
- anchor boxes 的提出是完全和真实框不相关的,需要在feature map上存在着均匀充分的anchor,因此,在目标检测任务中往往存在非常多的anchor boxes。然而我们的detector的任务是将大量的anchor回归到真实框上,但是只有非常小的一部分和真实框有重叠。造成正负样本的不平衡,从而使得训练速度下降。
- anchor的使用引入了很多超参数以及设计的方案:多少个anchor,多大的size,长宽比是多少,往往采用启发式方法,也就是经验选取的,同时在多尺度的网络结构上,每个尺度使用的anchor不相同。也无法确定怎么做是好的。
作者的解决方案:将object看成是一对关键点:bounding box的左上角和右下角,只要找到top-left和Bottom-right两个点,就可以准确框出一个目标了。
(四)Method
CornerNet的检测流程如上,文章将对象检测看作为一对边界框角点的检测。 卷积网络输出为所有左上角输出heatmap,所有右下角输出heatmap,并为每个检测到的角点输出一个嵌入矢量。 属于同一目标的两个角点的嵌入矢量是相似的,通过训练网络判断相似性,找到属于同一目标的两个角点,即检测到了目标。同时为了产生更紧密的bounding boxes,网络还预测角点位置的偏移量。
网络整体流程
网络由backbone和预测模块构成。
使用Hourglass Network用作CornerNet的backbone网络,后面接两个预测模块,一个模块用于左上角点,另一个模块用于右下角点。每个模块在预测Heatmaps,embeddings以及offsets之前都会先进行Corner Pooling,网络并没有使用不同尺度特征的输出(FPN),以及在不同尺度上检测目标(backbone不同特征图使用不同的anchor)。
网络的预测输出为:左上和右下角点的heatmap、embeddings、以及角点的偏移offsets,最后利用一个post-processing算法来得到最终的bounding boxes。
backbone网络结构
使用hourglass network,是一个完全卷积的神经网络,由一个或多个hourglass module组成,hourglass module首先通过一系列卷积和最大池层对输入进行下采样,然后,它通过一系列上采样和卷积层将特征图上采样回原始分辨率。由于最大池图层中的细节会丢失,因此会添加skip layers向上采样特征中增加细节信息。
网络实现的细节信息(关于backbone具体实现细节,应该仔细看看论文代码呢):
- 不使用最大池,而是简单地使用stride 2来降低特征图分辨率,一共进行了5次步长为2的卷积,特征图的数量变化为:(256,384,384,384,512)
预测模块的结构
其中,网络的第一个部分是一个修改版本的残差块,只不过是将第一个3*3的卷积模块,利用corner Pooling模块代替,其中corner pooling模块首先是两个3
×
\times
× 3的Conv-BN-ReLU后接corner pooling。经过这个corner Pooling模块后,又接了一个3
×
\times
× 3的Conv-BN。同时将projection shortcut加了过来,经过ReLU,然后进行3
×
\times
× 3 Conv-BN-ReLU,之后经过3个 Conv-ReLU,和1
×
\times
× 1 conv后得到heatmaps, embeddings and offsets
残差块的结构如下:
(五)实验
训练时的详细设置
- 数据增强方式:随机水平翻转、随机缩放、随机裁剪、随机颜色变换:调整图像的亮度、饱和度和对比度,最后对输入图像做了PCA
- 优化算法使用Adam
- 整体损失: L = L d e t + α L p u l l + β L p u s h + γ L o f f L=L_{d e t}+\alpha L_{p u l l}+\beta L_{p u s h}+\gamma L_{o f f} L=Ldet+αLpull+βLpush+γLoff, α and β不能太大,
测试时的详细设置
- 在得到预测角点后,会对这些角点做NMS操作,选择前100个左上角角点和100个右下角角点。
- 计算左上角和右下角角点的embedding vector的距离时采用L1范数,距离大于0.5或者两个点来自不同类别的目标的都不能构成一对。
- 测试图像采用0值填充方式得到指定大小作为网络的输入,而不是采用resize,另外同时测试图像以及其水平翻转图并融合二者的检测结果。
- 最后通过soft-nms操作去除冗余框,只保留前100个预测框。
Ablation Study
1. Corner Pooling
Corner Pooling Corner Pooling是CornerNet的关键组成部分。 为了理解它对性能的贡献,作者训练了另一个具有相同数量参数但没有corner Pooling的网络。
表1 MS COCO消除corner Pooling验证
表1显示添加corner Pooling有着显着改善:AP为2.0%,AP50 为2.1%,AP75 为2.2%。 我们还看到corner Pooling对中型和大型目标特别有用,它们的AP分别提高了2.4%和3.7%。 这是预料中的,因为中型和大型目标的最顶部,最底部,最左边,最右边得边界可能更远离角点位置。
2. Reduce Penalty的作用
我们减少对正位置周围目标半径范围内的负位置给出的惩罚(第3.2节)。 为了理解这对训练CornerNet有多大帮助,我们训练一个没有减少惩罚的网络和另一个固定半径为2.5的网络。 我们在验证集上将它们与CornerNet进行比较。
表2 减少对正位置附近的负位置的惩罚有助于显着改善网络的性能
我们看到减少惩罚特别有利于大中型目标。
3. 分析造成AP上不去的原因
我们用ground-truth替换预测的热图和偏移。也就是查看使用预测的Embedding,和预测角点到底是哪一个让网络的性能得不到提升?
单独使用ground-truth的热图可以将AP从38.5%提高到74.0%,这表明CornerNet的主要瓶颈是检测角点。
这表明尽管在检测和分组角点方面仍有很大的改进空间,但主要的瓶颈是检测角点。 图8显示了预测角点的两个定性示例。
4. 与最先进的检测器进行比较
在MS COCO数据集上进行了实验,CornerNet打败了所有之间的one-stage检测算法,取得了和最好的two-stage检测算法可匹敌的性能。
(六)Notes
为什么检测角点会有效呢?
作者给出了两种解释:
- 中心点的确定需要4条边,然而角点的确定只需要两个边,并且利用corner pooling编码了角定义的一些先验知识
- 利用角点给出了一种用于表示全部boxes的简便方法。
Corner Pooling
corner pooling的由来
像上图中的情况,可以看到两个角点周围没有任何涉及到目标的东西,也就是我们再进行局部的max pooling没有任何意义。也就是a corner cannot be localized based on local evidence。
corner pooling的过程
在CornerNet中corner pooling是至关重要的
论文中提到作者使用动态规划来计算Corner Pooling,这是因为在每一次计算当前的最大值时,仅仅考虑当前位置的特征图的值,以及上一次计算的当前最大值。
利用上一步骤的结果计算下一步骤的最大值。
Heatmap以及Reduce penalty策略
网络两个prediction module分别输出一个heatmap,每一个heatmap有C(为类别数)个通道,大小为(H*W),左上角点heatmap图的第k个通道为二值特征图,值为1的点表示第k类别目标的左上角点,值为0表示不是corners点,但是这样存在一个问题:
绿色点是gt,橙色是检测到的corners,红色代表检测出来的框;那么,如果heatmap是binary mask,很明显红色框的结果并不好,因为corners和gt的位置并不吻合,这很明显违背我们的认知。退一步考虑,如果此时,有一个和真实目标没有任何交集的框,在heatmap上,它和红色框是一样的,都属于错误的框。这显然是不正确的。
所以正确的思路应该是:heatmap在gt位置处的值最大,其它位置,越靠近gt值越大,换而言之,用和gt位置的距离来代替是否处于gt位置上。
(可以看出这个预测框的两个角点和ground truth并不重合,但是该预测框基本框住了目标,因此是有用的预测框,所以要有一定权重的损失返回,这就是为什么要对不同负样本点的损失函数采取不同权重值的原因。)
围绕这个思路,作者提出了reduce penalty策略,基本思想就是构造高斯函数,中心就是gt位置,离这个中心越远衰减得越厉害,即
e − x 2 + y 2 2 σ 2 e^{-\frac{x^{2}+y^{2}}{2 \sigma^{2}}} e−2σ2x2+y2, σ \sigma σ是半径的 1 3 \frac{1}{3} 31,半径的确定是根据和目标之间IoU最小为0.7(实验中设定)确定下来的。
从而heatmap上的损失函数确定方式就如下所示了:
L
d
e
t
=
−
1
N
∑
c
=
1
C
∑
i
=
1
H
∑
j
=
1
W
{
(
1
−
p
c
i
j
)
α
log
(
p
c
i
j
)
if
y
c
i
j
=
1
(
1
−
y
c
i
j
)
β
(
p
c
i
j
)
α
log
(
1
−
p
c
i
j
)
otherwise
L_{d e t}=\frac{-1}{N} \sum_{c=1}^{C} \sum_{i=1}^{H} \sum_{j=1}^{W}\left\{\begin{array}{cc} \left(1-p_{c i j}\right)^{\alpha} \log \left(p_{c i j}\right) & \text { if } y_{c i j}=1 \\ \left(1-y_{c i j}\right)^{\beta}\left(p_{c i j}\right)^{\alpha} \log \left(1-p_{c i j}\right) & \text { otherwise } \end{array}\right.
Ldet=N−1c=1∑Ci=1∑Hj=1∑W{(1−pcij)αlog(pcij)(1−ycij)β(pcij)αlog(1−pcij) if ycij=1 otherwise
其中p是预测值,y是真实值。
几个参数的含义:摘自文章
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的差别。为什么对不同的负样本点用不同权重的损失函数呢?这是因为靠近ground truth的误检角点组成的预测框仍会和ground truth有较大的重叠面积。
从上面的解释中可以看出,pcij和ycij的值都不是二值的情况,ycij是通过2D高斯分布进行调整后的,pcij就是就是heatmap的输出值(应该是经过sigmoid之后的吧)。
Focal Loss的损失函数为:关于Focal Loss函数的通俗理解可以参考Focal Loss由来
F
L
=
−
1
N
∑
i
=
1
N
{
α
(
1
−
p
i
)
γ
log
(
p
i
)
if
y
i
=
1
(
1
−
α
)
(
p
i
)
γ
log
(
1
−
p
i
)
otherwise
FL=\frac{-1}{N} \sum_{i=1}^{N} \left\{\begin{array}{cc} \alpha\left(1-p_{i}\right)^{\gamma} \log \left(p_{i}\right) & \text { if } y_{i}=1 \\ \left(1-\alpha\right)\left(p_{i}\right)^{\gamma} \log \left(1-p_{i}\right) & \text { otherwise } \end{array}\right.
FL=N−1i=1∑N{α(1−pi)γlog(pi)(1−α)(pi)γlog(1−pi) if yi=1 otherwise
和本文中的loss函数对比,可以看出本文中在考虑正确和错误分类的样本的权衡上和Focal loss采取相同的思路,而考虑正负样本数量不均衡上形式有所不同。这里由于ycij并不是二值取值的,而是经过2D高斯分布调整后的可以取到小数部分,因此可以用来调整负样本的权重。得到了本论文中的损失函数。
Location offsets
为了更好的解释Location offsets,首先我们从为什么要引入location offsets入手介绍。
许多网络中都包含着下采样层用于获取全局信息,并降低内存的使用,比如原图上 ( x , y ) (x,y) (x,y)坐标会变换到特征图上的 ( ⌊ x n ⌋ , ⌊ y n ⌋ ) (\lfloor\frac{ x}{n}\rfloor,\lfloor\frac{y}{n}\rfloor) (⌊nx⌋,⌊ny⌋)的位置,当从特征图上重新映射到输入图上时,会损失掉一部分的精度。作者最终是在特征图上找到左上角和右下角的位置的,需要将左下角和右上角的坐标对应到原始图片上,如果不预测这个location offsets的话,得到的左上角和右下角是不准确的。
因此,作者提出预测原图上角点
(
x
k
,
y
k
)
(x_k,y_k)
(xk,yk)变换到特征图(本文中也称作heatmap)上点
(
⌊
x
k
n
⌋
,
⌊
y
k
n
⌋
)
(\lfloor\frac{ x_k}{n}\rfloor,\lfloor\frac{y_k}{n}\rfloor)
(⌊nxk⌋,⌊nyk⌋)之间的误差,而且这个误差最好是[0,1)之间的,因为做sigmoid可以直接变换到(0,1)上,因此预测的location offsets
o
k
\mathbb o_k
ok为:
o
k
=
(
x
k
n
−
⌊
x
k
n
⌋
,
y
k
n
−
⌊
y
k
n
⌋
)
\boldsymbol{o}_{k}=\left(\frac{x_{k}}{n}-\left\lfloor\frac{x_{k}}{n}\right\rfloor, \frac{y_{k}}{n}-\left\lfloor\frac{y_{k}}{n}\right\rfloor\right)
ok=(nxk−⌊nxk⌋,nyk−⌊nyk⌋)
网络预测的location offsets是被所有类别的左上角点共享的,对于右下角也是进行同样的处理。这里存在的问题是offsets是如何共享的?网络上具体是怎么实现的?
这里offsets的损失函数为采用smooth L1损失: L o f f = 1 N ∑ k = 1 N L_{o f f}=\frac{1}{N} \sum_{k=1}^{N} Loff=N1∑k=1N SmoothL1Loss ( o k , o ^ k ) \left(\boldsymbol{o}_{k}, \hat{\boldsymbol{o}}_{k}\right) (ok,o^k)。
作者怎么对左上角点和右下角点进行一一对应起来的
如何确定一对左上角和右下角对应的是一个边界框,作者借鉴论文[27],其中对检测到的人体关节都有一个嵌入向量,根据关节嵌入向量之间的距离对他们进行分组。利用本文的网络为每一个检测到的角点预测嵌入向量,如果左上角点和右下角点属于同一个边界框,则它们之间的Embedding距离应该很小。论文中的网络对于嵌入向量具体是什么不关心,只关心计算出来的距离。因此,在这里采用了一维的embedding值,给不同的目标分配不同的id,比如1,2,3……然后在预测的时候,如果top-left的corner和bottom-right的corner的embedding值特别接近,比如一个是1.2另一个是1.3,那么这两个很有可能属于一个目标;如果是1.2和2.3这样差距很大的,则一般就是两个不同的目标。要想实现这样的预测,必须做到两点:
- 同一个目标的两个corners预测出来的embedding值应当尽可能地接近。
- 不同目标预测出来的embedding值应当尽可能地远 。
作者引入第k个目标左上角embedding
e
t
k
e_{t_k}
etk和右下角embedding
e
b
k
e_{b_k}
ebk的均值
e
k
e_k
ek,我们希望左上角目标和右下角目标接近,也就是第k个目标类中类内分布集中,和机器学习中的类内散度矩阵有些类似
L
p
u
l
l
=
1
N
∑
k
=
1
N
[
(
e
t
k
−
e
k
)
2
+
(
e
b
k
−
e
k
)
2
]
L_{p u l l}=\frac{1}{N} \sum_{k=1}^{N}\left[\left(e_{t_{k}}-e_{k}\right)^{2}+\left(e_{b_{k}}-e_{k}\right)^{2}\right]
Lpull=N1k=1∑N[(etk−ek)2+(ebk−ek)2]
而类内散度矩阵为:
对于不同目标我们希望他们的Embeding足够远,参考类间散度矩阵,我觉得应该是:
L
=
−
1
N
(
N
−
1
)
∑
k
=
1
N
∑
j
=
1
j
≠
k
N
(
e
k
−
e
j
)
2
L=-\frac{1}{N(N-1)} \sum_{k=1}^{N} \sum_{j=1 \atop j \neq k}^{N} \left(e_{k}-e_{j}\right)^2
L=−N(N−1)1k=1∑Nj=kj=1∑N(ek−ej)2
考虑到L2损失对于outlier过于敏感,我们变换成L1损失,得到
L
=
−
1
N
(
N
−
1
)
∑
k
=
1
N
∑
j
=
1
j
≠
k
N
∣
e
k
−
e
j
∣
L=-\frac{1}{N(N-1)} \sum_{k=1}^{N} \sum_{j=1 \atop j \neq k}^{N} \left|e_{k}-e_{j}\right|
L=−N(N−1)1k=1∑Nj=kj=1∑N∣ek−ej∣
我觉得这里作者想将损失限制在一定值域范围内(这样做的好处是什么?),可能这样得到的
e
k
e_k
ek和
e
j
e_j
ej不会偏得太远,同时考虑当
e
k
e_k
ek和
e
j
e_j
ej距离太远时,比如说超过了
Δ
\Delta
Δ,损失为0.
最后不同目标之间的损失为:
L
push
=
1
N
(
N
−
1
)
∑
k
=
1
N
∑
j
=
1
j
≠
k
N
max
(
0
,
Δ
−
∣
e
k
−
e
j
∣
)
L_{\text {push}}=\frac{1}{N(N-1)} \sum_{k=1}^{N} \sum_{j=1 \atop j \neq k}^{N} \max \left(0, \Delta-\left|e_{k}-e_{j}\right|\right)
Lpush=N(N−1)1k=1∑Nj=kj=1∑Nmax(0,Δ−∣ek−ej∣)
作者在这里
Δ
\Delta
Δ的取值为1.
其中
m
a
x
(
0
,
∣
e
k
−
e
i
∣
)
max(0,|e_k-e_i|)
max(0,∣ek−ei∣)的图像如下所示:
Hourglass Module的优势
Hourglass Module在一个统一的结构中捕获全局和局部特征。当多个Hourglass Module堆叠在网络中时,沙漏模块可以重新处理特征以捕获更高级别的信息。这些属性使得Hourglass Network也成为目标检测的理想选择。
作者想法的出发点
基于DeNet[39],作者提出网络的核心在于:使用单个卷积网络去检测和对角点进行分组,并且不需要任何的特征selection步骤,同时使用了corner pooling。
同时作者受到论文[27]的影响,对检测到的人体关节都有一个嵌入向量,根据关节嵌入向量之间的距离对他们进行分组。
叠在网络中时,沙漏模块可以重新处理特征以捕获更高级别的信息。这些属性使得Hourglass Network也成为目标检测的理想选择。
作者想法的出发点
基于DeNet[39],作者提出网络的核心在于:使用单个卷积网络去检测和对角点进行分组,并且不需要任何的特征selection步骤,同时使用了corner pooling。
同时作者受到论文[27]的影响,对检测到的人体关节都有一个嵌入向量,根据关节嵌入向量之间的距离对他们进行分组。