文章目录[隐藏]
简介
YOLO(you only look once)是最近很火爆的一种目标检测模型,之前一直想研究,但是苦于大学期间太忙,前段时间又忙于考研,所以一直没有来得及动笔。最近终于闲下来好好研究一下。
话不多说,进入正题。
YOLO与目标检测
相较于以往两阶段的检测模型,YOLO做到了一次检测,两个结果,即兼顾了物体位置和类别。而且在此基础上保证了不错的精度和速度。
这是目标检测的发展历程。
Yolo系列发表日期全部在Faster RCNN之后,Faster RCNN算法的精度是state-of-the-art级别的,Yolo算法的精度没有超越Faster RCNN,而是在速度与精度之间进行权衡。Yolo v3在改进多次之后,既有一定的精度,也保持了较高的运行速度。在很多边缘计算、实时性要求较高的任务中,Yolo v3备受青睐。在RCNN算法日益成熟之后,Yolo算法却能横空出世,离不开其高性能和使用回归思想做物体检测的两个特点。
YOLO算法原理
直接来一张YOLO的模型结构图
简单分析一下吧:输入是448 * 448,经过若干卷积变成7 * 7 * 1024的张量,然后全连接,然后reshape成7 * 7 * 30的张量,至于中间的激活函数和Dropout什么的我就不再赘述了,和其他的神经网络也差不多。相比R-CNN算法,其是一个统一的框架,其速度更快,而且Yolo的训练过程也是end-to-end的
训练的数据集格式
图片就是简单的png或者jpg,标签多用xml格式的数据,里面必须包含图片内物品的名字、坐标。常用的开源数据集有:voc、coco等。也可以自己搭建训练数据,通过打标软件,构建img和label文件夹。下面是图片及标签的示例:
最后一维输出的张量
这里的输出维度非常重要,下面逐一解释。
从上文我们可知,最后一维的张量是7 * 7 * 30的。其中:7 * 7表示的yolo将图片分成49个小格子,每一个小格子所生成的若干个矩形框用来预测一种物体。
我们取出其中的一个小格子,他的长度是30,也就是说一个小格子里有30个输出的信息。如下图所示,我们来仔细研究下其中具体包含了什么。
30=5+5+20,有意一个小格子可以生成2个bbox,所以这里有两个5,也就是有2组bbox的信息,当然生成几个bbox是可以自己确定的,不过模型的输出维度也要随之改变。
- 两个5——坐标信息
我们来看第一个5,如图所示,从上到下是:中心点的x坐标、y坐标、宽度w、高度h、是否属于被检测物体的置信度c。
这里详细解释一下置信度c:每个bbox都有一个confidence的值,表示预测的bbox包含一个物体的置信度。计算公式为:
从公式可以理解这个置信度衡量了两个方面:一个是bbox是否包含物体,另一个是bbox对于物体的位置预测的准确率(IOU)。如果一个bbox不包含物体,那么这个bbox的置信度为0,如果一个bbox包含物体,那么prob=1,置信度就是bbox和ground truth box的IOU值了。
第二个5和第一个5类型是一样的,因为有B个检验框,所以有B个5。
- 一个20——类别全概率
这里的20,是指yolo默认可以分20类的意思,也就是每个gridsell包含的物体属于20类别中每一类的概率。和上面一样,这里的概率仍然是条件概率,也就是probe和类概率的乘积(全概率),S * S个grid cell的B个bbox共享这个概率,其公式如下:
综上所述,一共有 S * S 个格子,每个格子预测B个bbox,每个bbox预测5个值,此外,每个格子预测C个类别,所以检测器最终需要预测一个 S * S * (B * 5 + C) 的tensor。在文中,S=7, B=2, C=20,所以最终会得到一个维度为30的tensor。
损失值的计算
损失函数是所有神经网络中都比较重要的部分,因为其用于比较真实值和预测值之间的差距,再用于优化器反向传播。在YOLO中,损失函数较一般的分类回归问题更为复杂。
在YOLO中,Loss是通过ground truth和输出之间的sum-squared error进行计算的,所以相当于把分类问题也当成回归问题来计算loss。如下图所示,loss一共包3个部分:
- 位置误差(2个部分)
- 置信度误差(是否含有object)
- 分类误差
如上图(出自B站:同济子豪兄)所示:所有部分的loss都是计算平方和的误差,所以都可以认为是回归问题。接下来我们按部分来了解一下YOLO的loss是怎么计算的:
- 位置误差(中心点误差x, y)
造成的损失是图五中的第一行。其中 1objij为控制函数,在标签中包含物体的那些格点处,该值为 1 ;若格点不含有物体,该值为 0。也就是只对那些有真实物体所属的格点进行损失计算,若该格点不包含物体,那么预测数值不对损失函数造成影响。(x, y)数值与标签用简单的平方和误差。 - 位置误差(预测框的宽高)
造成的损失是图五的第二行。 1objij的含义一样,也是使得只有真实物体所属的格点才会造成损失。这里对 (w, h)在损失函数中的处理分别取了根号,原因在于,如果不取根号,损失函数往往更倾向于调整尺寸比较大的预测框。例如,20个像素点的偏差,对于800 * 600的预测框几乎没有影响,此时的IOU数值还是很大,但是对于30 * 40的预测框影响就很大。取根号是为了尽可能的消除大尺寸框与小尺寸框之间的差异。
这里其实我一开始没有想得很明白,所以我另外参考了一位博主的说法:
上图中,蓝色为bounding box,红色框为真实标注,如果w和h没有平方根的话,那么bounding box跟两个真实标注的位置loss是相同的。但是从面积看来B框是A框的25倍,C框是B框的81/25倍。B框跟A框的大小偏差更大,也就是B和A之间差别要更离谱一点,所以不应该有相同的loss。
如果W和h加上平方根,那么B对A的位置loss约为3.06,B对C的位置loss约为1.17,B对A的位置loss的值更大,这更加符合我们的实际判断。所以,算法对位置损失中的宽高损失加上了平方根。(反正写到这里我是完全懂了) - 预测框的置信度C(含有object)
如果bbox里有物体,先验概率为1,否则为0。第二项代表bounding box和真实标记的box之间的IoU。值越大则box越接近真实位置。(至于IoU是怎么算的大家可以去百度一下,就是两块面积的交并比)
confidence是针对bounding box的,由于每个网格有两个bounding box,所以每个网格会有两个confidence与之相对应。 - 预测框的置信度C(不含有object)
这里和上面差不多,只不过是针对bbox里没有物体的情况下,也就是说这两个confidence只能二者取一。 - 分类误差
对象条件类别概率是一组概率的数组,数组的长度为当前模型检测的类别种类数量(YOLO中是20),它的意义是当bounding box认为当前box中有对象时,要检测的所有类别中每种类别的概率。
损失函数中的权重分配
此时再来看λcoord和λnoobj ,Yolo面临的物体检测问题,是一个典型的类别数目不均衡的问题。其中49个格点,含有物体的格点往往只有3、4个,其余全是不含有物体的格点。此时如果不采取点措施,那么物体检测的mAP不会太高,因为模型更倾向于不含有物体的格点。λcoord和λnoobj的作用,就是让含有物体的格点,在损失函数中的权重更大,让模型更加“重视”含有物体的格点所造成的损失。在论文中,λcoord和λnoobj的取值分别为5与0.5。
YOLO-V1的缺点
由于YOLOV1的框架设计,该网络存在以下缺点:
- 每个网格只对应两个bounding box,当物体的长宽比不常见(也就是训练数据集覆盖不到时),效果较差。
- 原始图片只划分为7x7的网格,当两个物体靠的很近时,效果比较差。
- 最终每个网格只对应一个类别,容易出现漏检(物体没有被识别到)。
- 对于图片中比较小的物体,效果比较差。这其实是所有目标检测算法的通病。
差不多就是这样,简单写了一点,有机会的话再去仔细研究一下原著,加深一下自己的理解。有写的不对的地方还请指正。
版权声明:本文为CSDN博主「计算机秃头选手」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44736333/article/details/122688796
暂无评论