前言
本文提出了一种新的one-stage目标检测方法,它没有使用anchor,而是通过bbox的左上角和右下角corner来检测目标。如下图所示,通过一个单一神经网络,为属于同一类别的所有实例的左上corner生成一个heatmap,同理右下corner也有一个heatmap,每个corner还有一个embedding vector,这个embedding负责将属于同一目标的一对儿corner进行分组,也就是网络为属于同一目标的两个corner预测相似的embedding,如图中的两个橙色的embedding。这样通过后续处理可以认为这两个corner组成一个bbox。
本文提出的另一个创新点是corner pooling,它可以帮助卷积网络更好地定位bbox的corner。通常bbox的一个corner会在目标的外部,如下图所示:
在这种情况下要确定一个location是不是corner,仅凭局部信息是不够的。如果要确定一个location是不是左上corner,需要从这个location水平向右看,才能知道是不是目标的topmost边界,从这个location水平向下看,才能知道是不是目标的leftmost边界。也就是说,左上corner是由topmost边界和leftmost边界共同确定的。受此启发,作者提出了corner pooling,如下图所示:
以两个特征图作为输入,在每个location处,将第一个特征图上所有位于这个location下边位置的特征向量进行最大池化,将第二个特征图上所有位于这个location右边位置的特征向量进行最大池化,然后将两个向量相加,得到这个location的特征向量。
作者解释了为什么检测corner的效果更好:
- 检测bbox的中心要依赖四条边,而定位一个corner只需两条边,所以检测corner更简单些。
- corner在离散的bbox空间中更有效率,用 O ( w h ) O(wh) O(wh)的corner就可以表征 O ( w 2 h 2 ) O(w^{2}h^{2}) O(w2h2)的可能的anchor。
CornerNet
上图是CornerNet的整体结构。它采用hourglass network作为主干网络,后接两个预测模块,一个负责左上corner,另一个负责右上corner。每个模块中都有各自的corner pooling模块,对来自hourglass的特征进行pool,然后再预测heatmap,embedding和offset。
其中,左上corner有一套heatmap,右上corner有一套heatmap,embedding用于判断左上corner和右上corner是否属于同一目标,属于同一目标的两个corner的embedding之间的距离很小。为了使通过预测corner得到的bbox更加紧贴目标,网络还预测了offset来稍微调整corner的位置。
1. detecting corner
每个heatmap都有 C C C个通道,大小为 H × W H×W H×W,其中 C C C为类别数量,这 C C C个通道中不包含背景。每个通道都是一个二值mask,表示一个corner的location是否属于这个类别。
对于每个corner,有一个gt positive location,其余都是negative location。在训练时,要以positive location为圆心,对一定半径以内的negative location降低惩罚。这是因为一对儿错误的corner检测如果与gt location靠得太近,它们生成的bbox与gt box之间的IoU将会很大。如下图所示,橘色的点是positive location,绿色的虚线框是在positive location一定范围之内的negative location所预测的bbox,可以看到,它与红色实线的gt box之间的重叠度很大。
那么这个半径该如何确定呢? 这个半径由目标大小决定,要保证在这个半径内,一对儿点生成的bbox与gt box之间的IoU为0.3,那么这个半径以内的这些点就是需要降低惩罚的negative location。设
y
c
i
j
y_{cij}
ycij为gt heatmap的值,本来
y
c
i
j
=
1
y_{cij}=1
ycij=1时表示positive location,为0表示negative location,但现在要对一定范围内的negative location降低惩罚,那么修改
y
c
i
j
y_{cij}
ycij为:
圆心就是positive location,
σ
\sigma
σ是半径的1/3。
y
c
i
j
=
1
y_{cij}=1
ycij=1依然表示positive location,而此时
y
c
i
j
<
1
y_{cij}<1
ycij<1表示negative location。所以此时
(
1
−
y
c
i
j
)
(1-y_{cij})
(1−ycij)表示应该被降低惩罚的negative location,并将它添加到focal loss中:
其中
p
c
i
j
p_{cij}
pcij表示在heatmap上的location
(
i
,
j
)
(i,j)
(i,j)处属于类别
c
c
c的概率,
N
N
N是一个图像中目标的数量,
α
\alpha
α和
β
\beta
β为超参数,控制各项对损失的贡献,这里
α
=
2
\alpha=2
α=2,
β
=
4
\beta=4
β=4,
(
1
−
y
c
i
j
)
(1-y_{cij})
(1−ycij)降低了position location周围一定范围内的negative location的惩罚。
2. offset
采用下采样之后,卷积网络输出的分辨率比原始图像要小。设下采样的倍数为
n
n
n,原始图像上的location
(
x
,
y
)
(x,y)
(x,y)映射到heatmap上的location为:
如果将heatmap上的location重新映射回原始图像上,会发生精度损失,尤其会对小目标的bbox和其gt box之间的IoU产生严重影响。为了解决这个问题,网络预测llocation的offset,在重新映射回原始图像之前对corner的location进行调整:
其中
o
k
o_{k}
ok就是offset,
x
k
x_{k}
xk和
y
k
y_{k}
yk分别是第
k
k
k个corner的
x
x
x和
y
y
y坐标。具体来说,网络预测了一套offset由所有类别的左上corner共享,另一套offset由右下corner共享。在训练时,对gt corner location用smooth L1 损失函数:
3. grouping corners
在一个图像中会有多个左上corner和右下corner,如何判断一个左上corner和一个右下corner属于同一个bbox呢?本文借鉴了embedding这一思想,为每个corner生成一个embedding vector,如果一个左上corner和一个右下corner属于同一个bbox,那么它们的embedding之间的距离应该很小,然后就能基于这个距离对corner进行分组。其实embedding的值是多少并不重要,只根据embedding之间的距离判断一对儿corner是不是属于一个bbox。
本文设置embedding的维数为1,设
e
t
k
e_{tk}
etk是目标
k
k
k的左上corner的embedding,
e
b
k
e_{bk}
ebk是目标
k
k
k的右下corner的embedding,用pull loss将属于同一bbox的corner分组,用push loss将corner分开:
其中
e
k
e_{k}
ek是
e
t
k
e_{tk}
etk和
e
b
k
e_{bk}
ebk的均值,这里
Δ
=
1
\Delta=1
Δ=1,与offset loss相似,以上的loss只用在gt corner location上。
4. corner pooling
接下来说一下corner pooling层的具体实现方法。假设现在要判断一个location
(
i
,
j
)
(i,j)
(i,j)是不是左上corner,记左上corner pooling层的输入的特征图分别为
f
t
f_{t}
ft和
f
l
f_{l}
fl,大小为
H
×
W
H × W
H×W,location
(
i
,
j
)
(i,j)
(i,j)处的特征向量分别为
f
t
i
,
j
{f_{t}}_{i,j}
fti,j和
f
l
i
,
j
{f_{l}}_{i,j}
fli,j,corner pooling层首先max-pool
(
i
,
j
)
(i,j)
(i,j)和
(
i
,
H
)
(i,H)
(i,H)之间所有的特征向量,得到特征向量
t
i
j
t_{ij}
tij;然后max-pool
(
i
,
j
)
(i,j)
(i,j)和
(
W
,
j
)
(W,j)
(W,j)之间所有的特征向量,得到特征向量
l
i
j
l_{ij}
lij,最后将
t
i
j
t_{ij}
tij与
l
i
j
l_{ij}
lij相加。计算可由下式表示:
t
i
j
t_{ij}
tij与
l
i
j
l_{ij}
lij进行的是element-wise max相加,通过上式可以看到这是一个递归的计算式,可以反过来提高计算效率,计算过程如下图:
整个预测模块如下图所示:
第一部分是经过修改的残差块,用corner pooling模块替代3 × 3的卷积块。corner pooling模块首先用两个3 × 3 × 128的卷积层处理来自backbone的特征图,然后再把处理后的特征图丢到corner pooling层里。然后将corner pooling层的输出结果送入一个3×3×256的Conv-BN层。corner pooling模块后接一个3×3×256的卷积块,然后通过3个Conv-ReLU-Conv层生成heatmap,embedding和offset
Training
作者在PyTorch中实现CornerNet,网络在PyTorch的默认设置下进行随机初始化,没有在任何数据集上进行预训练。在训练时,将输入图像的像素设为511 × 511,由此输出的像素为128 × 128。为了减少过拟合,采用了标准的数据增强方式,比如随机水平翻转,随机缩放,随机裁剪和随机色彩抖动,其中包括调整图像的亮度,饱和度和对比度。最后用PCA处理输入图像。
作者还用了Adam优化整体的loss:
其中
α
\alpha
α,
β
\beta
β和
γ
\gamma
γ分别是pull,push和offset损失的权重系数,这里
α
\alpha
α和
β
\beta
β都为0.1,
γ
\gamma
γ为1。作者发现
α
\alpha
α和
β
\beta
β为1或者更大的数时,检测性能会下降。
Inference
在测试时,作者用了一个简单的算法根据heatmap,embedding和offset生成bbox。首先使用3×3的最大池化层在corner heatmap上进行NMS处理,然后从heatmap中选取前100个左上corner和前100个右下corner,corner的location由对应的offset进行调整。然后计算左上和右下corner的embedding之间的L1距离,如果距离大于0.5,或者这一对儿corner属于不同的类别,那么就拒绝这对儿corner。然后将左上和右下corner的平均得分用作检测结果的得分。
作者保持了输入图像的原始像素,并在送入CornerNet前对其进行0填充处理。原始图像和经过反转后的图像都用于测试。最后将这两种图像的检测结果结合起来,并用soft-nms去除冗余的检测结果,只保留前100个检测结果。每个图象的平均inference时间是244ms.