前面写了四篇关于前面的文章yolov5的文章,链接如下:
1、标签文件解析">基于libtorch的yolov实现目标检测网络——COCO数据集json分析标签文件
2、基于libtorch的yolov实现目标检测网络(2)-网络结构
3、基于libtorch的yolov实现目标检测网络(3)——Kmeans聚类获取anchor框尺寸
4、C 实现Kmeans获取聚类算法COCO目标检测数据集anchor框
其中:
-
第一篇讲COCO数据集json标签分析;
-
第二篇讲yolov5神经网络正向传播liborch实现;
-
使用第三篇Opencv提供的Kmeans算法来获取anchor框尺寸;
-
第四篇关于自己使用的文章C 实现的Kmeans算法来获取anchor相对而言,本文获得的框架尺寸anchor比第三篇更准确。
我们主要讲这篇文章yolov计算网络损失函数的原理。
01
测量目标检测结果的准确性
目标检测任务有三个主要目的:
因此,判断检测结果是否准确,主要基于以上三个目的:
首先要定义理想情况:。检测结果越接近这种理想状态,即目标越少,结果越准确;
理想情况的定义也是:。测试结果越接近理想状态,结果就越准确;
识别和分类检测到的目标。分类结果越符合目标的实际分类,结果就越准确。
如下图所示,为了检测目标,人和公共汽车不仅要检测每个人和公共汽车的位置,还要检测周围人和公共汽车的最小矩形框,还要识别哪个矩形框是人,哪个矩形框是公共汽车。
02
yolov5网络损失函数构成
我们前面也说过yolov网络的基本思想:
把640*输入图像分为640N*N(通常为80*80、40*40、20*20)网格,然后预测每个网格的三个指标:。
其中:
-
矩形框 表示目标的大小和准确位置。 -
置信度 表示预测矩形框(以下简称预测框)的可信度,取值范围为0~1.值越大,目标越有可能存在于矩形框中。 -
分类概率 表示目标类别。
因此,在实际检测中:
-
首先 判断每个预测框的预测信度是否超过设定阈值。如果超过,则认为预测框中有目标,以获得目标的一般位置。 -
接着 根据非极大值抑制算法筛选目标预测框,删除相应目标的重复矩形框(我们将详细讨论非极大值抑制算法)。 -
最后 根据筛选后预测框的分类概率,取最大概率对应的索引,即目标的分类索引号,以获得目标的类别。
也就是说,整体损失是三种损失的加权和,通常最大权重是可信度损失、矩形框损失和分类损失,如:
a = 0.4
b = 0.3
c = 0.3
yolov5使用
03
mask掩码矩阵
下面我们以80*以80网格为例mask掩码的定义、用途以及如何获取。*40网格与20*20网格也差不多。
什么是mask掩码?
神经网络将图像分割成80*80网格预测了3*80*80个预测框,那么每个预测框都存在检测目标吗?显然不是。所以在训练时首先需要根据标签作初步判断,哪些预测框里面很可能存在目标?mask这样的3掩码*80*80的bool型矩阵:
mask掩码有什么用?
神经网络对80*80网格的每个网格预测三个矩形框,因此输出3*80*每个预测框的预测信息包括矩形框信息、可信度和分类概率。事实上,并非所有的预测框都需要计算所有类别的损失函数值,而是基于mask决定矩阵:
-
仅mask矩阵中的对应位置是true矩形框的损失需要计算; -
仅mask矩阵中的对应位置是true需要计算分类损失的预测框; -
所有的预测框都需要计算信心损失,但是 mask 为true的预测框与mask为false预测框的可信度标签值不同。
对于80*80网格,其各种损失函数的计算表达如下,其中
40*40网格和20*20网格的损失函数计算与80*80网格类似,最后把所有网格的损失函数值作加权和,即得到一张训练图像的最后的损失函数值:
上式中α1、α2、α3为各网格损失函数值的权重系数。考虑到图像中往往小型目标比较多,中型目标次之,大型目标最少,因此通常把80*80网格的权重α1设置最大,40*40网格的权重α2次之,20*20网格的权重α3最小,使得训练时网络更加专注于数量多的目标,比如α1、α2、α3依次取0.5、0.3、0.2。
怎么得到mask掩码?
下面我们详细说明一下mask矩阵是怎么得到的。
首先将3*80*80的mask矩阵
-
如果点(xg,yg)在格子的左上角,则取左边、上方的两个格子; -
如果点(xg,yg)在格子的右上角,则取右边、上方的两个格子; -
如果点(xg,yg)在格子的左下角,则取左边、下方的两个格子; -
如果点(xg,yg)在格子的右下角,则取右边、上下方的两个格子;
根据以上原则,x1和y1可按下式计算,其中round为四舍五入运算:
前文我们讲使用Kmeans聚类算法获取九个anchor框的时候,就讲过:
-
宽、高最小的anchor0、 anchor1 、anchor2 分配给80*80网格的每个格子; -
宽、高次小的 anchor3、 分配给40*40网格的每个格子;anchor4 、anchor5 -
宽、高最大的 anchor6、 分配给20*20网格的每个格子。anchor7 、anchor8
因此80*80网格中(x0, y0)、(x1, y0)、(x0, y1)这三个格子都对应
将保留的anchor框标记为true,剔除的anchor框标记为false,那么anchor0、anchor1、anchor2对应的标记为(m0, m1, m2):
对一张图像中的所有目标框,都作以上判断并对mask矩阵赋值,即可得到该图像的mask矩阵。
04
矩形框损失计算原理
这里为什么先讲矩形框损失呢?因为后面讲的置信度损失原理会使用到矩形框损失。
我们前文讲过,yolov5对每个格子预测3个不同位置和大小的矩形框,其中每个矩形框的信息为矩形中心的x坐标、y坐标,以及矩形宽、高。假设对某个格子预测的矩形框为(xp, yp, wp, hp),该格子对应的目标矩形框为(xl, yl, wl, hl),下面依次讲解几种最常见的矩形框损失函数的计算原理。
-
L1、L2、smooth L1损失函数
首先是L1损失函数:
其次是L2损失函数:
接着是smooth L1损失函数:
以上式子中,记d=x1-x2,分别画出fL1(d)、fL2(d)、fsL1(d)的曲线如下图:
由以上计算公式和曲线可以看出:
-
IOU系列损失函数
上述计算矩形框的L1、L2、smooth L1损失时有一个共同点,都是分别计算矩形框中心点x坐标、中心点y坐标、宽、高的损失,最后再将四个损失值相加得到该矩形框的最终损失值。
于是,IOU系列损失函数(IOU、GIOU、DIOU、CIOU)又被陆续提了出来。计算IOU系列损失函数需要使用矩形框左上角、右下角的坐标,假设预测矩形框的左上角、右下角坐标分别为(xp1, yp1)、(xp2, yp2),标签矩形框的左上角、右下角坐标分别为(xl1, yl1)、(xl2, yl2),如下图所示:
矩形框的中心坐标、宽、高可根据下式转换到左上角、右下角坐标:
下面分别介绍IOU、GIOU、DIOU、CIOU损失函数的计算原理。
(1)IOU loss
IOU为两个方框相交区域面积与相并部分面积的比值,所以也称为交并比。
首先求相交部分面积:
然后求相并部面积:
从而得到交并比IOU:
IOU的取值范围为0~1,当两个矩形框完全没有交集时,IOU为0,当它们完全重合时IOU为1,也即重合度越小IOU越接近0,重合度越大IOU越接近1。
最后得到IOU loss的计算公式如下,两个矩形框重合度越高IOU loss越接近0:
(2)GIOU loss
当两个矩形框完全没有重叠区域时,无论它们距离多远,它们的IOU都为0。这种情况下梯度也为0,导致无法优化。为了解决这个问题,GIOU又被提了出来。
如上图所示,GIOU在IOU的基础上,把包围矩形框A和矩形框B的最小矩形框(图中的虚线框)的面积也加入到计算中。
GIOU可按下式计算,其中S1为A、B相交部分的面积(红色区域)。其中S3为包围A、B的最小矩形框的面积,S2为A、B相并区域的面积(蓝色+红色+灰色区域)。
由上式可知GIOU相比IOU,新增了(S3-S2)/S3这一项。新增项表示什么意义呢?由上述可知S3-S2为虚线框中白色区域的面积,也即虚线框中不属于A也不属于B的空白区域,那么(S3-S2)/S3就是空白区域面积占虚线框面积的比例,这个比例越大说明A、B距离越远、重叠度越小,反之则A、B距离越近、重叠度越大。
GIOU的取值范围是-1~1,当A、B完全没有重叠区域时IOU为0,那么GIOU取负值,极端情况,当A、B无重叠区域且距离无限远时,此时(S3-S2)/S3等于1,那么GIOU取-1;另一个极端情况,当A、B完全重叠时(S3-S2)/S3等于0,IOU为1,那么GIOU取1。
因此,GIOU解决了当A、B完全没有重叠区域时IOU恒为0的问题。
最后得到GIOU loss的计算公式:
(3)DIOU loss
GIOU虽然把IOU的问题解决了,但它还是基于面积的度量,并没有把两个矩形框A、B的距离考虑进去。为了使训练更稳定、收敛更快,DIOU随之被提了出来,DIOU把矩形框A、B的中心点距离ρ、外接矩形框(虚线框)的对角线长度c都直接考虑进去,如下图所示:
DIOU可按下式计算:
由上式可知DIOU的取值范围也为-1~1,当两个框A、B完全重合时DIOU取1,当A、B距离无限远时,DIOU取-1。
从而得到DIOU loss的计算公式:
(4)CIOU loss
DIOU把两个矩形框A、B的重叠面积、中心点距离都考虑了进去,但并未考虑A、B的宽高比。为了进一步提升训练的稳定性和收敛速度,在DIOU的基础上CIOU又被提了出来,它将重叠面积、中心点距离、宽高比同时加入了计算。
CIOU可按下式计算:
上式中,ρ为框A和框B的中心点距离,c为框A和框B的最小包围矩形的对角线长度,v为框A、框B的宽高比相似度,α为v的影响因子。
反正切arctan函数的取值范围是0~Π/2,那么v的取值范围为0~1,当框A、框B的的宽高比相等时v取0,当框A、框B的的宽高比相差无限大时v取1。
当框A、框B的距离无限远,且宽高比差别无限大时DIOU取-1,v取1,alpha取0.5,此时CIOU取-1-0.5=-1.5;当框A、框B完全重叠时,DIOU取1,v取0,α取0,则CIOU取1。因此
IOU越大也即A、B的重叠区域越大,则α越大,从而v的影响越大;反之IOU越小也即A、B的重叠区域越小,则α越小,从而v的影响越小。因此在优化过程中:
-
如果A、B的重叠区域较小,则宽高比v在损失函数中影响较小,此时着重优化A、B的距离; -
如果A、B的重叠区域较大,则宽高比v在损失函数中影响也较大,此时着重优化A、B的宽高比。
用一句话来说,就是越缺什么,就越着重弥补什么,从而达到加速优化训练的收敛速度和稳定性的目的。
由以上可得CIOU loss的计算公式为:
05
置信度损失计算原理
下面以80*80网格为例,详细讲置信度损失的计算原理,40*40和20*20网格的置信度损失计算原理与80*80网格一样,可依此类推。
-
神经网络预测的置信度
比如下图中,红点A、B、C、D表示检测目标,那么每个红点所在格子的三个预测置信度应该比较大甚至接近1,而其它格子的预测置信度应该较小甚至接近0。
-
置信度的标签
标签的维度应该与神经网络的输出维度保持一致,因此
这里就用到了上文我们讲的
这样一来,标签值的大小与预测框、目标框的重合度有关,两框重合度越高则标签值越大。当然,上文我们讲CIOU的取值范围是-1.5~1,而置信度标签的取值范围是0~1,所以需要对CIOU做一个截断处理:
-
BCE loss损失函数
假设置信度标签为矩阵L,预测置信度为矩阵P,那么矩阵中每个数值的BCE loss的计算公式如下:
注意BCE loss要求输入数据的取值范围必须在0~1之间。
从得到80*80网格的置信度损失值:
此外,我们称对应mask位true的预测框为正样本,对应mask为false的预测框为负样本,负样本肯定是远远多于正样本的,为了使训练更专注于正样本,后来Focal loss又被提了出来,我们在此暂时不细说,下篇文章再详细介绍吧。
06
分类损失计算原理
下面也以80*80网格为例,详细讲分类损失的计算原理,40*40和20*20网格的分类损失计算原理与80*80网格一样,可依此类推。
神经网络对80*80网格的每个格子都预测三个预测框,每个预测框的预测信息都包含了N个分类概率。其中N为总类别数,比如COCO数据集有80个类别,那么N取80。所以对于COCO数据集,每个预测框有80个0~1的分类概率,那么神经网络总共预测
80*80网格的标签概率矩阵与预测概率矩阵的维度一样,也是3*80*80*80。每个预测框的标签,由解析json标签文件得到,是一个0~79的数值,需要将0~79的数值转换成80个数的独热码:
然而,为了减少过拟合,且增加训练的稳定性,通常对独热码标签做一个平滑操作。如下式,label为独热码中的所有数值,α为平滑系数,取值范围0~1,通常取0.1。
同样假设置标签概率为矩阵Lsmooth,预测概率为矩阵P,那么矩阵中每个数值的BCE loss的计算公式如下:
于是得到80*80网格的分类损失函数值的计算公式:
07
结语
好了,本文我们就讲到这里。说点题外话,隔了两三个月没有更新文章了,感觉很对不起粉丝们。因为本人在年底不仅换了工作,工作城市也换了,免不了一番奔波与适应,所以更新就被耽搁了。不过呢,我还是会在业余抽时间来学习、更新,不辜负粉丝们对我的期望~祝朋友们新年快乐,事事顺心(迟来的祝福^^)!
欢迎关注"