论文地址:YOLO9000: Better, Faster, Stronger
项目主页:YOLO: Real-Time Object Detection

最近博客下很多人请求 Caffe 代码,受人所托,已经不再提供,且关闭本文评论,望请见谅

概述

时隔一年,YOLO(You Only Look Once: Unified, Real-Time Object Detection)从 v1 版本进化到了 v2 版本,作者在 darknet 主页先行一步放出源代码,论文在我们等候之下终于在 12 月 25 日发布出来,本文对论文重要部分进行了翻译理解工作,不一定完全对,如有疑问,欢迎讨论。博主如果有新的理解,也会更新文章。

新的 YOLO 版本论文全名叫 “YOLO9000: Better, Faster, Stronger”,主要有两个大方面的改进:

第一,作者使用了一系列的方法对原来的 YOLO 多目标检测框架进行了改进,在保持原有速度的优势之下,精度上得以提升。VOC 2007 数据集测试,67FPS 下 mAP 达到 76.8%,40FPS 下 mAP 达到 78.6%,基本上可以与 Faster R-CNN 和 SSD 一战。这一部分是本文主要关心的地方。

第二,作者提出了一种目标分类与检测的联合训练方法,通过这种方法,YOLO9000 可以同时在 COCO 和 ImageNet 数据集中进行训练,训练后的模型可以实现多达 9000 种物体的实时检测。这一方面本文暂时不涉及,待后面有时间再补充。

回顾 YOLOv1

YOLOv2 始终是在 v1 版本上作出的改进,我们先简单回顾 YOLOv1 的检测步骤:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图1

(1) 给个一个输入图像,首先将图像划分成 7 * 7 的网格。

(2) 对于每个网格,每个网格预测 2 个 bouding box(每个 box 包含 5 个预测量)以及 20 个类别概率,总共输出 7×7×(2*5+20)=1470 个 tensor

(3) 根据上一步可以预测出 7 7 2 = 98 个目标窗口,然后根据阈值去除可能性比较低的目标窗口,再由 NMS 去除冗余窗口即可。

YOLOv1 使用了 end-to-end 的回归方法,没有 region proposal 步骤,直接回归便完成了位置和类别的判定。种种原因使得 YOLOv1 在目标定位上不那么精准,直接导致 YOLO 的检测精度并不是很高。

YOLO 检测原理参考推荐博客:论文阅读:You Only Look Once: Unified, Real-Time Object Detection

YOLOv2 精度的改进(Better)

先来一个总览图,看看它到底用了多少技巧,以及这些技巧起了多少作用:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图2

Batch Normalization

CNN 在训练过程中网络每层输入的分布一直在改变, 会使训练过程难度加大,但可以通过 normalize 每层的输入解决这个问题。新的 YOLO 网络在每一个卷积层后添加 batch normalization,通过这一方法,mAP 获得了 2% 的提升。batch normalization 也有助于规范化模型,可以在舍弃 dropout 优化后依然不会过拟合。

High Resolution Classifier

目前的目标检测方法中,基本上都会使用 ImageNet 预训练过的模型(classifier)来提取特征,如果用的是 AlexNet 网络,那么输入图片会被 resize 到不足 256 256,导致分辨率不够高,给检测带来困难。为此,新的 YOLO 网络把分辨率直接提升到了 448 448,这也意味之原有的网络模型必须进行某种调整以适应新的分辨率输入。

对于 YOLOv2,作者首先对分类网络(自定义的 darknet)进行了 fine tune,分辨率改成 448 * 448,在 ImageNet 数据集上训练 10 轮(10 epochs),训练后的网络就可以适应高分辨率的输入了。然后,作者对检测网络部分(也就是后半部分)也进行 fine tune。这样通过提升输入的分辨率,mAP 获得了 4% 的提升。

Convolutional With Anchor Boxes

之前的 YOLO 利用全连接层的数据完成边框的预测,导致丢失较多的空间信息,定位不准。作者在这一版本中借鉴了 Faster R-CNN 中的 anchor 思想,回顾一下,anchor 是 RNP 网络中的一个关键步骤,说的是在卷积特征图上进行滑窗操作,每一个中心可以预测 9 种不同大小的建议框。看到 YOLOv2 的这一借鉴,我只能说 SSD 的作者是有先见之明的。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图3

为了引入 anchor boxes 来预测 bounding boxes,作者在网络中果断去掉了全连接层。剩下的具体怎么操作呢?首先,作者去掉了后面的一个池化层以确保输出的卷积特征图有更高的分辨率。然后,通过缩减网络,让图片输入分辨率为 416 416,这一步的目的是为了让后面产生的卷积特征图宽高都为奇数,这样就可以产生一个 center cell。作者观察到,大物体通常占据了图像的中间位置, 就可以只用中心的一个 cell 来预测这些物体的位置,否则就要用中间的 4 个 cell 来进行预测,这个技巧可稍稍提升效率。最后,YOLOv2 使用了卷积层降采样(factor 为 32),使得输入卷积网络的 416 416 图片最终得到 13 * 13 的卷积特征图(416/32=13)。

加入了 anchor boxes 后,可以预料到的结果是召回率上升,准确率下降。我们来计算一下,假设每个 cell 预测 9 个建议框,那么总共会预测 13 13 9 = 1521 个 boxes,而之前的网络仅仅预测 7 7 2 = 98 个 boxes。具体数据为:没有 anchor boxes,模型 recall 为 81%,mAP 为 69.5%;加入 anchor boxes,模型 recall 为 88%,mAP 为 69.2%。这样看来,准确率只有小幅度的下降,而召回率则提升了 7%,说明可以通过进一步的工作来加强准确率,的确有改进空间。

Dimension Clusters(维度聚类)

作者在使用 anchor 的时候遇到了两个问题,第一个是 anchor boxes 的宽高维度往往是精选的先验框(hand-picked priors),虽说在训练过程中网络也会学习调整 boxes 的宽高维度,最终得到准确的 bounding boxes。但是,如果一开始就选择了更好的、更有代表性的先验 boxes 维度,那么网络就更容易学到准确的预测位置。

和以前的精选 boxes 维度不同,作者使用了 K-means 聚类方法类训练 bounding boxes,可以自动找到更好的 boxes 宽高维度。传统的 K-means 聚类方法使用的是欧氏距离函数,也就意味着较大的 boxes 会比较小的 boxes 产生更多的 error,聚类结果可能会偏离。为此,作者采用的评判标准是 IOU 得分(也就是 boxes 之间的交集除以并集),这样的话,error 就和 box 的尺度无关了,最终的距离函数为:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图4

作者通过改进的 K-means 对训练集中的 boxes 进行了聚类,判别标准是平均 IOU 得分,聚类结果如下图:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图5

可以看到,平衡复杂度和 IOU 之后,最终得到 k 值为 5,意味着作者选择了 5 种大小的 box 维度来进行定位预测,这与手动精选的 box 维度不同。结果中扁长的框较少,而瘦高的框更多(这符合行人的特征),这种结论如不通过聚类实验恐怕是发现不了的。

当然,作者也做了实验来对比两种策略的优劣,如下图,使用聚类方法,仅仅 5 种 boxes 的召回率就和 Faster R-CNN 的 9 种相当。说明 K-means 方法的引入使得生成的 boxes 更具有代表性,为后面的检测任务提供了便利。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图6

Direct location prediction(直接位置预测)

那么,作者在使用 anchor boxes 时发现的第二个问题就是:模型不稳定,尤其是在早期迭代的时候。大部分的不稳定现象出现在预测 box 的 坐标上了。在区域建议网络中,预测 以及 , 使用的是如下公式:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图7

后来修改博文时,发现这个公式有误,作者应该是把加号写成了减号。理由如下,anchor 的预测公式来自于 Faster-RCNN,我们来看看人家是怎么写的:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图8

公式中,符号的含义解释一下: 是坐标预测值, 是 anchor 坐标(预设固定值), 是坐标真实值(标注信息),其他变量 ,, 以此类推, 变量是偏移量。然后把前两个公式变形,就可以得到正确的公式:

这个公式的理解为:当预测 ,就会把 box 向右边移动一定距离(具体为 anchor box 的宽度),预测 ,就会把 box 向左边移动相同的距离。

这个公式没有任何限制,使得无论在什么位置进行预测,任何 anchor boxes 可以在图像中任意一点结束(我的理解是, 没有数值限定,可能会出现 anchor 检测很远的目标 box 的情况,效率比较低。正确做法应该是每一个 anchor 只负责检测周围正负一个单位以内的目标 box)。模型随机初始化后,需要花很长一段时间才能稳定预测敏感的物体位置。

在此,作者就没有采用预测直接的 offset 的方法,而使用了预测相对于 grid cell 的坐标位置的办法,作者又把 ground truth 限制在了 0 到 1 之间,利用 logistic 回归函数来进行这一限制。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图9

现在,神经网络在特征图(13 *13 )的每个 cell 上预测 5 个 bounding boxes(聚类得出的值),同时每一个 bounding box 预测 5 个坐值,分别为 ,其中前四个是坐标,是置信度。如果这个 cell 距离图像左上角的边距为 以及该 cell 对应 box(bounding box prior)的长和宽分别为 ,那么预测值可以表示为:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图10

这几个公式参考上面 Faster-RCNN 和 YOLOv1 的公式以及下图就比较容易理解。 经 sigmod 函数处理过,取值限定在了 0~1,实际意义就是使 anchor 只负责周围的 box,有利于提升效率和网络收敛。 函数的意义没有给,但估计是把归一化值转化为图中真实值,使用 的幂函数是因为前面做了 计算,因此,是 bounding box 的中心相对栅格左上角的横坐标,是纵坐标,是 bounding box 的 confidence score。

定位预测值被归一化后,参数就更容易得到学习,模型就更稳定。作者使用 Dimension Clusters 和 Direct location prediction 这两项 anchor boxes 改进方法,mAP 获得了 5% 的提升。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图11

Fine-Grained Features(细粒度特征)

上述网络上的修改使 YOLO 最终在 13 13 的特征图上进行预测,虽然这足以胜任大尺度物体的检测,但是用上细粒度特征的话,这可能对小尺度的物体检测有帮助。Faser R-CNN 和 SSD 都在不同层次的特征图上产生区域建议(SSD 直接就可看得出来这一点),获得了多尺度的适应性。这里使用了一种不同的方法,简单添加了一个转移层( passthrough layer),这一层要把浅层特征图(分辨率为 26 26,是底层分辨率 4 倍)连接到深层特征图。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图12

这个转移层也就是把高低两种分辨率的特征图做了一次连结,连接方式是叠加特征到不同的通道而不是空间位置,类似于 Resnet 中的 identity mappings。这个方法把 26 26 512 的特征图连接到了 13 13 2048 的特征图,这个特征图与原来的特征相连接。YOLO 的检测器使用的就是经过扩张的特征图,它可以拥有更好的细粒度特征,使得模型的性能获得了 1% 的提升。(这段理解的也不是很好,要看到网络结构图才能清楚)

补充:关于 passthrough layer,具体来说就是特征重排(不涉及到参数学习),前面 26 26 512 的特征图使用按行和按列隔行采样的方法,就可以得到 4 个新的特征图,维度都是 13 13 512,然后做 concat 操作,得到 13 13 2048 的特征图,将其拼接到后面的层,相当于做了一次特征融合,有利于检测小目标。

Multi-Scale Training

原来的 YOLO 网络使用固定的 448 448 的图片作为输入,现在加入 anchor boxes 后,输入变成了 416 416。目前的网络只用到了卷积层和池化层,那么就可以进行动态调整(意思是可检测任意大小图片)。作者希望 YOLOv2 具有不同尺寸图片的鲁棒性,因此在训练的时候也考虑了这一点。

不同于固定输入网络的图片尺寸的方法,作者在几次迭代后就会微调网络。没经过 10 次训练(10 epoch),就会随机选择新的图片尺寸。YOLO 网络使用的降采样参数为 32,那么就使用 32 的倍数进行尺度池化 {320,352,…,608}。最终最小的尺寸为 320 320,最大的尺寸为 608 608。接着按照输入尺寸调整网络进行训练。

这种机制使得网络可以更好地预测不同尺寸的图片,意味着同一个网络可以进行不同分辨率的检测任务,在小尺寸图片上 YOLOv2 运行更快,在速度和精度上达到了平衡。

在小尺寸图片检测中,YOLOv2 成绩很好,输入为 228 * 228 的时候,帧率达到 90FPS,mAP 几乎和 Faster R-CNN 的水准相同。使得其在低性能 GPU、高帧率视频、多路视频场景中更加适用。

在大尺寸图片检测中,YOLOv2 达到了先进水平,VOC2007 上 mAP 为 78.6%,仍然高于平均水准,下图是 YOLOv2 和其他网络的成绩对比:

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图13

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图14

Further Experiments

作者在 VOC2012 上对 YOLOv2 进行训练,下图是和其他方法的对比。YOLOv2 精度达到了 73.4%,并且速度更快。同时 YOLOV2 也在 COCO 上做了测试(IOU=0.5),也和 Faster R-CNN、SSD 作了成绩对比。总的来说,比上不足,比下有余。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图15

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图16

YOLOv2 速度的改进(Faster)

YOLO 一向是速度和精度并重,作者为了改善检测速度,也作了一些相关工作。

大多数检测网络有赖于 VGG-16 作为特征提取部分,VGG-16 的确是一个强大而准确的分类网络,但是复杂度有些冗余。224 * 224 的图片进行一次前向传播,其卷积层就需要多达 306.9 亿次浮点数运算。

YOLOv2 使用的是基于 Googlenet 的定制网络,比 VGG-16 更快,一次前向传播仅需 85.2 亿次运算。可是它的精度要略低于 VGG-16,单张 224 * 224 取前五个预测概率的对比成绩为 88% 和 90%(低一点点也是可以接受的)。

Darknet-19

YOLOv2 使用了一个新的分类网络作为特征提取部分,参考了前人的先进经验,比如类似于 VGG,作者使用了较多的 3 3 卷积核,在每一次池化操作后把通道数翻倍。借鉴了 network in network 的思想,网络使用了全局平均池化(global average pooling),把 1 1 的卷积核置于 3 * 3 的卷积核之间,用来压缩特征。也用了 batch normalization(前面介绍过)稳定模型训练。

最终得出的基础模型就是 Darknet-19,如下图,其包含 19 个卷积层、5 个最大值池化层(maxpooling layers ),下图展示网络具体结构。Darknet-19 运算次数为 55.8 亿次,imagenet 图片分类 top-1 准确率 72.9%,top-5 准确率 91.2%。

YOLOv2 论文笔记_Jesse_Mx的博客-CSDN博客 - 图17

Training for classification

作者使用 Darknet-19 在标准 1000 类的 ImageNet 上训练了 160 次,用的随机梯度下降法,starting learning rate 为 0.1,polynomial rate decay 为 4,weight decay 为 0.0005 ,momentum 为 0.9。训练的时候仍然使用了很多常见的数据扩充方法(data augmentation),包括 random crops, rotations, and hue, saturation, and exposure shifts。 (这些训练参数是基于 darknet 框架,和 caffe 不尽相同)

初始的 224 224 训练后,作者把分辨率上调到了 448 448,然后又训练了 10 次,学习率调整到了 0.001。高分辨率下训练的分类网络在 top-1 准确率 76.5%,top-5 准确率 93.3%。

Training for detection

分类网络训练完后,就该训练检测网络了,作者去掉了原网络最后一个卷积层,转而增加了三个 3 3 1024 的卷积层(可参考 darknet 中 cfg 文件),并且在每一个上述卷积层后面跟一个 1 1 的卷积层,输出维度是检测所需的数量。对于 VOC 数据集,预测 5 种 boxes 大小,每个 box 包含 5 个坐标值和 20 个类别,所以总共是 5 (5+20)= 125 个输出维度。同时也添加了转移层(passthrough layer ),从最后那个 3 3 512 的卷积层连到倒数第二层,使模型有了细粒度特征。

作者的检测模型以 0.001 的初始学习率训练了 160 次,在 60 次和 90 次的时候,学习率减为原来的十分之一。其他的方面,weight decay 为 0.0005,momentum 为 0.9,依然使用了类似于 Faster-RCNN 和 SSD 的数据扩充(data augmentation)策略。

YOLOv2 分类的改进(Stronger)

这一部分,作者使用联合训练方法,结合 wordtree 等方法,使 YOLOv2 的检测种类扩充到了上千种,具体内容待续。

总结和展望

作者大概说的是,之前的技术改进对检测任务很有帮助,在以后的工作中,可能会涉足弱监督方法用于图像分割。监督学习对于标记数据的要求很高,未来要考虑弱标记的技术,这将会极大扩充数据集,提升训练量。

扩展阅读:deepsystems.io:Illustration of YOLO
https://blog.csdn.net/Jesse_Mx/article/details/53925356?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param