YOLO算法解读

本文以从头实现YOLO的角度出发,解释了YOLO目标检测框架。本文不会描述网络的优点/缺点或每个设计选择的原因,而是关注于它是如何工作的。在阅读本文之前,假设读者对神经网络,特别是CNN有一个基本的了解。

文中所有的描述都与YOLO的原论文有关: You Only Look Once: Unified, Real-Time Object Detection by Joseph Redmon, Santosh Divvala, Ross Girshick and Ali Farhadi (2015). 从那时起,已经有了很多改进的建议,这些改进在新的YOLOv2版本中得到了结合,我可能会在下次的文章中写到。首先理解这个原始版本更容易,然后再看做了哪些更改以及为什么进行更改。

YOLO是什么?

YOLO (You Only Look Once),是一个用于目标检测的网络。目标检测任务包括确定图像中存在某些对象的位置,以及对这些对象进行分类。以前的方法,比如R-CNN和它的变种,使用一个管道在多个步骤中执行这个任务。这可能运行缓慢,也很难优化,因为每个单独的组件都必须单独训练。YOLO,只用一个神经网络就能搞定。原文中提到:

We reframe the object detection as a single regression problem, straight from image pixels to bounding box coordinates and class probabilities.

简单地说,拿一个图像作为输入,通过一个看起来像普通CNN的神经网络,你就会得到一个在输出中包含边界框和类别预测的向量。

那么,这些预测是什么样的呢?

预测向量

理解YOLO的第一步是如何编码输出。输入图像被分割成一个S x S网格单元格。对于图像中出现的每个对象,一个网格单元负责预测它。这就是物体中心所在的单元格。

每个网格单元预测B个边界框以及C个类别的概率。边界框的预测有5个组成部分:(x, y, w, h, confidence)。(x, y)坐标表示框的中心,相对于网格单元格位置(记住,如果框的中心不落在网格单元格内,则此单元格不负责)。这些坐标被归一化在0到1之间。(w, h)框的尺寸也被归一化到[0, 1],相对于图像的大小。让我们来看一个例子:
在这里插入图片描述
在边界框预测中还有一个部分,即置信度:

Formally we define confidence as Pr(Object) * IOU(pred, truth) . If no object exists in that cell, the confidence score should be zero. Otherwise we want the confidence score to equal the intersection over union (IOU) between the predicted box and the ground truth.

注意,置信度反映了任何类对象的存在或不存在,如果不知道什么是IOU,请看这里.

现在我们已经了解了边界框预测的5个组成部分,记住每个网格单元做了B次这样的预测,所以总共有S x S x B x 5个与边界框预测相关的输出。

还需要预测类别的概率Pr(class (i) |Object)。这个概率取决于包含一个对象的网格单元。在实践中,这意味着如果网格单元中没有对象,损失函数将不会因为错误的类别预测而进行惩罚,我们将在后面看到这一点。一个网络只预测每个单元格的一组类别概率,而与边界框的数量无关。这里会得到总共S x S x C个类别概率。

将类别预测加到输出向量中,我们得到一个S x S x (B x 5 +C)的张量作为输出。
在这里插入图片描述

网络

一旦你理解了预测是如何编码的,剩下的就很简单了。网络结构看起来像一个普通的CNN,有卷积层和最大池化层,最后是两个全连接层:
在这里插入图片描述
关于框架:

  • 注意,该体系结构是为Pascal VOC数据集而设计的,其中作者使用了S=7、B=2和C=20。这解释了为什么最终的feature map是7x7,也解释了输出的大小(7x7x(2*5+20))。使用具有不同网格大小或不同数量的类别的网络可能需要调整维度。
  • 作者提到有一个快速版本的YOLO,有更少的卷积层。不过上面的表格展示的是完整的版本。
  • 1x1简化层和3x3卷积层的部分主要是根据GoogLeNet (Inception)模型得到的启发
  • 最后一层使用线性激活函数。而所有其他层使用leaky RELU(如果x > 0,Φ(x)= x,否则为0.1x)

损失函数

关于损失函数有很多东西要讲,我们分几部分来做。首先:
在这里插入图片描述
这个方程计算了与预测的边界框位置(x, y)相关的损失。不要担心λ,暂时认为它是一个给定的常数。该函数计算所有网格(i = 0 …S ^ 2)中所有边界框预测器的和(j = 0…B)。𝟙obj定义为:

  • 1, 如果一个对象存在于网格单元i中,第j个边界框预测器“负责”该预测
  • 0, 其他情况

但是我们怎么知道哪个预测器对物体负责呢?引用原文:

YOLO predicts multiple bounding boxes per grid cell. At training time we only want one bounding box predictor to be responsible for each object. We assign one predictor to be “responsible” for predicting an object based on which prediction has the highest current IOU with the ground truth.

方程中的其他项应该是容易理解的:(x,y)为预测的边界框位置,(x̂, ŷ)为训练数据的实际位置。

来看第二部分:
在这里插入图片描述

这是与预测边界框宽度/高度相关的损失。这个方程和第一个方程很相似,除了平方根。这是怎么回事?再次引用原文:

Our error metric should reflect that small deviations in large boxes matter less than in small boxes. To partially address this we predict the square root of the bounding box width and height instead of the width and height directly.

第三部分:
在这里插入图片描述
在这里,我们计算与每个边界框预测器的置信度得分相关的损失。C是置信度得分,Ĉ是预测的边界框与真值的IOU。𝟙obj等于1时,说明在网格中存在目标,而其他情况为0。𝟙 noobj 则代表相反的情况。

The λ parameters that appear here and also in the first part are used to differently weight parts of the loss functions. This is necessary to increase model stability. The highest penalty is for coordinate predictions (λ coord = 5) and the lowest for confidence predictions when no object is present (λ noobj = 0.5).出现在这里的λ参数,同第一部分的λ一样,用于为损失函数的不同部分指定权重。这对于提高模型的稳定性是必要的。最高惩罚(λcoord = 5)用于坐标预测,最低惩罚用于当没有对象存在时的置信度预测(λnoobj = 0.5)。

损失函数的最后一部分是分类损失:
在这里插入图片描述
它看起来类似于分类中的常规的平方和误差,除了𝟙obj。之所以使用它,是因为当单元格上没有对象时,我们不会惩罚分类错误(因此前面讨论了条件概率)。

训练

作者用以下方式描述了训练过程:

  • 首先,使用ImageNet 1000-class 竞赛数据集预训练前20个卷积层,输入大小为224x224
  • 然后,将输入分辨率提高到448x448
  • 配置批次大小为64,动量为0.9,衰减为0.0005,训练整个网络135个epoch
  • 学习率进度:第一个epoch,学习率从0.001缓慢提高到0.01。训练大约75个epoch,然后开始减少。
  • 使用随机缩放和平移,随机调整曝光和饱和度,将数据增强。本文对这一过程进行了较详细的描述。
阅读更多

没有更多推荐了,返回首页