YOLOv1 论文简要

相关文章

项目地址:YOLOv1 VOC 2007

笔者训练的权重地址:阿里云盘分享

YOLOv1 论文📃传送门🚪:《You Only Look Once: Unified, Real-Time Object Detection》👈快戳我🥵

10 秒文章速览

本文主要讲解了 YOLOv1 的模型构建、损失函数、模型训练

介绍

YOLO 已经成为目前最热门🔥🔥🔥的目标检测算法之一,虽然 YOLO 的作者在写完 YOLOv3 后,便停止了开发,但由于 YOLO 的卓越性能和创新性,吸引了不少企业、研究院对 YOLO 的改进,使得 YOLO 已经子孙满堂,玩出花🪷来了。但本文的重心依然是 YOLOv1

YOLO 的全名是 You Only Look Once,你只需要看一次。在 YOLO 中,我们将目标检测看作为一个回归问题,所以只需要在图片上“看”一次,就可以获取目标的所有边界框和类别。也正因将检测视为回归问题,所以 YOLO 的速度非常快。并且,由于不需要复杂的流程,测试时只需要在图片上简单的运行的神经网络就可以来预测检测

好了好了,下面来粗略瞅瞅 YOLOv1 都干了啥吧

1.png

在上图中,我们经历了以下操作:

  1. 调整图片大小,将输入图片大小调整为 448×448
  2. 将图片放入卷积网络运行
  3. 根据模型输出的置信度对结果进行非极大值抑制(NMS)

然后,再来欣赏下 YOLO 的魔力🪄吧(虽然 YOLO 在艺术品和自然图像上的运行结果中,它将人误检成了飞机,但它大部分上是准确的)

2.png

概念梳理

先不急,在谈 YOLO 是如何检测目标之前,先来解释一下IOU、置信度、非极大值抑制(NMS)的概念💡。当然,倘若阁下对此早已了然于胸,那么也可以跳过这部分内容

IOU

IOU(交并比,intersection over union),交并比嘛,顾名思义咯,就是描述集合A与集合B的交集与并集之比的一个数值🔢

I O U = A ∩ B A ∪ B IOU = \frac{A\cap B}{A\cup B} IOU=ABAB

IOU 可以描述两个框的重合度,它们的IOU等于两个框重合部分的面积除以它们合并起来的面积。在 YOLO 中,IOU 可以描述模型预测框与真实框之间的重合度

3.png

在上图中,“交集”中青色区域是两个框的重合部分,“并集”中蓝色区域是两个框的相并部分。“交集”除以“并集”即可得到它们之间的IOU

置信度

置信度(confidence)表示预测框与实际边界框之间的IOU,即 c o n f i d e n c e = P r ( O b j e c t ) ∗ I O U t r u t h confidence = Pr(Object)*IOU^{truth} confidence=Pr(Object)IOUtruth P r ( O b j e c t ) Pr(Object) Pr(Object) 为是否有目标,有就为1,没就是0。

置信度反映了该模型对预测框的准确程度。在设置标签时,如果该单元格中存在目标,则置信度应为1(因为有目标, P r ( O b j e c t ) = 1 Pr(Object)=1 Pr(Object)=1,并且我们希望预测框与实际边界框完全重合, I O U p r e d t r u t h = 1 IOU^{truth}_{pred}=1 IOUpredtruth=1)。如果该单元格中不存在目标,置信度应该为0。在测试时,当置信度输出为1,说明预测框与实际边界框完全重合,这是再理想不过🌈的,但如果置信度为0,那就寄了,懂吧😧😧😧

于是乎,这里有一个问题🫤⁉️,既然置信度是预测框与实际边界框之间的IOU,那么在测试的时候可没有实际边界框来让我们计算 I O U p r e d t r u t h IOU^{truth}_{pred} IOUpredtruth 噢!吾当如何?🤔主公莫怕!且听臣下细细道来。因为我们将置信度设置为了标签,所以训练的过程中,模型会不断的学习置信度的规则,使得模型最终输出的就是置信度

既然说了这么多,这里再插一嘴,提一提🫴置信度分数(confidence scores)。在测试的时候,模型会输出一堆的预测框,但并不是每个都有用的,所以需要进行筛选。至于筛选的依据是什么,这不就来咯——👉置信度分数👈

4.png

在上图中, P r ( C l a s s i ) Pr(Class_{i}) Pr(Classi) 表示类别的概率,IOU 的就不必多言了。so?置信度分数=类别概率×置信度预测值

非极大值抑制

置信度分数是为了筛选预测框而存在的,巧了🫡,NMS(非极大值抑制,Non-Maximum Suppression)也是为了筛选预测框而存在的。非极大值抑制,顾名思义,不是最大的值就要抑制了。在依据置信度分数进行初步筛选后,可能会出现如下图所示的尴尬😅的情况

5.png

图中,目标是车🚙,但这里却有3个预测框,该如何进一步的筛选,吾又当如何?😨主公莫怕!有上将 NMS,定可斩杀冗余预测框,取得目标最终预测框。NMS 的步骤其实蛮简单,排序、比较、筛选、重复以上步骤

  • 排序: 对于所有的预测框按照置信度分数进行排序
  • 比较: 选出置信度分数最大的预测框作为标准,将剩余的预测框与这一标准比较
  • 筛选: 若二者的IOU(重合度)高于阈值,则去除这一预测框

在上图中,对橙框🟧、蓝框🟦、绿框🟩根据置信度分数排序,得 [🟧0.9, 🟦0.8, 🟩0.7],最大的是 🟧0.9,将蓝框🟦、绿框🟩与橙框🟧作比较,设置阈值0.6,这里很明显啦~蓝框🟦、绿框🟩和橙框🟧的IOU值都大于阈值0.6(肉眼都看得出吧😏)

由此可见,NMS 其实在单个目标具有多个预测框的情况下进行进一步的筛选。最后,说明一下,NMS 只发生在测试阶段

检测

至此,终于进入了正文……

网格分割

我们先将输入的图像分成S×S的网格。如果目标的中心落入了某个网格中,则由该网格负责检测该目标(包括目标的边界框、类别、置信度)。下面是一张网格的可视化图,我们设置 S=7,将图像一共分成了49个网格

6.png

网格预测

虽然每个网格能够预测B个边界框(bounding box),但是在测试时,每个网格只取置信度分数最大的一个边界框作为输出

一个边界框包含5个预测:x、y、w、h和置信度。(x, y) 表示边界框中心相对于网格边界的偏置(这里的网格边界多指网格的左上角),(w, h) 是边界框的宽度和高度,置信度表示预测框与实际边界框之间的IOU

7.png

前面说 (x, y) 表示边界框中心相对于网格边界的偏置(这里的网格边界一般指网格的左上角),“边界框中心”指上图中蓝框的中心蓝点🔵,“网格的左上角”指上图中灰框的左上角红点🔴

当然,(x, y, w, h) 在设置标签的时候还需要进行归一化处理,将 (x, y) 对于网格的尺寸做归一化,(w, h) 对于整张图片的尺寸做归一化,使最终的数值介于0到1之间

非常的抱歉😞,对于 (x, y, w, h) 的部分,笔者承认写的不好,因为懒得画图,有些细节解释有不周到,读者若有不理解之处,在评论区探讨或是自寻其他资料吧🤐

同时,对于存在目标的网格,网格还负责预测C个类别。在测试时,我们将类别概率乘置信度预测值,也就是置信度分数,分数编码了该类别出现在框中的概率以及预测框拟合目标的程度

8.png

我们将图像分成S×S的网格,并让每个网格都生成B个预测框,这些预测框生成 (x, y, w, h, confidence) 以及C个类别的概率。这些预测结果被编码为 S×S×(B×5+C) 的张量(所谓的网络分割,分割体现在张量的维度S×S上

我们使用Pascal VOC数据集,使用S=7,B=2,即将图片分成7×7=49个网格,每个网格会生成2个预测框。Pascal VOC有20个类别,所以C=20。我们最终输出的是 (7, 7, 30) 的张量(30=2×5+20,2:2个预测框,5:(x, y, w, h, confidence),20:类别数)

模型构建

9.png

网络的构建受到 GoogLeNet 模型的启发。YOLOv1 网络有24个卷积层,后面是2个全连接层,网络最终输出的是 (b, 7, 7, 30) 的张量,即每个网格会生成长度为30的向量。并且对最后一层使用线性激活函数,所有其它层使用下面的 Leaky ReLU 激活函数

10.png

损失函数

11.png

我嘞个豆,精神大爆发 o((⊙﹏⊙))o。这么一串串的计算过程。先说好,笔者没喝多🍻,笔者的意思是,这里没放错图,面对疾风吧,少年

确实,损失函数的计算有亿点复杂,像是大乱炖🍲。好了,扯多了,接下来且听读者细细分析

众所周知,损失函数是计算模型输出和标签的误差。那么,还记得模型的输出的是什么吗?没错,是一个 (7, 7, 30) 的张量,这一个张量中包含了49个网格所预测的信息。每个网格的输出有B个预测框和C个预测类别

预测框中包含了 (x, y, w, h, confidence),再加上预测类别,而损失函数计算的就是预测框和预测类别与标签之间的误差。这里我们对于损失函数分段解释

说明

这里先解释一些损失函数中特殊的参数

通常的,在一张图片中,大多数网格是不包含任何对象的。这就会导致这些网格的“置信度”分数为0,从而可能导致在反向传播中压倒包含目标的网格的梯度,导致模型的不稳定

为了改善这一点,采用了以下两种方式

  1. 增加边界框坐标预测的损失
  2. 减小不包含目标边界框的置信度预测的损失

YOLOv1 使用了 λ c o o r d = 5 λ_{coord}=5 λcoord=5 λ n o o b j = 0.5 λ_{noobj}=0.5 λnoobj=0.5 参数来完成这个调整工作

训练时,我所需要关注的是出现目标的网格。所以在计算损失函数时,用 1 i j o b j 1^{obj}_{ij} 1ijobj 来表示目标是否出现在网格中。 1 i j o b j 1^{obj}_{ij} 1ijobj 表示第i个网格的第j个预测框,若出现目标则为1,没有目标则为0。 1 i j n o o b j 1^{noobj}_{ij} 1ijnoobj 则恰恰相反,当目标不存在时为1,存在目标时为0

虽然每个网格能够预测多个边界框,但是在训练时,我们只需要一个边界框来负责。在多个预测框中,我们选取与真实框之间 IOU 最高的预测框来负责预测该目标

YOLOv1 使用 SSE(平方和误差,sum-squared error)来计算各个部分的损失

坐标 (x, y) 损失

至此,正式进入损失函数的解读

12.png

∑ i = 0 S 2 ∑ j = 0 B \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} i=0S2j=0B:通过两个∑来获取到预测框, ∑ i = 0 S 2 \sum_{i=0}^{S^{2}} i=0S2 负责遍历S×S个网格, ∑ j = 0 B \sum_{j=0}^{B} j=0B 负责遍历网格输出的B个预测框

当这个预测框中存在目标则 1 i j o b j = 1 1^{obj}_{ij}=1 1ijobj=1,如若不然嘛, 1 i j o b j = 0 1^{obj}_{ij}=0 1ijobj=0

对于 [ ( x i − x i ^ ) 2 + ( y i − y i ^ ) 2 ] [(x_{i}-\widehat{x_{i}})^{2} + (y_{i}-\widehat{y_{i}})^{2}] [(xixi )2+(yiyi )2] 就显得非常简单了,使用 SSE 对 x x x y y y 求误差

宽高 (w, h) 损失

13.png

这里是和上文差不多的,若要说有什么区别,读者也一定看出来了。对w和h进行了开根号

开根号是为了体现出大的预测框和小预测框之间的区别,举个栗子🌰,大框: { w = 37 h = 18     { w ^ = 30 h ^ = 20 \left\{\begin{matrix} w = 37 \\ h = 18 \end{matrix}\right. \ \ \ \left\{\begin{matrix} \widehat{w} = 30 \\ \widehat{h} = 20 \end{matrix}\right. {w=37h=18   {w =30h =20,小框: { w = 7 h = 3     { w ^ = 14 h ^ = 5 \left\{\begin{matrix} w = 7 \\ h = 3 \end{matrix}\right. \ \ \ \left\{\begin{matrix} \widehat{w} = 14 \\ \widehat{h} = 5 \end{matrix}\right. {w=7h=3   {w =14h =5

计算得 S S E ( 大框 ) = 53 ,   S S E ( 小框 ) = 53 SSE(大框)=53,\ SSE(小框)=53 SSE(大框)=53, SSE(小框)=53,可以发现,大框和小框的损失并没有区别

但如果开了根号后,计算得 S S E ( 大框 ) = 0.31 ,   S S E ( 小框 ) = 0.95 SSE(\sqrt{大框})=0.31,\ SSE(\sqrt{小框})=0.95 SSE(大框 )=0.31, SSE(小框 )=0.95,这样二者的区别就出来了

置信度 (confidence) 损失

14.png

前面就说了 训练时,我所需要关注的是出现目标的网格,所以置信度损失的计算可分为2个部分。对包含目标的网格与不包含目标的网格进行不同的损失计算

当网格中存在目标时, 1 i j o b j = 1 ,   1 i j n o o b j = 0 ,   C i ^ = 1 1^{obj}_{ij}=1,\ 1^{noobj}_{ij}=0,\ \widehat{C_{i}}=1 1ijobj=1, 1ijnoobj=0, Ci =1,损失的计算为 ∑ i = 0 S 2 ∑ j = 0 B ( C i − 1 ) 2 \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} (C_{i}-1)^{2} i=0S2j=0B(Ci1)2,即仅计算图中算式加号➕左边的部分

当网格中不存在目标时, 1 i j o b j = 0 ,   1 i j n o o b j = 1 ,   C i ^ = 0 1^{obj}_{ij}=0,\ 1^{noobj}_{ij}=1,\ \widehat{C_{i}}=0 1ijobj=0, 1ijnoobj=1, Ci =0,损失的计算为 λ n o o b j ∑ i = 0 S 2 ∑ j = 0 B ( C i ) 2 λ_{noobj} \sum_{i=0}^{S^{2}} \sum_{j=0}^{B} (C_{i})^{2} λnoobji=0S2j=0B(Ci)2,即仅计算图中算式加号➕右边的部分

类别 (classes) 损失

15.png

类别的损失计算就显得 so easy 了。还是一样的,在损失计算中仅对存在目标的网格感兴趣。并用 SSE 计算类别的误差

模型训练

预训练

YOLOv1 先在ImageNet 1000类竞赛数据集上预训练卷积层。但是在预训练中,只使用前面的模型图的前20个卷积层,接着是平均池化层和全连接层,进行了大约一周的训练🏋️(一周的训练……劝退了)

在预训练结束后,进行模型转换,去除了原本的平均池化层和全连接层,随后增加了4个卷积层与2个全连接层。由于检测通常需要微小的视觉信息,因此我们将网络的输入分辨率从224×224提升到448×448

正式训练

YOLOv1 使用了64的批大小,0.9的动量和0.0005的衰减率,在Pascal VOC 2007和2012的训练和验证数据集上训练了约135个周期

具体的训练方案如下

  • 第1个训练周期中将学习率从0.001慢慢地提高到0.01
  • 以0.01的学习率训练75个周期
  • 以0.001的学习率训练30个周期
  • 最后用0.0001的学习率训练30个周期

为了防止过拟合,使用了 Dropout 和数据增强。在第一个全连接层之后使用 rate=0.5 的 Dropout 层。对于数据增强,引入高达原始图像20%大小的随机缩放和转换。还在HSV色彩空间中使用高达1.5的因子来随机调整图像的曝光和饱和度

总结

虽然每个格子可以预测B个边界框 ,但是最终只取置信度分数最高的边界框作为输出,一共49个网格,所以模型最多也就预测49个框。也因为这点,使得模型难以成群出现的小物体(比如鸟群,似乎这是任意模型的通病)

  • 33
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余将董道而不豫兮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值