前言:YOLO V1 问世已久,风头很快就被SSD盖过,原作者rbg(Ross Girshick)大神自然不甘心,于是又在yolo v1的基础之上提出了YOLO v2 ,根据论文中的总结,yolo v2在yolo v1的基础之上一共有10个主要的改进点,本文是结合网上的众多博客文章,用自己习惯的方式做了一个简单地整理。
前言:YOLO V1 问世已久,风头很快就被SSD盖过,原作者rbg(Ross Girshick)大神自然不甘心,于是又在yolo v1的基础之上提出了YOLO v2 ,根据论文中的总结,yolo v2在yolo v1的基础之上一共有10个主要的改进点,本文是结合网上的众多博客文章,用自己习惯的方式做了一个简单地整理。
一、YOLO V2概览
二、YOLO V2相比于YOLO V1的改进点
三、YOLO V2的10大改进点剖析(Better)
3.1 Batch Normalization
3.2 High Resolution Classifier
3.3 Convolutional With Anchor Boxes
3.4 Dimension Clusters (维度聚类
3.5 Direct location prediction(直接位置预测)
3.6 Fine-Grained Features(细粒度特征)
3.7 Multi-Scale Training
四、YOLO V2的10大改进点剖析(Faster)
4.1 Darknet-19 架构
4.2 Training for Classification (分类的训练技巧)
4.3 Training for Detection (检测时的训练技巧)
五、YOLO V2的10大改进点剖析(Stronger)
YOLO V2的原始论文是,《YOLO9000: Better, Faster, Stronger 》,新的YOLO版本论文全名叫“YOLO9000: Better, Faster, Stronger”,主要有两个大方面的改进:
第一,作者使用了一系列的方法对原来的YOLO多目标检测框架进行了改进,在保持原有速度的优势之下,精度上得以提升。VOC 2007数据集测试,67FPS下mAP达到76.8%,40FPS下mAP达到78.6%,基本上可以与Faster R-CNN和SSD一战。这是它特别牛的地方,
第二,作者提出了一种目标分类与检测的联合训练方法,通过这种方法,YOLO9000可以同时在COCO和ImageNet数据集中进行训练,训练后的模型可以实现多达9000种物体的实时检测。这是非常不容易的,一下子看可以检测9000种物体类别,是一个大的飞跃。
那为什么论文的名字不叫yolo v2,而是yolo9000呢?
其实yolo9000是在YOLO V2的基础之上提出的,可以产生9418个类别的目标检测,至于为什么是这个名字,我想是因为它可以一次性检测9000多种物体吧。
可以看出,YOLO V2相比于前一个版本YOLO V1,一共有10个点的改进措施,而且每一个措施都带来了性能上的提升,总的mAP从63.4%提升到了78.6%,基本上跟faster-RCNN和SSD在伯仲之间。
既然论文的标题为 Better、Faster、Stronger,下面也将从这三个大的方面来看
3.1 Batch Normalization
CNN在训练过程中网络每层输入的分布一直在改变, 会使训练过程难度加大,但可以通过normalize每层的输入解决这个问题。新的YOLO网络在每一个卷积层后添加batch normalization,通过这一方法,mAP获得了2%的提升。batch normalization 也有助于规范化模型,可以在舍弃dropout优化后依然不会过拟合。
现在BN已经是任何网络架构的基本组件了
3.2 High Resolution Classifier
现在基本跑个分类或目标检测模型都不会从随机初始化所有参数开始,所以一般都是用预训练的网络来fine-tuning自己的网络,而且预训练的网络基本上都是在ImageNet数据集上跑的,一方面数据量大,另一方面训练时间久,而且也比较容易得到。
YOLOv1在预训练的时候用的是224*224的输入,一般预训练的分类模型都是在ImageNet数据集上进行的,然后在检测的时候采用448*448的输入。这会导致从分类模型切换到检测模型的时候,模型还要适应图像分辨率的改变。
YOLOv2中将预训练分成两步:先用224*224的输入从头开始训练网络,大概160个epoch,然后再将输入调整到448*448,再训练10个epoch。
注意:这两步都是在ImageNet数据集上操作。最后再在检测的数据集上fine-tuning,也就是检测的时候用448*448的图像作为输入就可以顺利过渡了。
3.3 Convolutional With Anchor Boxes
之前的YOLO利用全连接层的数据完成边框的预测,导致丢失较多的空间信息,定位不准。作者在这一版本中借鉴了Faster R-CNN中的anchor思想,
什么是anchor呢?
我在上一篇文章中已经非常清晰的说明了anchor到底是什么,参考:https://blog.csdn.net/qq_27825451/article/details/88843333
为了引入anchor boxes来预测bounding boxes,作者使用了一下几个技术手段:
(1)在网络中果断去掉了全连接层。因为全连接层丢失了空进信息和位置信息;
(2)去掉卷积网络部分的最后一个池化层。这是为了确保输出的卷积特征图有更高的分辨率;
(3)缩减网络输入。让图片输入分辨率从448*448降为416 * 416,这一步的目的是为了让后面产生的卷积特征图宽、高都为奇数,这样就可以产生一个center cell。
加入了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%,说明可以通过进一步的工作来加强准确率,的确有改进空间。
思想总结:
Faster-RCNN的 Anchor 机制又一次得到印证,与SSD一样,Anchor建立了和原始坐标的对应关系:
定义了不同的Scale和宽高比,一个中心对应K个不同尺度和宽高比的Boxes。
YOLO v1: S*S* (B*5 + C) => 7*7(2*5+20)
其中B对应Box数量,5对应 Rect 定位+置信度。
每个Grid只能预测对应两个Box,这两个Box共用一个分类结果(20 classes),
这是很不合理的临时方案,看来作者为第二篇论文预留了改进,没想被 SSD 抢了风头。
YOLO v2: S*S*K* (5 + C) => 13*13*9(5+20)
分辨率改成了13*13,更细的格子划分对小目标适应更好,再加上与Faster一样的K=9,计算量增加了不少。
通过Anchor Box改进,mAP由69.5下降到69.2,Recall由81%提升到了88%。
SSD(-): S*S*K*(4 + C) => 7*7*6*( 4+21 )
对应C=21,代表20种分类类别和一种 背景类。
可见,faster-RCNN、yolo v2、SSD都是使用了anchor机制。
3.4 Dimension Clusters (维度聚类)
我们知道在Faster R-CNN中anchor box的大小和比例是按经验设定的,即所谓的精选的先验框(hand-picked priors),然后网络会在训练过程中调整anchor box的尺寸。但是如果一开始就能选择到合适尺寸的anchor box,那肯定可以帮助网络越好地预测detection。所以作者采用k-means的方式对训练集的bounding boxes做聚类,试图找到合适的anchor box。 (这是一种非常重要是思想,现寻找到比较合适的比盲目的尝试更好)
和以前的精选boxes维度不同,作者使用了K-means聚类方法类训练bounding boxes,可以自动找到更好的boxes宽高维度。传统的K-means聚类方法使用的是欧氏距离函数,也就意味着较大的boxes会比较小的boxes产生更多的error,聚类结果可能会偏离。为此,作者采用的评判标准是IOU得分(也就是boxes之间的交集除以并集),这样的话,error就和box的尺度无关了,最终的距离函数为:
作者通过改进的K-means对训练集中的boxes进行了聚类,判别标准是平均IOU得分,聚类结果如下图:
可以看到,平衡复杂度和IOU之后,最终得到k值为5,意味着作者选择了5种大小的box维度来进行定位预测,这与手动精选的box维度不同。结果中扁长的框较少,而瘦高的框更多(这符合行人的特征),这种结论如不通过聚类实验恐怕是发现不了的。
那我们现在不是使用经验法的9种标准候选框,而是使用聚类选择的5种,到底效果差不差呢?通过实验证明,效果并不会差,如下图:
作者通过实验来对比两种策略的优劣,如下图,使用聚类方法,仅仅5种boxes的召回率就和Faster R-CNN的9种相当。说明K-means方法的引入使得生成的boxes更具有代表性,为后面的检测任务提供了便利。
3.5 Direct location prediction(直接位置预测)
作者在引入anchor box的时候遇到的第二个问题:模型不稳定,尤其是在训练刚开始的时候,有可能导致回归过程震荡,甚至无法收敛。回顾前面的文章,在进行边框回归的时候,我们预测的值是什么?如下:
那么我们得到的(x,y,w,h)就是如下:
上面这两个式子看似没什么问题,但是实际上隐含着一个问题那就是x,y的位置,可能刚开始x,y的位置是任意,离真实标签的x,y很远,这就导致的结果是要想x,y收敛,可能需要迭代很长的时间,甚至是无法收敛。
假如tx=1,就会把box向右移动anchor box的宽度;假如tx=-1,就会把box向左移动anchor box的宽度。
这个公式有个问题,假如对tx和ty取值范围没有限制,那么在任意cell,预测出的box可以在整张图片的任意位置,导致模型需要很长时间才能收敛。
因此没有采用这个公式,而是预测box相对于cell的偏移,即把ground truth限制到0,1之间。我们使用logistic激活函数(取值范围在0,1之间)来限制输出在这个区间内。
网络在feature map每个cell预测5个bboxes。每个bbox预测5个坐标,tx,ty,tw,th和to。假设一个cell左上角的坐标是(cx,cy),bbox的先验宽度和高度是pw,ph,则预测结果为:
如下图所示:
结论:
这几个公式参考上面Faster-RCNN和YOLOv1的公式以及下图就比较容易理解。 经sigmod函数处理过,取值限定在了0~1,实际意义就是使anchor只负责周围的box,有利于提升效率和网络收敛。 函数的意义没有给,但估计是把归一化值转化为图中真实值,使用 的幂函数是因为前面做了 计算,因此,是bounding box的中心相对栅格左上角的横坐标,是纵坐标,是bounding box的confidence score。
定位预测值被归一化后,参数就更容易得到学习,模型就更稳定。作者使用Dimension Clusters和Direct location prediction这两项anchor boxes改进方法,mAP获得了5%的提升。
3.6 Fine-Grained Features(细粒度特征)
SSD通过不同Scale的Feature Map来预测Box来实现多尺度,而YOLO v2则采用了另一种思路:添加一个passthrough layer,来获取上一层26x26的特征,并将该特征同最后输出特征(13*13)相结合,以此来提高对小目标的检测能力。这种思想其实就是一个跨层链接的思想,这不就是残差的思想吗?:
通过Passthrough 把26 * 26 * 512的特征图叠加成13 * 13 * 2048的特征图,与原生的深层特征图相连接。
YOLO v2 使用扩展后的的特征图(add passthrough),将mAP提高了了1%。
总结:这里实际上是有个Trick,网络最后一层是13*13,相对原来7*7的网络来讲,细粒度的处理目标已经double了,再加上上一层26*26的Feature共同决策,这两层的贡献等价于SSD的4层以上,但计算量其实并没有增加多少。这里添加的那个层称之为:passthrough layer。这个层的作用就是将前面一层的26*26的feature map和本层的13*13的feature map进行连接,有点像ResNet。这样做的原因在于虽然13*13的feature map对于预测大的object以及足够了,但是对于预测小的object就不一定有效。也容易理解,越小的object,经过层层卷积和pooling,可能到最后都不见了,所以通过合并前一层的size大一点的feature map,可以有效检测小的object。
3.7 Multi-Scale Training
为了让YOLOv2模型更加robust(鲁棒性),作者引入了Muinti-Scale Training,简单讲就是在训练时输入图像的size是动态变化的。
注意:这一步是在检测数据集上fine tune时候采用的,不要跟前面在Imagenet数据集上的两步预训练分类模型混淆,本文细节确实很多。
具体来讲,在训练网络时,每训练10个epoch,网络就会随机选择另一种size的输入。那么输入图像的size的变化范围要怎么定呢?前面我们知道本文网络本来的输入是416*416,最后会输出13*13的feature map,也就是说downsample的factor是32,因此作者采用32的倍数作为输入的size,具体来讲文中作者采用从{320,352,…,608}的输入尺寸。
这种网络训练方式使得相同网络可以对不同分辨率的图像做detection。虽然在输入size较大时,训练速度较慢,但同时在输入size较小时,训练速度较快,而multi-scale training又可以提高准确率,因此算是准确率和速度都取得一个不错的平衡。
不同输入size情况下的YOLOv2和其他object detection算法的对比。可以看出通过multi-scale training的检测模型,在测试的时候,输入图像在尺寸变化范围较大的情况下也能取得mAP和FPS的平衡。不过同时也可以看出SSD算法的表现也十分抢眼。如下图所示:
总结:
下面几个策略对于mAP的提升贡献较大:
High Resolution Classifier的提升非常明显(近4%),另外通过结合dimension prior+localtion prediction这两种方式引入anchor也能带来近5%mAP的提升。
在YOLO v1中,作者采用的训练网络是基于GooleNet,这里作者将GooleNet和VGG16做了简单的对比,GooleNet在计算复杂度上要优于VGG16(8.25 billion operation VS 30.69 billion operation),但是前者在ImageNet上的top-5准确率要稍低于后者(88% VS 90%)。而在YOLO v2中,作者采用了新的分类模型作为基础网络,那就是Darknet-19。
4.1 Darknet-19 架构
Darknet-19只需要5.58 billion operation。这个网络包含19个卷积层和5个max pooling层,而在YOLO v1中采用的GooleNet,包含24个卷积层和2个全连接层,因此Darknet-19整体上卷积卷积操作比YOLO v1中用的GoogleNet要少,这是计算量减少的关键。最后用average pooling层代替全连接层进行预测。这个网络在ImageNet上取得了top-5的91.2%的准确率。
darknet-19的基本结构如下:
4.2 Training for Classification (分类的训练技巧)
这里的2和3部分在前面有提到,就是训练处理的小trick。这里的training for classification都是在ImageNet上进行预训练,主要分两步:1、从头开始训练Darknet-19,数据集是ImageNet,训练160个epoch,输入图像的大小是224*224,初始学习率为0.1。另外在训练的时候采用了标准的数据增加方式比如随机裁剪,旋转以及色度,亮度的调整等。2、再fine-tuning 网络,这时候采用448*448的输入,参数的除了epoch和learning rate改变外,其他都没变,这里learning rate改为0.001,并训练10个epoch。结果表明fine-tuning后的top-1准确率为76.5%,top-5准确率为93.3%,而如果按照原来的训练方式,Darknet-19的top-1准确率是72.9%,top-5准确率为91.2%。因此可以看出第1,2两步分别从网络结构和训练方式两方面入手提高了主网络的分类准确率。
总的训练技巧可以总结如下:
(1)预训练 - 训练分类网络(Training for classification)
采用随机梯度下降法SGD,在 ImageNet-1000分类数据集 上训练了160个epochs,参数设定:
初始学习率 - starting learning rate:0.1
多项式速率衰减 - polynomial rate decay:4的幂次
权值衰减 - weight decay:0.0005
动量 - momentum:0.9
(2)数据增广方法(Data augmentation)
采用了常见的data augmentation,包括:
随机裁剪、旋转 - random crops、rotations
色调、饱和度、曝光偏移 - hue、saturation、exposure shifts
(3)多分辨率训练
通过初始的224 * 224训练后,把分辨率上调到了448 * 448,同样的参数又训练了10个epochs,然后将学习率调整到了0.001。
4.3 Training for Detection (检测时的训练技巧)
在前面第2步之后,就开始把网络移植到detection,并开始基于检测的数据再进行fine-tuning。
(1)首先把最后一个卷积层去掉,然后添加3个3*3的卷积层,每个卷积层有1024个filter,而且每个后面都连接一个1*1的卷积层,1*1卷积的filter个数根据需要检测的类来定。比如对于VOC数据,由于每个grid cell我们需要预测5个box,每个box有5个坐标值和20个类别值,所以每个grid cell有125(即5*(5+20)=125)个filter(与YOLOv1不同,在YOLOv1中每个grid cell有30个filter,还记得那个7*7*30的矩阵吗;
(2)在YOLOv1中,类别概率是由grid cell来预测的,也就是说一个grid cell对应的两个box的类别概率是一样的,但是在YOLOv2中,类别概率是属于box的,每个box对应一个类别概率,而不是由grid cell决定,因此这边每个box对应25个预测值(5个坐标加20个类别值),而在YOLOv1中一个grid cell的两个box的20个类别值是一样的)。另外作者还提到将最后一个3*3*512的卷积层和倒数第二个卷积层相连。最后作者在检测数据集上fine tune这个预训练模型160个epoch,学习率采用0.001,并且在第60和90epoch的时候将学习率除以10,weight decay采用0.0005。
这里指的是通过在yolo v2的基础之上进行改进,得到了yolo9000,该网络可以同时检测9000+种物体类别,所以更加强大,关于他的具体实现,这里先不坐叙述,会在下一篇文章里面详细说明是如何能够识别9000+种物体的。