yolo-v1

tech2024-06-28  57

背景

根据 YOLO官网 对它的解释,YOLO:Real-Time Object Detection. You Only Look Once(YOLO)是一个最先进的实时的目标检测系统。这是继RCNN,fast-RCNN 和 faster-RCNN之后,rbg(Ross Girshick)大神挂名的又一大作,起了一个很娱乐化的名字:YOLO。 虽然目前版本还有一些硬伤,但是解决了目前基于DL检测中一个大痛点,就是速度问题。 其增强版本GPU中能跑45fps,简化版本155fps。

下面为一个对比图:

具有:1. 速度快;2. 将整张图作为输入,把背景误认为物体错误率小;3. 泛化能力强

说明:下述预测的位置信息均为偏移量,这里为了理解方便才说为准确信息。

核心思想

将整张图片作为网络的输入,直接在输出层对bounding box的位置和所属类别进行回归。

YOLO检测系统简单直接,可以看做只有三步:

YOLO检测系统先将输入图像调整到448×448。需要固定尺寸;

在图像上运行卷积网络;

通过模型的置信度对结果进行阈值。

细节解释

网络结构

YOLO网络借鉴了GoogleNet的思想,但与之不同的是,为了更好的性能,它增加额外的4层卷积层(conv)。YOLO一共使用了24个级联的卷积层和2个全连接层(fc),其中conv层中包含了1×1和3×3两种kernel,最后一个fc全连接层后经过reshape之后就是YOLO网络的输出,是长度为S×S×(B×5+C)=7×7×30的tensor,最后经过识别过程得到最终的检测结果。其中在ImageNet分类任务上使用分辨率的一半(224×224输入图像)对卷积层进行预训练。

核心点

点1:对于每一个框,预测出来的位置信息(x,y,w,h),是如何归一化到0-1的?

点2:置信度(confidence)

点3:对于最终输出张量解释

假设我们对于原图分成SS的网格状,每个网格预测B个候选框,其中每个候选框返回四个位置信息(x,y,w,h)和置信度(为5维张量),对于每一个网格返回K个分类概率(为K维张量)。那么对于每一个网格就应该返回[B(4+1)+K]维张量,其中B*(4+1)代表候选框信息,K代表分类概率;对于整张图,就应该返回SS[B*(4+1)+K]维张量。下面详细依次记述:(前提假设S=7,B=2,K=20):

将原始图片划分成77网格,则网络最后输出为7730维张量,其中取出一个网格对应的输出为11*30为张量。

前5个代表一个预测框的位置信息和置信度(前面4个为(x,y,w,h)位置信息,后一个为置信度);后5个代表另一个预测框的位置信息和置信度(排列顺序同理);

最后20表示当该网格含有物体时,属于每一类别的概率,即。其中需要注意的是:属于同一网格的两个预测框,共享一套条件概率值。

总得来讲就是让网格负责类别信息,bounding box主要负责坐标信息(部分负责类别信息:confidence也算类别信息)。

点4:在得到最后SS[B*(4+1)+K]维张量输出后,如何计算每一个预测框属于每一类的概率?

以S=7,B=2,K=20为例

如上面两图,分别表示第一个预测框和第二个预测框与类别概率相乘情况。以第一个预测框举例(第二个一样):将预测框的置信度和类别概率相乘,得到一个20维的向量,为上图的黄色部分,其中每一维代表预测框属于该类别的置信度,公式如下:

那么我们就会得到772=98个上述黄色部分。其进程可以用下面三个图展现:

(计算完第一个网格,第二个网格对应的两个预测框生成的概率向量)

点5:针对每一类进行NMS

现在我们得到98个概率向量,如下图,假如第一类为“dog”,我们现在针对”dog”这一类进行举例说明,其余步骤相同。下图为整体流程:

首先针对“dog”这一行向量(在这之前我们已经执行:对其概率得分score,首先设置一个阈值,假若score小于该阈值则设置为0)对score进行由大到小排序。如下:

得到score序列:0.5、0.3、0.2、0.1、…、0、0、0、0。找出最大概率得分score对应的预测框(下图中最大概率得分为0.5,对应预测框为“bb47”),记为“bbox_max”,对于概率得分非零且不是最大的预测框,记为“bbox_cur”。

将“bbox_max”和“bbox_cur”按照“bbox_cur”的概率得分从大到小依次做IOU,假若IOU(bbox_max, bbox_cur)>0.5(这里0.5为人为设定的阈值),则将该bbox_cur对应的概率得分score改为0;若不满足则对该bbox_cur的概率得分不做改变。如下,假若第二个和第一个IOU>0.5,则将第二个概率得分0.2改为0,这样一次将“bbox_max”和后面的“bbox_cur”做IOU:

我们以“0.5”对应的预测框作为“bbox_max”计算完一轮之后,现在假设我们得到score序列:0.5、0、0.2、0.1 … 0、0、0、0。

那么进行下一轮循环,从0.2开始,将0.2对应的框作为“bbox_max”,继续循环计算后面的“bbox_cur”与新的“bbox_max”的IoU值,大于0.5的设为0,小于0.5的score不变。

再这样进入下一轮,一直计算比较到最后一个score。得到最后的score序列:0.5、0、0.2、0、0、…、0、0。我们只得到两个候选框对“dog”的预测概率得分不为0,如下:

上面1-6步是对第一类别“dog”进行的NMS。假若第二类是“cat”,我们只需要提取出第二行概率得分向量,依次进行上面步骤即可。如下:

点6:在原图上标出候选框

假设我们已经执行完,1. 对其概率得分score,首先设置一个阈值,假若score小于该阈值则设置为0;2.对每一类进行NMS。现在再次筛选预测框,将剩下的标在原图上,具体步骤如下:

1)先取出针对bbox3的所有20个scores,按照类别的默认顺序找出score最大的那个score的index索引号(根据此index可以找出所属的类别)记为class。

2)以及相应的bbox3的最大score分数,记为score。

3)判断score是否大于0,如果是,就在图像中画出标有class的框。否则,丢弃此bbox。

4)对于下一个bbox执行上述三步,一直到执行完所有预测框。如下图,我们选出三个预测框,其余舍弃:

点7:损失函数

论文中损失函数分为3部分,如下:

7.1 位置误差

注意:其中开根号是为了对于小物体的预测误差敏感大一些,对于大物体的预测误差敏感小一些(由于小物体相对于大物体对位置预测要求更高一些)。如下:

7.2 置信度损失

7.3 类别损失

训练

预训练分类网络,数据为imagenet-1000,输入分辨率为224*224。包括20层卷积,1层全局平均池化,1层全连接。

训练检测网络。对于网络结构,取出分类网络的卷积部分,然后再添加4层卷积,后面接两个全连接层,(对于这6层的权重初始化),输入变为448448。数据为VOC-20,分辨率448448。

按照点7的损失函数,进行训练网络。

测试

在原图上标出候选框,如下:

(参考点6部分)

优缺点

优点

假阳性(FP)错误率低。YOLO网络将整个图像的全部信息作为上下文,在训练的过程中使用到了全图信息,能够更好的区分目标个背景区域。

端到端(end-to-end)的方法,速度快,如官网所说,具有实时性,45fps,在YOLO-tiny上可以达到155fps。

通用性强,可以学到物体的generalizable-representation。对于艺术类作品中的物体检测同样适用。它对非自然图像物体的检测率远远高于DPM和RCNN系列检测方法。

缺点

性能表现比当前最先进的目标检测技术低。

定位准确性差,对于小目标或者密集型群体object的定位效果不好。虽然每个格子可以预测出B个bounding box,但是最终只选择一个score最高的作为输出,即每个格子最多只得出一个box,如果多个物体的中心落在同一个格子,那么最终可能只预测出一个object。

YOLO的loss函数中,大物体的IoU误差和小物体的IoU的误差对训练中的loss贡献值接近,造成定位不准确。作者采用了一个去平方根的方式,但还不是最好的解决方法。

输入尺寸固定。由于输出层为全连接层,因此在检测时,YOLO训练模型只支持与训练图像相同的输入分辨率。其他分辨率需要缩放成此固定分辨率大小。

采用了多个下采样层,网络学到的物体特征并不精细,因此对检测效果会有影响。

最新回复(0)