YOLO v1 详解

YOLO v1 详解

    • 一、网络详解
      • (一)网络结构
      • (二)输入
      • (三)输出
        • 1. 7 x 7 部分
        • 2. 30 通道部分
    • 二、网络训练
      • (一)训练样本构造
      • (二)损失函数
      • (三)训练细节
    • 三、网络预测

You Only Look Once: Unified, Real-Time Object Detection

论文链接


  YOLO v1 是典型的 one-stage 的算法。相对于 Faster R-CNN,YOLO v1 不需要分别训练各个部分的网络,可以实现 end-to-end 的训练。YOLO v1 有着更高的检测速度,可以用于视频的检测。

YOLO v1 详解_第1张图片

图 1:Bounding Box 回归和最终类别的关系。

  人类只用看一眼图片就能大体了解到在各个方位有哪些感兴趣的物体。而对比 Faster R-CNN,我们实际上看了 2 眼图片。那么有没有一种方法能让我们只看 1 眼,并且快速定位物体呢?YOLO v1 就是这样。YOLO v1 的核心思想是直接对 Bounding Box 进行回归然后进行类别的预测。 换句话说 Bounding Box 的回归和最终物体的类别是有很大的关系的。例如图一,我们只用看第一幅图,就能想到猫的耳朵和屁股的大致位置。

  对于 Faster R-CNN,第一步我们要生成大量的 anchor,用于 RPN 网络判断 objectness 和边框的微调。那么既然最后会调整 anchor 的边界框,我们就没有必要生成那么多的 anchor,只生成大致的区域就行。类比 YOLO v1,我们在一开始生成少量的预测区域(在 YOLO v1 中没有 anchor)后直接对预测区域进行微调,并给出其对应的物体类别,就可以得到最终的输出结果。这样的方法,要比 Faster R-CNN 速度快很多。


一、网络详解


YOLO v1 详解_第2张图片

图 2:详细的网络结构


(一)网络结构


YOLO v1 详解_第3张图片

图 3:YOLO v1 的网络大体结构

  去掉生成 region proposals 这个步骤以后,YOLO v1的结构非常简单,就是单纯的卷积、池化最后加了两层全连接。单看网络结构的话,和普通的 CNN 对象分类网络几乎没有本质的区别,最大的差异是最后输出层用线性函数做激活函数,因为需要预测 bounding box 的位置(数值型),而不仅仅是对象的概率。所以粗略来说,YOLO 的整个结构就是输入图片经过神经网络的变换得到一个输出的张量,如图 3 所示。

  因为只是一些常规的神经网络结构,所以,理解 YOLO v1 的设计的时候,重要的是理解输入和输出的映射关系。


(二)输入


  对于输入,我们将常见网络输入的 224 x 224 的大小放大 2 倍,采用固定的尺度 448 x 448。


(三)输出


网络的输出为 7 x 7 x 30 的张量,那么这 7 x 7 x 30 的输出代表什么含义呢?我们分别来看一看。


1. 7 x 7 部分

YOLO v1 详解_第4张图片

图 4:YOLO v1 的步骤

  对于 YOLO v1,当图片输入网络时我们先要将输入图片平均分成 S x S 个大小相同的网格(见上图)。然后对每个网格生成 B 个 Bounding Box,这个生成的 Bounding Box 就是我们最终要输出的 Bounding Box。所以生成的总 Bounding Box 的个数为 S × S × B S \times S \times B S×S×B

  需要理解的是,这个 Bounding Box 并不是 Faster R-CNN 中的 anchor。Faster RCNN 等一些算法采用每个 grid 中手工设置 n 个 Anchor(先验框,预先设置好位置的 bounding box)的设计,每个 Anchor 有不同的大小和宽高比。YOLO 的 bounding box 看起来很像一个 grid 中 2 个 Anchor,但它们不是。YOLO 并没有预先设置 2 个 bounding box 的大小和形状,也没有对每个 bounding box 分别输出一个对象的预测。它的意思仅仅是对一个对象预测出 2 个 bounding box,在训练只选择预测得相对比较准的那个。

  这里的 bounding box,有点像不完全算监督算法,而是像进化算法。如果是监督算法,我们需要事先根据样本就能给出一个正确的 bounding box 作为回归的目标。但 YOLO 的 2 个 bounding box 事先并不知道会在什么位置,只有经过前向计算,网络会输出 2 个 bounding box,这两个 bounding box 与样本中对象实际的 bounding box 计算 IOU。这时才能确定,IOU 值大的那个 bounding box,作为负责预测该对象的 bounding box。

  训练开始阶段,网络预测的 bounding box 可能都是乱来的,但总是选择 IOU 相对好一些的那个,随着训练的进行,每个 bounding box 会逐渐擅长对某些情况的预测(可能是对象大小、宽高比、不同类型的对象等)。所以,这是一种进化或者非监督学习的思想。

  这里作者使用的 S = 7、B = 2。输出张量中的 7 x 7 个值就对应着输入图像的 7 x 7 网格。或者我们把 7 x 7 x 30 的张量看作 7 x 7 = 49 个 30 维的向量,也就是输入图像中的每个网格对应输出一个 30 维的向量(见下图)

YOLO v1 详解_第5张图片

图 5:对于原始图像中的每个网格都对应最终结果的一行输出。


2. 30 通道部分

YOLO v1 详解_第6张图片

图 6:30 个通道的含义

30 个通道包含了如下 3 个部分:

(1)20 个对象分类的概率

  因为 YOLO 支持识别 20 种不同的对象(人、鸟、猫、汽车、椅子等),所以这里有 20 个值表示该网格位置存在任一种对象的概率。可以记为 P ( C 1 ∣ O b j e c t ) , . . . , P ( C i ∣ O b j e c t ) , . . . , P ( C 20 ∣ O b j e c t ) P(C_1|Object),...,P(C_i|Object),...,P(C_{20}|Object) P(C1Object),...,P(CiObject),...,P(C20Object) 。之所以写成条件概率,意思是如果该网格存在一个对象 Object,那么它是 C i C_i Ci 类别的概率为 P ( C i ∣ O b j e c t ) P(C_i|Object) P(CiObject)。(条件概率)


(2)2 个 bounding box 的置信度

  bounding box 的置信度 = 该 bounding box 内存在对象的概率 * 该 bounding box 与该对象实际 bounding box 的 IOU。用公式来表示就是
C o n f i d e n c e = P r ( O b j e c t ) × I O U p r e d t r u e Confidence=Pr(Object) \times IOU_{pred}^{true} Confidence=Pr(Object)×IOUpredtrue

P r ( O b j e c t ) Pr(Object) Pr(Object) 是存在对象的概率。区别于(1)的 P ( C i ∣ O b j e c t ) P(C_i|Object) P(CiObject) P r ( O b j e c t ) Pr(Object) Pr(Object) 不管是哪个对象,它体现的是有或没有对象的概率。(1)中的 P ( C i ∣ O b j e c t ) P(C_i|Object) P(CiObject) 是假设已经有一个对象在网格中了,这个对象具体是哪一个类别。

   I O U p r e d t r u e IOU_{pred}^{true} IOUpredtrue 是 bounding box 与 对象真实 bounding box 的 IOU(Intersection over Union,交并比)。要注意的是,现在讨论的 30 维向量中的 bounding box 是 YOLO 网络的输出,也就是预测的 bounding box。所以 I O U p r e d t r u e IOU_{pred}^{true} IOUpredtrue 体现了预测的 bounding box 与真实 bounding box 的接近程度。

  还要说明的是,虽然有时说"预测"的 bounding box,但这个 IOU 是在训练阶段计算的。等到了测试阶段(Inference),这时并不知道真实对象在哪里,只能完全依赖于网络的输出,这时已经不需要(也无法)计算 IOU 了。

  综合来说,一个 bounding box 的置信度 Confidence 意味着它是否包含对象且位置准确的程度。置信度高表示这里存在一个对象且位置比较准确,置信度低表示可能没有对象或者即便有对象也存在较大的位置偏差。


(3)2 个 bounding box 的位置

  每个 bounding box 需要 4 个数值来表示其位置,( C e n t e r x Center_x Centerx, C e n t e r y Center_y Centery, w i d t h width width, h e i g h t height height),即 bounding box 的中心点的 x 坐标,y 坐标,bounding box 的宽度,高度。注意在 YOLO 中预测的坐标都是 Bounding Box 的中点。这里有 2 个 bounding box 共需要 8 个数值来表示其位置。


总结来说,30 维向量 = 20 个对象的概率 + 2 个 bounding box 的置信度+ 2 个 bounding box * 4 个坐标

更一般的:最终网络的输出就是 S × S × ( C + B × ( 4 + 1 ) ) S \times S \times (C+B\times(4+1)) S×S×(C+B×(4+1)),其中 C 为目标检测类别数。


二、网络训练


(一)训练样本构造

YOLO v1 详解_第7张图片

图 7:构造训练样本

  作为监督学习,我们需要先构造好训练样本,才能让模型从中学习。那么 如何构造训练样本 呢?对于一张输入图片,其对应输出的 7 x 7 x 30 张量(也就是通常监督学习所说的标签 y 或者 label)应该填写什么数据呢?


(1)20 个对象分类的概率

  对于输入图像中的每个对象,先找到其中心点。比如图 7 中的自行车,其中心点在黄色圆点位置,中心点落在黄色网格内,所以这个黄色网格对应的 30 维向量中,自行车的那个值的概率是1,其它对象的概率是0。所有其它 48 个网格的 30 维向量中,该自行车的概率都是0。这就是所谓的"中心点所在的网格对预测该对象负责"。狗和汽车的分类概率也是同样的方法填写。


(2)2 个 bounding box 的位置
  训练样本的 bounding box 位置应该填写对象实际的 bounding box,但一个对象对应了2个 bounding box,该填哪一个呢?上面讨论过,需要根据网络输出的 bounding box 与对象实际 bounding box 的 IOU 来选择,所以要在训练过程中动态决定到底填哪一个 bounding box。参考下面第(3)点。


(3)2 个 bounding box 的置信度

  上面讨论过置信度公式:
C o n f i d e n c e = P r ( O b j e c t ) × I O U p r e d t r u e Confidence=Pr(Object) \times IOU_{pred}^{true} Confidence=Pr(Object)×IOUpredtrue

   I O U p r e d t r u e IOU_{pred}^{true} IOUpredtrue 可以直接计算出来,就是用网络输出的 2 个 bounding box 与对象真实 bounding box 一起计算出 IOU。
然后看 2 个 bounding box 的 IOU,哪个比较大(更接近对象实际的 bounding box),就由哪个 bounding box 来负责预测该对象是否存在,即该 bounding box 的 P r ( O b j e c t ) = 1 Pr(Object)=1 Pr(Object)=1,同时对象真实 bounding box 的位置也就填入该 bounding box。另一个不负责预测的 bounding box 的 P r ( O b j e c t ) = 0 Pr(Object)=0 Pr(Object)=0

  总的来说就是,与对象实际 bounding box 最接近的那个 bounding box,其 C o n f i d e n c e = I O U p r e d t r u e Confidence=IOU_{pred}^{true} Confidence=IOUpredtrue,该网格的其它 bounding box 的 C o n f i d e n c e = 0 Confidence=0 Confidence=0

  举个例子,比如上图中自行车的中心点位于 4 行 3 列网格中,所以输出 tensor 中 4 行 3 列位置的 30 维向量如下图所示。

YOLO v1 详解_第8张图片

图 8:训练样本的一个30维向量

  注意,图中将自行车的位置放在 bounding box1,但实际上是在训练过程中等网络输出以后,比较两个 bounding box 与自行车实际位置的 IOU,自行车的位置(实际 bounding box)放置在 IOU 比较大的那个 bounding box(图中假设是bounding box1),且该 bounding box 的置信度设为 1。


(二)损失函数

YOLO v1 详解_第9张图片

图 9:YOLO v1 损失函数

公式中:
1 i o b j 1_{i}^{obj} 1iobj 意思是网格 i 中存在对象。
1 i j o b j 1_{ij}^{obj} 1ijobj意思是网格 i 的第 j 个 bounding box 中存在对象。
1 i j n o o b j 1_{ij}^{noobj} 1ijnoobj意思是网格 i 的第 j 个 bounding box 中不存在对象。

总的来说,就是用网络输出与样本标签的各项内容的误差平方和作为一个样本的整体误差。


(三)训练细节

  YOLO 先使用 ImageNet 数据集对前20层卷积网络进行预训练,然后使用完整的网络,在 PASCAL VOC 数据集上进行对象识别和定位的训练和预测。YOLO 的网络结构如下图所示:

YOLO v1 详解_第10张图片

  YOLO 的最后一层采用线性激活函数,其它层都是 Leaky ReLU。训练中采用了 drop out 和数据增强(data augmentation)来防止过拟合。更多细节请参考原论文。


三、网络预测


  训练好的 YOLO 网络,输入一张图片,将输出一个 7 x 7 x 30 的张量(tensor)来表示图片中所有网格包含的对象(概率)以及该对象可能的 2 个位置(bounding box)和可信程度(置信度)。

  为了从中提取出最有可能的那些对象和位置,YOLO 采用 NMS(Non-maximal suppression,非极大值抑制)算法。NMS 方法并不复杂,其核心思想是:选择得分最高的作为输出,与该输出重叠的去掉,不断重复这一过程直到所有备选处理完。


YOLO 的 NMS 计算方法如下:

  网络输出的 7 x 7 x 30 的张量,在每一个网格中,对象 C i C_i Ci 位于第 j 个 bounding box 的得分:

S c o r e i j = P ( C i ∣ O b j e c t ) × C o n f i d e n c e j Score_{ij}=P(C_i|Object)\times Confidence_j Scoreij=P(CiObject)×Confidencej

  它代表着某个对象 C i C_i Ci 存在于第 j 个 bounding box 的可能性。

  每个网格有:20 个对象的概率 * 2 个bounding box的置信度,共 40 个得分(候选对象)。49 个网格共 1960 个得分。Andrew Ng 建议每种对象分别进行 NMS,那么每种对象有 1960/20=98 个得分。

NMS 步骤如下:
1)设置一个 Score 的阈值,低于该阈值的候选对象排除掉(将该 Score 设为 0)
2)遍历每一个对象类别
 2.1)遍历该对象的 98 个得分
  2.1.1)找到 Score 最大的那个对象及其 bounding box,添加到输出列表
  2.1.2)对每个 Score 不为 0 的候选对象,计算其与上面 2.1.1 输出对象的 bounding box 的 IOU
  2.1.3)根据预先设置的 IOU 阈值,所有高于该阈值(重叠度较高)的候选对象排除掉(将 Score 设为 0)
  2.1.4)如果所有 bounding box 要么在输出列表中,要么 Score=0,则该对象类别的 NMS 完成,返回步骤 2 处理下一种对象
3)输出列表即为预测的对象



参考链接:
https://arxiv.org/pdf/1506.02640.pdf
https://www.jianshu.com/p/cad68ca85e27

你可能感兴趣的:(目标检测)