目标检测(后处理):从 NMS 到 Soft-NMS 到 Softer NMS
1、NMS
非最大抑制(NMS)主要用于基于深度学习的目标检测模型输出的后处理,从而去除冗余的检测框,获得正确的检测结果。示意图如下:
算法流程:
- 将网络输出框集合 B B B 按照置信度分数 S S S 从高到低的顺序排序,定义 D D D 为最终检测框集合, N t N_t Nt 为 N M S NMS NMS 阈值。
- 当
B
B
B 不为空集时:
- m m m 为置信度分数最高的框,将 m m m 放入 D D D,并将它从 B B B 中删除
- 对于
B
B
B 中余下的每个框
b
i
b_i
bi:
如果 i o u ( m , b i ) ≥ N t iou(m, b_i)\ge N_t iou(m,bi)≥Nt,则将 b i b_i bi 从 B B B 中删除
- 返回检测结果 D D D
通过分析可以发现 N M S NMS NMS 存在以下几个缺陷:
- 稠密场景下漏检多:如下图
1
1
1 所示,当两个目标距离较近存在部分重叠时,置信度较小的目标漏检的可能性较大。
图 1: 红色框的置信度比绿色框的置信度高,两个框重叠较多,NMS 会将绿色框过滤 -
N
M
S
NMS
NMS 默认置信度分数较高的框,定位更精确,由于分类和回归任务没有直接相关性,因此这个条件并不总是成立。比如图
2
2
2 中,置信度分数高的边界框并不总是比置信度低的框更可靠。
图 2: ( a ) (a) (a) 中两个边界框位置都不够精确; ( b ) (b) (b) 中置信度较高的边界框的左边界精确度较低 -
G
r
o
u
n
d
T
r
u
t
h
Ground~Truth
Ground Truth 的标注可能并不可靠。
代码:
import numpy as np
def nms(dets, Nt):
x1 = dets[:,0]
y1 = dets[:,1]
x2 = dets[:,2]
y2 = dets[:,3]
scores = dets[:,4]
order = scores.argsort()[::-1]
#计算面积
areas = (x2 - x1 + 1)*(y2 - y1 + 1)
#保留最后需要保留的边框的索引
keep = []
while order.size > 0:
# order[0]是目前置信度最大的,肯定保留
i = order[0]
keep.append(i)
#计算窗口i与其他窗口的交叠的面积
xx1 = np.maximum(x1[i], x1[order[1:]])
yy1 = np.maximum(y1[i], y1[order[1:]])
xx2 = np.minimum(x2[i], x2[order[1:]])
yy2 = np.minimum(y2[i], y2[order[1:]])
#计算相交框的面积,不相交时用0代替
w = np.maximum(0.0, xx2 - xx1 + 1)
h = np.maximum(0.0, yy2 - yy1 + 1)
inter = w * h
#计算IOU:相交的面积/相并的面积
ovr = inter / (areas[i] + areas[order[1:]] - inter)
inds = np.where(ovr < thresh)[0]
order = order[inds + 1]
return keep
# test
if __name__ == "__main__":
dets = np.array([[30, 20, 230, 200, 1],
[50, 50, 260, 220, 0.9],
[210, 30, 420, 5, 0.8],
[430, 280, 460, 360, 0.7]])
thresh = 0.35
keep_dets = nms(dets, thresh)
print(keep_dets)
print(dets[keep_dets])
时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 为待筛选检测框数量
2、Soft-NMS
针对 N M S NMS NMS 存在的第一个问题,通过分析发现主要是因为在 N M S NMS NMS 算法中每次直接将与 m m m 的 i o u iou iou 大于等于 N t N_t Nt 的检测框直接删除导致的。 因此基于 N M S NMS NMS 算法, S o f t − N M S Soft-NMS Soft−NMS 进行了如下改进:
将于 m m m 重叠的检测框置信度降低,而不是直接删除。
这样可能存在另一个问题,同一目标的其他检测框也可能被保留下来。因此需要设计合适的策略,既保留相近的其他目标,又删除重复检测的目标。直觉上可以发现通常重复的检测框具有更高的重叠,因此可以根据
i
o
u
iou
iou 大小来设计置信度分数下降的程度。置信度修正策略如下:
s
i
=
{
s
i
,
iou
(
M
,
b
i
)
<
N
t
s
i
(
1
−
iou
(
M
,
b
i
)
)
,
iou
(
M
,
b
i
)
≥
N
t
s_{i}=\left\{\begin{array}{ll}{s_{i},} & {\operatorname{iou}\left(\mathcal{M}, b_{i}\right)<N_{t}} \\ {s_{i}\left(1-\operatorname{iou}\left(\mathcal{M}, b_{i}\right)\right),} & {\operatorname{iou}\left(\mathcal{M}, b_{i}\right) \geq N_{t}}\end{array}\right.
si={si,si(1−iou(M,bi)),iou(M,bi)<Ntiou(M,bi)≥Nt
该策略为
i
o
u
iou
iou 的线性函数,同样可以使用高斯惩罚函数
s
i
=
s
i
∗
e
−
i
ou
(
M
,
b
i
)
2
σ
,
∀
b
i
∉
D
s_{i}=s_{i}*e^{-\frac{\mathrm{i} \text { ou }\left(\mathcal{M}, b_{i}\right)^{2}}{\sigma}}, \forall b_{i} \notin \mathcal{D}
si=si∗e−σi ou (M,bi)2,∀bi∈/D
算法流程如下图所示:
代码:
# -*- coding:utf-8 -*-
import numpy as np
def py_cpu_softnms(dets, Nt=0.3, sigma=0.5, thresh=0.5, method=2):
"""
py_cpu_softnms
:param dets: boexs 坐标矩阵 format [x1, y1, x2, y2, score]
:param Nt: iou 交叠阈值
:param sigma: 使用 gaussian 函数的方差
:param thresh: 最后的分数阈值
:param method: 使用的方法,1:线性惩罚;2:高斯惩罚;3:原始 NMS
:return: 留下的 boxes 的 index
"""
N = dets.shape[0]
# the order of boxes coordinate is [x1,y1,x2,y2]
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
for i in range(N):
# intermediate parameters for later parameters exchange
tB = dets[i, :4]
ts = dets[i, 4]
ta = areas[i]
pos = i + 1
if i != N-1:
maxscore = np.max(dets[:, 4][pos:])
maxpos = np.argmax(dets[:, 4][pos:])
else:
maxscore = dets[:, 4][-1]
maxpos = -1
if ts < maxscore:
dets[i, :] = dets[maxpos + i + 1, :]
dets[maxpos + i + 1, :4] = tB
dets[:, 4][i] = dets[:, 4][maxpos + i + 1]
dets[:, 4][maxpos + i + 1] = ts
areas[i] = areas[maxpos + i + 1]
areas[maxpos + i + 1] = ta
# IoU calculate
xx1 = np.maximum(dets[i, 0], dets[pos:, 0])
yy1 = np.maximum(dets[i, 1], dets[pos:, 1])
xx2 = np.minimum(dets[i, 2], dets[pos:, 2])
yy2 = np.minimum(dets[i, 3], dets[pos:, 3])
w = np.maximum(0.0, xx2 - xx1 + 1)
h = np.maximum(0.0, yy2 - yy1 + 1)
inter = w * h
ovr = inter / (areas[i] + areas[pos:] - inter)
# Three methods: 1.linear 2.gaussian 3.original NMS
if method == 1: # linear
weight = np.ones(ovr.shape)
weight[ovr > Nt] = weight[ovr > Nt] - ovr[ovr > Nt]
elif method == 2: # gaussian
weight = np.exp(-(ovr * ovr) / sigma)
else: # original NMS
weight = np.ones(ovr.shape)
weight[ovr > Nt] = 0
dets[:, 4][pos:] = weight * dets[:, 4][pos:]
# select the boxes and keep the corresponding indexes
inds = np.argwhere(dets[:, 4] > thresh)
keep = inds.astype(int).T[0]
return keep
算法时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 为待筛选检测框数量
注意:
通过对比可以看出,原始 N M S NMS NMS 与 S o f t − N M S Soft-NMS Soft−NMS 算法中的模式 3 3 3 等价,也就是说,删除 i o u iou iou 过高的重叠框等价于将该重叠框置信度分数置 0 0 0 。
3、Softer-NMS
S
o
f
t
−
N
M
S
Soft-NMS
Soft−NMS 只解决了三个问题中的第一个问题。对于第二个问题,分类置信度分数和框的
i
o
u
iou
iou 不是强相关,因此需要一种新的方法来衡量框的位置置信度
。
作者假设边界框的
4
4
4 个坐标值之间相互独立,并使用单变量高斯分布来预测位置置信度。
P
Θ
(
x
)
=
1
2
π
σ
2
e
−
(
x
−
x
e
)
2
2
σ
2
P_{\Theta}(x)=\frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{\left(x-x_{e}\right)^{2}}{2 \sigma^{2}}}
PΘ(x)=2πσ21e−2σ2(x−xe)2
其中
Θ
\Theta
Θ 为可学习参数的集合,
x
e
x_e
xe 为被估计的边界框位置。标准差
σ
\sigma
σ 衡量预测的不确定性,当
σ
→
0
\sigma \rightarrow0
σ→0 时,表示网络对预测的位置的置信度很高。
G
T
GT
GT 边界框置信度也可以使用高斯分布来表示,当
σ
→
0
\sigma \rightarrow0
σ→0 时,变成
D
i
r
a
c
d
e
l
t
a
Dirac~delta
Dirac delta 函数:
P
D
(
x
)
=
δ
(
x
−
x
g
)
P_{D}(x)=\delta\left(x-x_{g}\right)
PD(x)=δ(x−xg)
其中,
x
g
x_g
xg 为
G
T
GT
GT 边界框位置。
KL 损失函数
目标定位的目标是估计参数
Θ
^
\hat{\Theta}
Θ^,使
N
N
N 个样本的
P
Θ
(
x
)
P_{\Theta}(x)
PΘ(x) 和
P
D
(
x
)
P_{D}(x)
PD(x) 之间的
K
L
KL
KL 散度最小。
Θ
^
=
arg
min
Θ
1
N
∑
D
K
L
(
P
D
(
x
)
∥
P
Θ
(
x
)
)
\hat{\Theta}=\underset{\Theta}{\arg \min } \frac{1}{N} \sum D_{K L}\left(P_{D}(x) \| P_{\Theta}(x)\right)
Θ^=ΘargminN1∑DKL(PD(x)∥PΘ(x))
使用
K
L
KL
KL 散度作为回归损失函数,对于单个样本:
L
r
e
g
=
D
K
L
(
P
D
(
x
)
∥
P
Θ
(
x
)
)
=
∫
P
D
(
x
)
log
P
D
(
x
)
d
x
−
∫
P
D
(
x
)
log
P
Θ
(
x
)
d
x
=
(
x
g
−
x
e
)
2
2
σ
2
+
log
(
σ
2
)
2
+
log
(
2
π
)
2
−
H
(
P
D
(
x
)
)
\begin{aligned} L_{r e g} &=D_{K L}\left(P_{D}(x) \| P_{\Theta}(x)\right) \\ &=\int P_{D}(x) \log P_{D}(x) \mathrm{d} x-\int P_{D}(x) \log P_{\Theta}(x) \mathrm{d} x \\ &=\frac{\left(x_{g}-x_{e}\right)^{2}}{2 \sigma^{2}}+\frac{\log \left(\sigma^{2}\right)}{2}+\frac{\log (2 \pi)}{2}-H\left(P_{D}(x)\right) \end{aligned}
Lreg=DKL(PD(x)∥PΘ(x))=∫PD(x)logPD(x)dx−∫PD(x)logPΘ(x)dx=2σ2(xg−xe)2+2log(σ2)+2log(2π)−H(PD(x))
分析可知,当
x
e
x_e
xe 预测不准确时,网络预测更大的
σ
2
\sigma^2
σ2 使
L
r
e
g
L_{reg}
Lreg 更小。
l
o
g
(
2
π
)
2
\frac{log(2\pi)}{2}
2log(2π) 和
H
(
P
D
(
x
)
)
H(P_D(x))
H(PD(x)) 与估计参数
Θ
\Theta
Θ 无关,因此
L
r
e
g
∝
(
x
g
−
x
e
)
2
2
σ
2
+
1
2
log
(
σ
2
)
L_{r e g} \propto \frac{\left(x_{g}-x_{e}\right)^{2}}{2 \sigma^{2}}+\frac{1}{2} \log \left(\sigma^{2}\right)
Lreg∝2σ2(xg−xe)2+21log(σ2)
由于
σ
\sigma
σ 位于分母,为了防止梯度爆炸,网络预测
α
=
l
o
g
(
σ
2
)
\alpha=log(\sigma^2)
α=log(σ2) 代替直接预测
σ
\sigma
σ。
L
r
e
g
∝
e
−
α
2
(
x
g
−
x
e
)
2
+
1
2
α
L_{r e g} \propto \frac{e^{-\alpha}}{2}\left(x_{g}-x_{e}\right)^{2}+\frac{1}{2} \alpha
Lreg∝2e−α(xg−xe)2+21α
对于
∣
x
g
−
x
e
∣
>
1
|x_g-x_e|>1
∣xg−xe∣>1 使用类似于
s
m
o
o
t
h
L
1
smooth~L_1
smooth L1 损失。
L
r
e
g
=
e
−
α
(
∣
x
g
−
x
e
∣
−
1
2
)
+
1
2
α
L_{r e g}=e^{-\alpha}\left(\left|x_{g}-x_{e}\right|-\frac{1}{2}\right)+\frac{1}{2} \alpha
Lreg=e−α(∣xg−xe∣−21)+21α
方差投票
获取预测框位置方差后,根据相邻边界框位置方差来对候选框投票。
s
o
f
t
e
r
−
N
M
S
softer-NMS
softer−NMS 算法如下。
位置更新规则如下:
p i = e − ( 1 − I o U ( b i , b ) ) 2 / σ t x = ∑ i p i x i / σ x , i 2 ∑ i p i / σ x , i 2 subject to IoU ( b i , b ) > 0 \begin{aligned} p_{i} &=e^{-\left(1-I o U\left(b_{i}, b\right)\right)^{2} / \sigma_{t}} \\ x &=\frac{\sum_{i} p_{i} x_{i} / \sigma_{x, i}^{2}}{\sum_{i} p_{i} / \sigma_{x, i}^{2}} \\ & \text { subject to } \operatorname{IoU}\left(b_{i}, b\right)>0 \end{aligned} pix=e−(1−IoU(bi,b))2/σt=∑ipi/σx,i2∑ipixi/σx,i2 subject to IoU(bi,b)>0
通过分析发现,有两类邻近框权重较低:
- 位置方差较大的检测框
- 和选中框的 i o u iou iou 小的框
由于分类分数较低的框可能有较高的位置置信度,因此分类置信度不参与位置投票。
4、总结
本文主要介绍了 N M S NMS NMS、 S o f t − N M S Soft-NMS Soft−NMS 和 S o f t e r − N M S Softer-NMS Softer−NMS 算法,及其主要改进的方向。
- N M S NMS NMS 主要用于去除重复的检测框。
- S o f t − N M S Soft-NMS Soft−NMS 在 N M S NMS NMS 的基础上,不再直接去除重叠较高的检测框,而是将重叠的检测框的分类置信度分数降低。最终去除重复的检测框,而保留存在一定程度重叠的不同目标的检测框,该方法比较适用于稠密目标的检测。
- 在前两者的基础上, S o f t e r − N M S Softer-NMS Softer−NMS 算法对检测框的位置概率分布进行建模。对于重叠的检测框,根据重叠程度和位置不确定性进行投票,重叠程度高,位置分布方差小的检测框权重大,从而获得更精确的检测框。