这次来讲解一下YOLO v2算法(CVPR2016的文章)。之前已经讲解过YOLO v1,YOLO v1以完全端到端的模式实现达到实时水平的目标检测,但是它追求速度而牺牲了部分检测精度,所以原作者在YOLO v1的基础上进行了改进,得到了YOLO9000。相对于YOLO v1来说,在继续保持处理速度的基础上,从预测更准确(Better),速度更快(Faster),识别对象更多(Stronger)这三个方面进行了改进。其中识别更多对象也就是扩展到能够检测9000种不同对象,称之为YOLO9000。
摘要 Abstract
我们介绍YOLO9000,一个最先进的,实时目标检测系统,可以检测超过9000个目标类别。首先,我们提出对YOLO检测方法的各种改进方法,包括新颖的和从以前的工作中得出的。改进的模型YOLOv2在如PASCAL VOC和COCO标准检测任务是最先进的。使用一种新颖的多尺度训练方法,相同的YOLOv2模型可以运行在不同的大小的图片上,提供速度和精度之间的轻松权衡。在67 FPS时,YOLOv2在VOC 2007上获得76.8 mAP。在40 FPS时,YOLOv2获得78.6 mAP,性能优于最先进的方法,例如使用ResNet的faster RCNN和SSD,同时运行速度明显更快。最后,我们提出了一种联合训练目标检测和分类的方法。使用这种方法,我们在COCO检测数据集和ImageNet分类数据集上同时训练YOLO9000。我们的联合训练方法允许YOLO9000预测没有标记检测数据的目标类的检测。我们在ImageNet检测数据集上验证我们的方法。YOLO9000在ImageNet检测验证集上获得19.7 mAP,尽管只有200个类中的44类检测数据。在不在COCO的156类中,YOLO9000获得16.0 mAP。但是YOLO可以检测超过200个类;它预测超过9000个不同目标类别的检测。它仍然实时运行。
介绍 Introduction
通用目标检测应该快速,准确,并且能够识别各种各样的目标。与分类和标记等其他任务的数据集相比,当前目标检测数据集是有限的。最常见的检测数据集包含数十到数十万的图像,具有几十到几百个标签。分类数据集具有数百万个具有数十或数十万类别的图像。这也是因为目标检测标注的成本较高。
如此,作者提出了一种新方法来利用我们已经拥有的大量分类数据(ImageNet),并使用它来扩大当前检测系统的范围,并且使用目标分类的层次视图,将不同的数据集合在一起。
除此之外,还提出了一种联合训练的方法,在检测和分类数据上训练目标检测器,利用标记的检测图像来学习精确地定位目标,同时使用分类图像来增加其词汇和鲁棒性。
使用这种方法,我们训练YOLO9000,一个实时目标检测器,可以检测超过9000不同的目标类别。首先,我们改进基本的YOLO检测系统,以产生YOLOv2,一个最先进的,实时检测器。然后我们使用我们的数据集组合方法和联合训练算法来训练来自ImageNet的超过9000个类的模型以及来自COCO的检测数据。
作者的代码和预训练模型都在http://pjreddie.com/yolo9000/
预测更准确(Better)
前面有提过,虽然YOLOv1检测速度很快,但是在精度上却不R-CNN系列的检测方法,YOLOv1在物体定位方面(localization)不够准确,并且召回率(recall)较低。YOLOv2共提出了几种改进策略来提升YOLO模型的定位准确度和召回率,从而提高mAP,YOLOv2在改进中遵循一个原则:保持检测速度,这也是YOLO模型的一大优势。YOLOv2的改进方法如下图所示,可以看到,大部分的改进策略都可以比较显著的提高模型的mAP。
batch normalization 批归一化
批归一化提高了2的mAP
批归一化有助于解决反向传播过程中的梯度消失和梯度爆炸问题,降低对一些超参数(比如学习率、网络参数的大小范围、激活函数的选择)的敏感性,并且每个batch分别进行归一化的时候,起到了一定的正则化效果(YOLO2不再使用dropout),从而能够获得更好的收敛速度和收敛效果。
通常,一次训练会输入一批样本(batch)进入神经网络。批规一化在神经网络的每一层,在网络(线性变换)输出后和激活函数(非线性变换)之前增加一个批归一化层(BN),并且有个很重要的点,BN是对每一个神经元进行标准化,我之后会对Batch Normalization论文进行解读和实现。
High Resolution Classifier
提高了大约4的mAP
目前大部分的检测模型都会在先在ImageNet分类数据集上预训练模型的主体部分(CNN特征提取器),而且大部分的ImageNet分类模型基本才用224 x 224的图片进行输入,分辨率比较低,其实是不太适合检测模型的。YOLOv1使用ImageNet的图像分类样本采用 224 x 224作为输入,来训练CNN卷积层。然后在训练对象检测时,检测用的图像样本采用更高分辨率的 448x448 的图像作为输入,但这样切换对模型性能有一定影响。
所以在YOLO v2中,先采用224x224的图片进行预训练,再采用448x448的高分辨率的样本对分类模型信息微调 10 个 epoch,给时间给网络逐渐适应高分辨率。
Convolutional With Anchor Boxes
召回率从81%提高到88%,但是mAP轻微下降0.3。
借鉴Faster RCNN的做法,YOLO2也尝试采用先验框(anchor)。在每个grid预先设定一组不同大小和宽高比的边框,来覆盖整个图像的不同位置和多种尺度,这些先验框作为预定义的候选区在神经网络中将检测其中是否存在对象,以及微调边框的位置。
同时YOLO2移除了全连接层,另外去掉了一个池化层,使网络卷积层输出具有更高的分辨率。除此之外,还对图像进行收缩,使得我们的特征图为奇数,因为这样每一个特征图就存在一个中心点。最后在池化层之前,与原图像大约是32倍,所以如果输入416x416的图像,我们会得到(batch,13,13,5,25)
之前YOLO1并没有采用先验框,并且每个grid只预测两个bounding box,整个图像98(7x7x2)个。YOLO2如果每个grid采用9个先验框,总共有13x13x9=1521个先验框。所以,相对YOLO1的81%的召回率,YOLO2的召回率大幅提升到88%。同时mAP有0.3%的轻微下降。
Dimension Clusters
提高了4.8的mAP
在之前的Faster R-CNN中,先验框都是手工选取的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测。因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析。
聚类算法最重要的是选择如何计算两个边框之间的“距离”,对于常用的欧式距离,大边框会产生更大的误差,但我们关心的是边框的IOU。所以,YOLO2在聚类时采用以下公式来计算两个边框之间的“距离”。
centroid是聚类时被选作中心的边框,box就是其它边框,d就是两者间的“距离”。IOU越大,“距离”越近。YOLO2给出的聚类分析结果如下图所示:
上图左边是选择不同的聚类k值情况下,得到的k个centroid边框,计算样本中标注的边框与各centroid的Avg IOU。显然,边框数k越多,Avg IOU越大。YOLO2选择k=5作为边框数量与IOU的折中。对比手工选择的先验框,使用5个聚类框即可达到61 Avg IOU,相当于9个手工设置的先验框60.9 Avg IOU。
上图右边显示了5种聚类得到的先验框,VOC和COCO数据集略有差异,不过都有较多的瘦高形边框。
Direct location prediction
借鉴于Faster RCNN的先验框方法,在训练的早期阶段,其位置预测容易不稳定。其位置预测公式为:
其中,
x , y是预测边框的中心,x a , y a 是先验框(anchor)的中心点坐标,w a , h a 是先验框(anchor)的宽和高,t x , t y 是要学习的参数。
注意,YOLO论文中写的是x = ( t x ∗ w a ) − x a,根据Faster RCNN,应该是"+"。
由于t x , t y 的取值没有任何约束,因此预测边框的中心可能出现在任何位置,训练早期阶段不容易稳定。YOLO调整了预测公式,将预测边框的中心约束在特定gird网格内。
其中,b x , b y , b w , b h 是预测边框的中心和宽高。Pr(object)∗IOU(b,object)是预测边框的置信度,YOLO1是直接预测置信度的值,这里对预测参数t o 进行σ变换后作为置信度的值。
c x , c y 是当前网格左上角到图像左上角的距离,要先将网格大小归一化,即令一个网格的宽=1,高=1。
p w , p h 是先验框的宽和高。
σ是sigmoid函数。
t x , t y , t w , t h , t o 是要学习的参数,分别用于预测边框的中心和宽高,以及置信度。
由于σ函数将t x , t y 约束在(0,1)范围内,所以根据上面的计算公式,预测边框的蓝色中心点被约束在蓝色背景的网格内。约束边框位置使得模型更容易学习,且预测更为稳定。
Fine-Grained Features
用了passthrough层提高了1的mAP。
对象检测面临的一个问题是图像中对象会有大有小,输入图像经过多层网络提取特征,最后输出的特征图中(比如YOLO2中输入416x416经过卷积网络下采样最后输出是13x13),较小的对象可能特征已经不明显甚至被忽略掉了。为了更好的检测出一些比较小的对象,最后输出的特征图需要保留一些更细节的信息,将低层和高层的特征图进行一个融合。
YOLO2引入一种称为passthrough层的方法在特征图中保留一些细节信息。具体来说,就是在最后一个pooling之前,特征图的大小是26x26x512,将其1拆4,直接传递(passthrough)到pooling后(并且又经过一组卷积)的特征图,两者叠加到一起作为输出的特征图。
具体的1拆4我借用了一张图来解释一下
根据YOLO2的代码,作者借鉴了ResNet网络,不是直接对高分辨特征图处理,而是增加了一个中间卷积层,特征图先用1x1卷积从 26x26x512 降维到 26x26x64,再做1拆4并passthrough。
Multi-Scale Training
多尺度图像训练对mAP有1的提升。
因为去掉了全连接层,YOLO2可以输入任何尺寸的图像。因为整个网络下采样倍数是32,作者采用了{320,352,…,608}等10种输入图像的尺寸,这些尺寸的输入图像对应输出的特征图宽和高是{10,11,…19}。训练时每10个batch就随机更换一种尺寸,使网络能够适应各种大小的对象检测。
这其实是某种意义的数据增强,防止了过拟合,而且这些得益于网络中的结构平均池化层,平均池化层对我们的结果进行一个均值计算,而不用去考虑每个特征图的宽高,所以说不用一直进行模型的调整。
速度更快(Faster)
为了进一步提升速度,YOLO2提出了Darknet-19(有19个卷积层和5个MaxPooling层)网络结构。DarkNet-19比VGG-16小一些,精度不弱于VGG-16,但浮点运算量减少到约1/5,以保证更快的运算速度。
YOLO2的训练主要包括三个阶段。第一阶段就是先在ImageNet分类数据集上预训练Darknet-19,此时模型输入为 224x224 ,共训练160个epochs。然后第二阶段将网络的输入调整为 448x448 ,继续在ImageNet数据集上finetune分类模型,训练10个epochs,此时分类模型的top-1准确度为76.5%,而top-5准确度为93.3%。第三个阶段就是修改Darknet-19分类模型为检测模型,移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个 3x3x1024卷积层,同时增加了一个passthrough层,最后使用 1x1 卷积层输出预测结果,输出的channels数为:num_anchors*(5+num_classes) ,和训练采用的数据集有关系。由于anchors数为5,对于VOC数据集(20种分类对象)输出的channels数就是125,最终的预测矩阵T的shape为 (batch_size, 13, 13, 125),可以先将其reshape为 (batch_size, 13, 13, 5, 25) ,其中 T[:, :, :, :, 0:4] 为边界框的位置和大小 ( t x , t y , t w , t h ) 为边界框的置信度,而 T[:, :, :, :, 5:] 为类别预测值。
看一下passthrough层。图中第25层route 16,意思是来自16层的output,即26x26x512,这是passthrough层的来源(细粒度特征)。第26层1x1卷积降低通道数,从512降低到64(这一点论文在讨论passthrough的时候没有提到),输出26x26x64。第27层进行拆分(passthrough层)操作,1拆4分成13x13x256。第28层叠加27层和24层的输出,得到13x13x1280。后面再经过3x3卷积和1x1卷积,最后输出13x13x125。
综上所述,虽然YOLO2做出了一些改进,但总的来说网络结构依然很简单。就是一些卷积+pooling,从416x416x3 变换到 13x13x5x25。稍微大一点的变化是增加了batch normalization,增加了一个passthrough层,去掉了全连接层,以及采用了5个先验框。
对比YOLO1的输出张量,YOLO2的主要变化就是会输出5个先验框,且每个先验框都会尝试预测一个对象。输出的 13x13x5x25 张量中,25维向量包含 20个对象的分类概率+4个边框坐标+1个边框置信度。
YOLO v2 误差函数
误差依然包括边框位置误差、置信度误差、对象分类误差。
公式中:
1 MaxIOU<Thresh
意思是预测边框中,与真实对象边框IOU最大的那个,其IOU<阈值Thresh,此系数为1,即计入误差,否则为0,不计入误差。YOLO2使用Thresh=0.6。
1 t < 128000 意思是前128000次迭代计入误差。注意这里是与先验框的误差,而不是与真实对象边框的误差。可能是为了在训练早期使模型更快学会先预测先验框的位置。
1_{k}^{truth} 意思是该边框负责预测一个真实对象(边框内有对象)。
各种λ 是不同类型误差的调节系数。
识别对象更多(Stronger)/ YOLO9000
VOC数据集可以检测20种对象,但实际上对象的种类非常多,只是缺少相应的用于对象检测的训练样本。YOLO2尝试利用ImageNet非常大量的分类样本,联合COCO的对象检测数据集一起训练,使得YOLO2即使没有学过很多对象的检测样本,也能检测出这些对象。
基本的思路是,如果是检测样本,训练时其Loss包括分类误差和定位误差,如果是分类样本,则Loss只包括分类误差。
YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略。众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。
作者选择在COCO和ImageNet数据集上进行联合训练,但是遇到的第一问题是两者的类别并不是完全互斥的,比如"Norfolk terrier"明显属于"dog",所以作者提出了一种层级分类方法(Hierarchical classification),主要思路是根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree,结合COCO和ImageNet建立的WordTree如下图所示:
WordTree中的根节点为"physical object",每个节点的子节点都属于同一子类,可以对它们进行softmax处理。在给出某个类别的预测概率时,需要找到其所在的位置,遍历这个path,然后计算path上各个节点的概率之积。
通过联合训练策略,YOLO9000可以快速检测出超过9000个类别的物体,总体mAP值为19,7%。我觉得这是作者在这篇论文作出的最大的贡献,因为YOLOv2的改进策略亮点并不是很突出,但是YOLO9000算是开创之举。
总结
总的来说,YOLO2通过一些改进明显提升了预测准确性,同时继续保持其运行速度快的优势。YOLO9000则开创性的提出联合使用分类样本和检测样本的训练方法,使对象检测能够扩展到缺乏检测样本的对象。