前言
关于YOLOv3可以看一下我前面的推文讲解:YOLOV3点这里 。前面提到过,YOLOv3在实时性和精确性都是做的比较好的,并在工业界被广泛应用。当前的目标检测算法,大都在网络结构,Anchor,IOU上做了大量的文章,而在检测框的可靠性上做文章的却非常少。所以,Gaussian YOLOv3它来了。论文地址为:点这里 。并且作者也开放了源码,地址为:点这里。所以本文就带大家来学习一下这个算法。
算法原理
YOLOv3回顾
对于左图,就是YOLOv3的网络结构。可以看到YOLO V3整体使用了特征金字塔的结构,使得网络在3个尺度上执行目标检测任务,可以适应各种不同大小的目标。并且使用了跳跃连接skip shortcut防止因为网络过深而发生梯度消失,无法收敛。YOLOV3还使用了上采样操作,并将大特征图和小特征图上采样的特征图进行concat,使得网络既可以包含高层特征的高级语义信息又可以保留低层特征的物体位置信息,对目标检测任务起到促进作用。
而右图也就是YOLOv3中的输出层,可以看到YOLOv3会在三个特征层分别输出,输出信息为目标的坐标位置,目标是前景的置信度,目标属于某个特定类别的置信度。对于对于每个尺度分支而言,在每个grid cell中会预测出三个结果(每个尺度下会有三个anchor)。将三个尺度的结果合并,进行非极大值抑制(NMS)后,输出最终的检测结果。
YOLOv3可能存在的问题?
从上面的回顾中可以看到,YOLOV3的目标类别是一个概率值来评价的,而目标的框只有位置信息 ( x , y , w , h ) (x,y,w,h) (x,y,w,h)却没有概率值,也就是说我们无法知道当前目标框的可靠性。这就是YOLOv3存在的问题,我们无法评价目标框的可靠性。所以这篇论文以这位切入点提出了Gaussian YOLOv3.即利用Guassian模型对网络输出进行建模,在基本不改变YOLOv3结构和计算量的情况下,能够输出每个预测框的可靠性,并且在算法总体性能上提升了3个点的MAP。
Gaussian YOLOv3
将原始的YOLOv3的目标框输出加入高斯模型后,网络的输出变成了下图这样。
原始的YOLOv3对于三个不同尺度的feature map,每个点输出
3
×
(
(
t
x
,
t
y
,
t
w
,
t
h
)
+
o
b
j
s
c
o
r
e
+
c
l
a
s
s
s
c
o
r
e
)
3\times ((t_x, t_y, t_w, t_h) + obj_score + class_score)
3×((tx,ty,tw,th)+objscore+classscore)个信息,其中
c
l
a
s
s
s
c
o
r
e
class_score
classscore包含了类别的可靠性信息,
o
b
j
s
c
o
r
e
obj_score
objscore包含了是否是目标的可靠性信息,而关于边界框,我们只有关于坐标的相关信息
t
x
,
t
y
,
t
w
,
t
h
t_x,t_y,t_w,t_h
tx,ty,tw,th,但这些坐标信息并不能表示该bbox的可靠性。基于此,论文提出了将高斯模型用到bbox的坐标预测上,通过高斯模型的标准差来估计坐标信息的可靠性。加入了高斯模型后,bbox的输出变成了:
其中
μ
\mu
μ代表均值,
∑
\sum
∑表示标准差(方差),考虑到YOLOv3的一贯做法,我们需要将上面的参数做以下变换:
通过这一系列等式(2),(3),(4)得到的
u
t
x
,
μ
t
y
,
μ
t
w
,
μ
t
h
u_{tx},\mu_{ty},\mu_{tw},\mu_{th}
utx,μty,μtw,μth可以直接当做计算bbox回归的坐标来用(因为
μ
t
x
\mu_{tx}
μtx就是
t
x
tx
tx的最大似然估计)。
注意,这里对 u t x ^ , u t y ^ \hat{u_{tx}},\hat{u_{ty}} utx^,uty^做了sigmoid操作将值限定在(0,1)范围是YOLOv3的直接坐标预测做法,即是说每个grid检测的物体中心必须落在当前grid内。这一点可以看我之前的推文解释:点这里。而 u t w ^ \hat{u_{tw}} utw^和 u t h ^ \hat{u_th} uth^没有做sigmoid操作的原因是因为长宽的尺度变化可能操作1,这个做法和YOLOv3一致。标准差 δ t x ^ \hat{\delta_{tx}} δtx^, δ t y ^ \hat{\delta_{ty}} δty^, δ t w ^ \hat{\delta_{tw}} δtw^, δ t h ^ \hat{\delta_{th}} δth^也通过sigmoid将值限定在(0,1)范围内,这是因为标准差表明了点坐标的可靠性,0表示非常可靠,1表示不可靠(因为对于高斯分布,方差越大,则一定程度上说明这个分布的变化比较大,即是 μ t x \mu_{tx} μtx这个bbox的估计结果越不可靠)。
做了上面的铺垫后就可以引出论文的损失函数了。现在对于网络输出的每个bbox坐标都满足均值为
μ
\mu
μ,方差为
σ
\sigma
σ的高斯,因此论文中使用了NLL_LOSS,即是negative log likelihood loss。
其中:这个式子表示了对于bbox的ground truth框的每一个值在均值为
u
t
x
u_{tx}
utx和房差为
σ
t
x
\sigma_{tx}
σtx的高斯分布下的值
x
i
j
k
G
x_{ijk}^G
xijkG,其中高斯分布的密度函数是:
f
(
x
)
=
1
2
π
σ
e
x
p
(
−
(
x
−
μ
)
2
2
σ
2
)
f(x)=\frac{1}{\sqrt{2\pi}\sigma}exp(-\frac{(x-\mu)^2}{2\sigma^2})
f(x)=2πσ1exp(−2σ2(x−μ)2)。其中每个
x
x
x对应的输出值
f
(
x
)
f(x)
f(x)是在该点的概率密度值,这个值可以近似表示概率,但是它实际上不是概率(其实概率密度函数是概率分布函数的导数)。所以我们的目标是希望ground truth 的概率密度函数值在网络的所有输出值的均值
μ
t
x
\mu_{tx}
μtx和方差
δ
t
x
\delta_{tx}
δtx构成的高斯分布中是最大的,即表明网络输出的高斯分布和真实标签是最相符的。那么当
μ
t
x
\mu_{tx}
μtx和
σ
t
x
\sigma_{tx}
σtx构成的分布和真实的lable分布越接近时,
N
N
N就会越大,
l
o
g
(
N
.
.
.
)
log(N...)
log(N...)也会越大,那么前面取负号,整个损失就会越小。
损失函数还有一个权重惩罚系数
γ
i
j
k
\gamma_{ijk}
γijk,计算公式如下:
其中
w
s
c
a
l
e
w_{scale}
wscale使用ground truth的长宽来计算的。然后
δ
i
j
k
o
b
j
\delta_{ijk}^{obj}
δijkobj表示当ground truth和当前的Anchor的IOU大于一定阈值时取1,如果没有合适的Anchor和Ground Truth就取0。
注意上面只是针对了bbox的x坐标进行了讲解,其他的一样类推即可。还有在目标检测预测阶段,bbox的每一类特定的置信度就要用下面的公式来计算了:
相比原来的YOLO系列,预测部分增加了一个
U
n
c
e
r
t
a
i
n
t
y
a
v
e
r
Uncertainty_{aver}
Uncertaintyaver坐标可靠性系数,这个系数是bbox的四个标准差
σ
t
x
,
σ
t
y
,
σ
t
w
,
σ
t
h
\sigma_{tx},\sigma_{ty},\sigma_{tw},\sigma_{th}
σtx,σty,σtw,σth的平均值,这也是前面为什么对标准差做了sigmoid操作的原因。
实验结果
在KITTI和BDD上验证结果:
可以看到Gaussian YOLOv3比YOLOv3的效果提升了很多,并且加入了Gaussian之后的YOLO效果在同等速度下达到了最优。并且文中提到Gaussian YOLOv3有效的减少约%40的False Positive,提高了约5%的True Positive。
代码推荐
建议跑AlexAB版本的darknet里面的GaussianYOLOv3,非常简单和准确。地址如下:点这里
后记
今天介绍了Gaussian YOLOv3,个人觉得这篇论文的思想是值得点赞的。从bbox的可靠性做文章有可能会是目标检测算法优化的又一重要方向。
欢迎关注我的微信公众号GiantPandaCV,期待和你一起交流机器学习,深度学习,图像算法,优化技术,比赛及日常生活等。