序言
关于YOLOv3相信大家都很熟悉了,如果对YOLOv3还不熟悉的同学可以先去了解一下它的原理,别选择跳级理解,因为本篇文章说到的Gaussian YOLOv3是基于YOLOv3的改进版本,如果有了解过YOLOv3的理论知识,理解起来相对来说要简单一些。
论文链接:Gaussian YOLOv3
Github代码:Gaussian YOLOv3代码
一、YOLOv3存在的问题
在以往基于深度学习的对象检测算法最关键的问题之一是,被检测对象的bbox坐标是已知的,而bbox结果的不确定性是未知的,造成了一些误检测情况,也就是说,目标框只有位置而没有置信度,从结果中无法预知当前目标框的可靠性,基于此,作者提出使用利用Gaussian模型来对网络输出进行建模,通过输出预测bbox的定位准确性来降低FP,提高TP,在不改变YOLOv3的计算量和网络结构情况下,仍然可以保持很快的速度。改进的重点:对bbox的不确定性进行建模。
二、Guassian YOLOv3和YOLOv3输出对比
首先回顾一下YOLOv3的边框输出:
在YOLOv3中,在feature上的每个点输出为:3 x((tx,ty,tw,th)+obj_score+class_score),每个点上预设了3个anchors,其中(tx,ty)用来确定中心点的坐标,(tw,th)用来回归目标框的宽高,obj_score用来确定物体的位置,而class_score则包含了目标的分类信息,在上述输出的信息中,可以看到,在回归的bbox目标框中,只有坐标的位置信息,至于这个坐标框位置的可靠性我们是不知道的,也就是说我们并不知道这个框坐标点是否能正确的代表目标框,所以就有了以下Guassian YOLOv3的改进,在加入高斯模型后,网络的输出变成了这样:
注意到,网络的输出由原来的3*(四个位置信息+一个obj_score+C个class_score),变成了3*(八个位置信息+一个obj_score+C个class_score),也就是bbox的输出变成了:
其中u()为边框的坐标,代表均值,∑为各坐标的不确定性,表示方差,这样一来,通过引进Guassian模型,每个目标框坐标的不确定性也就有了判别的依据。
但是在这里并不能直接将u()和∑直接拿来做为高斯模型的均值和方差,还需要经过如下变换:
通过等式(2),将做了sigmoid处理,将值的范围控制在(0-1)之间,秉承了YOLOv3的思想,对和不做处理,不限制其大小,因为长宽的尺度变化有可能超过1,这也是YOLOv3的原始思想。标准差也通过sigmoid将值限定在(0,1)范围内,这是因为标准差表明了点坐标的可靠性,0表示非常可靠,1表示不可靠(因为对于高斯分布,方差越大,则一定程度上说明这个分布的变化比较大,即是这个bbox的估计结果越不可靠)。
经过了(2)、(3)、(4)的式子变换之后,就得到了高斯模型真正的均值和方差。
三、loss function
在满足了高斯分布的均值和方差后,文中对损失函数也相对做了改进,采用NLL_LOSS损失函数,即negative log likelihood loss(负对数似然损失),主要修改的是坐标回归处的损失,其他的分类和前景的交叉熵损失没变化。
此外,在阈值的计算上,标准标变成了:
加入了坐标值可靠性因素Uncertainty_aver,这个值是bbox输出的四个标准差的平均值,这也就是前面为什么对标准差做了sigmoid的结果。
四、结果对比
作者分别在KITTI和BDD数据集上做了测试,对比结果如下:
-
mAP对比
可以看到在KITTI数据集上mAP提升了3.09,在BDD数据集上mAP提升了3.5,作者并未在coco数据集上做详细的实验,因此此算法只能算是自动驾驶领域的一个针对性检测算法,而非通用目标检测算法。 -
FP和TP的对比效果:
Gaussian YOLOv3有效的减少约40%的FP,提高了约5%的TP。
参考文档: