本文大部分内容来自史上最通俗易懂的YOLOv2讲解。
YOLO v1提出了一种端到端的目标检测算法。虽然其mAP相对于当前表现最好的目标检测算法faster R-CNN略有不及,但是其速度却快了很多。YOLO v1有两个主要的缺点:其一是物体定位不够准确,其二是目标对象召回率较低。YOLO v2针对这两点进行了改进,并提出了一种检测与分类联合训练的方法。使用这种联合训练方法在COCO检测数据集和ImageNet分类数据集上训练出了YOLO 9000模型,其可以检测超过9000多类物体。所以这篇文章其实包含两个模型:YOLO v2和YOLO9000,不过后者是在前者基础上提出的,两者模型主体结构一致。YOLOv2相比YOLOv1做了很多方面的改进,这也使得YOLOv2的mAP有显著的提升,并且YOLOv2的速度依然很快,保持着自己作为one-stage方法的优势,YOLOv2和Faster R-CNN, SSD等模型的对比如图1所示。这里将首先介绍YOLOv2的改进策略,然后介绍YOLO9000。
1、YOLOv2的改进策略
YOLOv1虽然检测速度很快,但是在检测精度上却不如R-CNN系检测方法,YOLOv1在物体定位方面(localization)不够准确,并且召回率(recall)较低。YOLOv2共提出了几种改进策略来提升YOLO模型的定位准确度和召回率,从而提高mAP,YOLOv2在改进中遵循一个原则:保持检测速度,这也是YOLO模型的一大优势。YOLOv2的改进策略如图2所示,可以看出,大部分的改进方法都可以比较显著提升模型的mAP。下面详细介绍各个改进策略。
1.1 Batch Normalization
Batch Normalization可以提升模型收敛速度,而且可以起到一定正则化效果,降低模型的过拟合。在YOLOv2中,每个卷积层后面都添加了Batch Normalization层,并且不再使用droput。使用Batch Normalization后,YOLOv2的mAP提升了2.4%。
1.2 High Resolution Classifier
使用了高分辨率图片fine-tune模型,在YOLO v1中是用低分辨率(224x224)进行训练,高分辨率(448x448)直接预测。而在YOLO v2中先用低分辨率分辨率进行训练模型,再用高分辨率(448x448)fine-tune。使用高分辨率fine-tune分类器后,YOLOv2的mAP提升了约4%。
1.3 Convolutionlal With Anchor Boxes
YOLO v1是先将整个图片分为SxS个网格,每个网格,每个网格预测两个bounding boxes。最后使用NMS选择预测结果好的bbox最为此网格的预测结果。而YOLO v2则是借鉴了faster R-CNN中的anchor boxes思想,选择feature map上的多个anchor box来进行预测而非像YOLO v1中那样使用最后的全连接层直接进行定位预测。因此,YOLO v1中仅有SxSx2个bbox进行预测,而YOLO v2中则有SxSxn(S指feature map大小,n指feature map上每个位置的anchor box数量)。而且YOLO v2输出的feature map更大,这使得它可以生成更多的目标候选框进行预测,不容易丢失对象。所以使用anchor boxes之后,YOLOv2的召回率大大提升,由原来的81%升至88%,但是其mAP却稍有下降。
1.4 Dimensions cluster
在faster R-CNN中,anchor box的长宽都是事先设定好的,带有一定的人为主观性,不一定适合模型。因此,在YOLO v2中采用了KMeans方法对anchor box的大小做了聚类分析。因为设置anchor box的目的是为了使得预测框和GT的IOU更好,所以聚类分析时选用box与聚类中心box之间的IOU值作为距离指标:上图为在VOC和COCO数据集上的聚类分析结果,可以看到,随着聚类中心数目的增加,平均IOU是增加的,但综合考虑模型复杂度和召回率,最终选择5个聚类中心最为anchor box的大小。
1.5 New Network:Darknet-19
YOLO v2使用了一个新的基础模型,即Darknet 19,包括19个卷积层和5个maxpooling层,如下图所示。Darknet 与vgg16的设计原则一致,主要采用3x3卷积,每个2x2的maxpooling层之后,特征维度降低2倍,而同时将特征图的channel增加两倍。与NIN类似,Darknet-19最终使用global avgpooling做预测,并且在3x3卷积之间使用1x1卷积来压缩特征图channels以降低模型计算量和参数。Darknet-19每个卷积层后面同样使用了BN来加快收敛速度,降低过拟合。使用Darknet后,虽然mAP没有显著提升,但由于减少了参数数量,计算量也减少了。1.6 Direct location prediction
在faster R-CNN中,边界框的实际中心位置需根据预测的坐标偏移值来确定,即若先验宽尺度为( wa, ha),中心坐标( xa,y a),预测偏移值为( tx, ty),则预测框的中心(x,y)为:
x =( tx* wa)- xa
y = ( ty*ha)- ya
但是上面的公式没有约束,即tx,ty可为任意大小,这将导致每个anchor box的预测框都可以出现在图中任意位置,这无疑是不合适的,将导致模型的不稳定,需要很长的时间来预测出正确的offsets。
因此,YOLO v2启用了这种预测方式,选择沿用YOLO v1中的方法思想,即预测框中心相对于对应cell左上角位置的相对偏移、为了将预测边界框的中心值约束在当前cell中,使用sigmoid函数处理偏移值,这样预测偏移值在(0,1)范围内(每个cell看作1)。中的来看,根据边界框预测的4个offset可预测出边界框实际位置和大小:
其中(cx, cy)为cell的左上角坐标,如下图所示,在计算时每个cell的尺度为1,所以当前cell的左上角坐标为(1,1)。由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多。而pw和ph是先验宽(即anchor box)的长宽,他们都是相对于特征图大小的。这里记特征图的大小为(W,H),这样我们就可以将边界框相对于整张图片的位置和大小计算出来(4个值均在0和1之间):
将上面的四个值在分别乘以图片的长宽就可以得到边界框的最终位置和大小了。这就是YOLOv2边界框的整个解码过程。约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值提升了约5%。
1.7 Fine-Grained Features
YOLO v2的输入图片大小为416x416,经过5次maxpooling后得到13x13大小的特征图,并以此特征图做预测。对于一般对象,13x13的大小已经足够,但对于更小的物体,还需要更精细的特征图,FPN,SSD等使用多尺度特征图来检测小物体。
YOLO v2提出了一种passthrough层来利用更精细的特征图。对于Darknet来说,最后一层输出feature map大小为13x13,下采样之前的大小为26x26,将其拆分为4个13x13的feature map(具体怎么拆的还没弄清楚)。因此feature map大小减半,但是通道数增加了4倍(因为拆开后是按通道并排的)。这些上一层拆分后的feature map在于最后一层的feature map进行合并(虽然文中提到的合并是类似于ResNet中的跳跃连接,但是其实这里更像DenseNet的跳跃连接,通道数合并而非相同位置的feature按位相加)。因此,最后的feature map通道数为两层feature map通道数之和。
另外,作者在后期的实现中借鉴了ResNet网络,不是直接对高分辨特征图处理,而是增加了一个中间卷积层,先采用64个11卷积核进行卷积,然后再进行passthrough处理,这样2626512的特征图得到1313*256的特征图。这算是实现上的一个小细节。使用Fine-Grained Features之后YOLOv2的性能有1%的提升。
1.8 Multi-Scale Training
由于YOLO v2所用的模型只有卷积层和池化层,所以YOLO v2的输入可以不限于416x416的图片。为增强模型鲁棒性,YOLO v2采用多尺度输入训练的策略,具体地,就是在训练过程中每隔一定的iteration之后改变模型的输入大小。由于YOLO v2模型的总下采样倍数为32,输入图片大小选择一系列为32倍数的值:{320,352,...,608}。没训练10个iterations随机选择一个输入图片的大小。
采用Multi-Scale训练策略,YOLO v2可以适应不同大小的图片,并且预测出很好地结果。在测试时,YOLOv2可以采用不同大小的图片作为输入。采用低分辨率输入时,mAP较低,但是速度快;采用高分辨率时,mAP提升,但相应的速度也有所下降。
1.9 小结
总结来看,虽然YOLOv2做了很多改进,但是大部分都是借鉴其它论文的一些技巧,如Faster R-CNN的anchor boxes,YOLOv2采用anchor boxes和卷积做预测,这基本上与SSD模型(单尺度特征图的SSD)非常类似了,而且SSD也是借鉴了Faster R-CNN的RPN网络。从某种意义上来说,YOLOv2和SSD这两个one-stage模型与RPN网络本质上无异,只不过RPN不做类别的预测,只是简单地区分物体与背景。在two-stage方法中,RPN起到的作用是给出region proposals,其实就是作出粗糙的检测,所以另外增加了一个stage,即采用R-CNN网络来进一步提升检测的准确度(包括给出类别预测)。而对于one-stage方法,它们想要一步到位,直接采用“RPN”网络作出精确的预测,要因此要在网络设计上做很多的tricks。YOLOv2的一大创新是采用Multi-Scale Training策略,这样同一个模型其实就可以适应多种大小的图片了。
2. YOLO v2的训练
YOLO v2的训练主要包括三个阶段:
- 第一阶段就是现在ImageNet分类数据集上预训练Darknet-19,此时模型输入为224x224,共训练160个epochs;
- 第二个阶段调整输入为448x448,fine-tune模型,训练10个epoch;
-
第三阶段,修改Darknet为检测模型,在检测数据集上fine-tune模型。网络结构修改包括:移除最后一层卷积层、global avgpooling层以及softmax层,并且新增了三个3x3x2014卷积层,同时增加了一个passthrough层,最后使用1*1卷积层输出预测结果,输出的channel数为num_anchors*(5 + num_classes),num_classes和训练采用的数据集对象类数有关系。
YOLOv2的网络结构以及训练参数我们都知道了,但是貌似少了点东西。仔细一想,原来作者并没有给出YOLOv2的训练过程的两个最重要方面,即先验框匹配(样本选择)以及训练的损失函数,难怪Ng说YOLO论文很难懂,没有这两方面的说明我们确实不知道YOLOv2到底是怎么训练起来的。不过默认按照YOLOv1的处理方式也是可以处理,我看了YOLO在TensorFlow上的实现darkflow(见yolov2/train.py),发现它就是如此处理的:和YOLOv1一样,对于训练图片中的ground truth,若其中心点落在某个cell内,那么该cell内的5个先验框所对应的边界框负责预测它,具体是哪个边界框预测它,需要在训练中确定,即由那个与ground truth的IOU最大的边界框预测它,而剩余的4个边界框不与该ground truth匹配。YOLOv2同样需要假定每个cell至多含有一个grounth truth,而在实际上基本不会出现多于1个的情况。与ground truth匹配的先验框计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的边界框只计算置信度误差(此时target为0)。YOLOv2和YOLOv1的损失函数一样,为均方差函数。但是我看了YOLOv2的源码(训练样本处理与loss计算都包含在文件region_layer.c中,YOLO源码没有任何注释,反正我看了是直摇头),并且参考国外的blog以及allanzelener/YAD2K(Ng深度学习教程所参考的那个Keras实现)上的实现,发现YOLOv2的处理比原来的v1版本更加复杂。先给出loss计算公式:
我们来一点点解释,首先W,H分别指的是特征图(13*13)的宽与高,而A指的是先验框数目(这里是5),各个λ值是各个loss部分的权重系数。
第一项loss是计算background的置信度误差,但是哪些预测框来预测背景呢,需要先计算各个预测框和所有ground truth的IOU值,并且取最大值Max_IOU,如果该值小于一定的阈值(YOLOv2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差。
第二项是计算先验框与预测宽的坐标误差,但是只在前12800个iterations间计算,我觉得这项应该是在训练前期使预测框快速学习到先验框的形状。
第三大项计算与某个ground truth匹配的预测框各部分loss值,包括坐标误差、置信度误差以及分类误差。先说一下匹配原则,对于某个ground truth,首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground truth的IOU值(YOLOv2中bias_match=1),计算IOU值时不考虑坐标,只考虑形状,所以先将先验框与ground truth的中心点都偏移到同一位置(原点),然后计算出对应的IOU值,IOU值最大的那个先验框与ground truth匹配,对应的预测框用来预测这个ground truth。
在计算obj置信度时,在YOLOv1中target=1,而YOLOv2增加了一个控制参数rescore,当其为1时,target取预测框与ground truth的真实IOU值。对于那些没有与ground truth匹配的先验框(与预测框对应),除去那些Max_IOU低于阈值的,其它的就全部忽略,不计算任何误差。这点在YOLOv3论文中也有相关说明:YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值低于一定阈值的先验框,其预测结果就忽略了。这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框。尽管YOLOv2和YOLOv1计算loss处理上有不同,但都是采用均方差来计算loss。另外需要注意的一点是,在计算boxes的和误差时,YOLOv1中采用的是平方根以降低boxes的大小对误差的影响,而YOLOv2是直接计算,但是根据ground truth的大小对权重系数进行修正:l.coord_scale * (2 - truth.w*truth.h),这样对于尺度较小的boxes其权重系数会更大一些,起到和YOLOv1计算平方根相似的效果(参考YOLO v2 损失函数源码分析)。
最终的YOLOv2模型在速度上比YOLOv1还快(采用了计算量更少的Darknet-19模型),而且模型的准确度比YOLOv1有显著提升,详情见paper。
3、YOLO9000
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上各个节点的概率之积。
在训练时,如果是检测样本,按照YOLOv2的loss计算误差,而对于分类样本,只计算分类误差。在预测时,YOLOv2给出的置信度就是Pr(physicalobject),同时会给出边界框位置以及一个树状概率图。在这个概率图中找到概率最高的路径,当达到某一个阈值时停止,就用当前节点表示预测的类别。
通过联合训练策略,YOLO9000可以快速检测出超过9000个类别的物体,总体mAP值为19,7%。我觉得这是作者在这篇论文作出的最大的贡献,因为YOLOv2的改进策略亮点并不是很突出,但是YOLO9000算是开创之举。
参考:
YOLO9000: Better, Faster, Stronger.
史上最通俗易懂的YOLOv2讲解
目标检测之YOLO系列-V1至V3改进详解