本文参考、摘录、修改自以下文章:
[1] https://blog.csdn.net/l7H9JA4/article/details/79955903
[2] http://www.360doc.com/content/17/1017/09/42392246_695618898.shtml
[3] https://blog.csdn.net/hrsstudy/article/details/71173305?utm_source=itdadao&utm_medium=referral
[4] https://coolshell.cn/articles/7779.html
1、概述
相对于YOLO V1,新版的YOLO主要有两个大方面的改进:
第一,作者使用了一系列的方法对原来的YOLO多目标检测框架进行了改进,在保持原有速度的优势之下,精度上得以提升。VOC 2007数据集测试,67FPS下mAP达到76.8%,40FPS下mAP达到78.6%。
第二,作者提出了一种目标分类与检测的联合训练方法,通过这种方法,YOLO9000可以同时在COCO和ImageNet数据集中进行训练,训练后的模型可以实现多达9000种物体的实时检测。
2、改进
2.1 Batch Normalization
CNN在训练过程中网络每层输入的分布一直在改变, 会使训练过程难度加大,但可以通过normalize每层的输入解决这个问题。新的YOLO网络在每一个卷积层后添加batch normalization,通过这一方法,mAP获得了2%的提升。batch normalization 也有助于规范化模型,可以在舍弃dropout优化后依然不会过拟合。
2.2 High Resolution Classifier
目前大部分的检测模型都会在先在ImageNet分类数据集上预训练模型的主体部分,ImageNet分类模型基本采用大小为224x224的图片作为输入,分辨率相对较低,不利于检测模型。
YOLOv1在采用224x224分类模型预训练后,将分辨率增加至448x448,并使用这个高分辨率在检测数据集上finetune。但是直接切换分辨率,检测模型可能难以快速适应高分辨率。所以YOLOv2增加了在ImageNet数据集上使用448x448来finetune分类网络这一中间过程,这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入。使用高分辨率分类器后,YOLOv2的mAP提升了约4%。
2.3 Convolutionlal With Anchor Boxes
YOLOv1是采用全连接层直接对物体的边界框进行预测,这会丢失较多的空间信息,定位不准确。在YOLOv2中,作者参考了Faster R-CNN中的anchor思想。
为了引入anchor boxes思想,作者去掉了最后的全连接层。之后,去掉最后的一个池化层确保输出的卷积特征图拥有更高的分辨率。然后,缩减图片输入大小为416x416,以确保最后得到的卷积特征图的边长为奇数,这样就可以得到一个最中心的cell。最后,YOLOv2使用了卷积层降采样(factor为32),使得输入卷积网络的416 * 416图片最终得到13 * 13的卷积特征图。
YOLOv1中,每个cell只预测一套类分类概率值,供两个框共享,YOLOv2使用了anchor boxes之后,每个位置的各个anchor box都单独预测一套分类概率值。
使用anchor boxes之后,YOLOv2的mAP有稍微下降。YOLOv1只能预测98个边界框,而YOLOv2使用anchor boxes之后可以预测上千个边界框(13x13xnum_anchor)。YOLOv2的召回率大大提升,由原来的81%升至88%。
2.4 Dimension Clusters
在Faster R-CNN中,先验框的维度都是固定的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习。YOLOv2采用K-means方法对训练集中的边界框做了聚类分析。 传统的K-means方法使用的是欧氏距离函数,在这里并不适用,因为设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,所以聚类分析时选用box与聚类中心box之间的IOU值作为距离指标:
d(box, centroid) = 1 − IOU(box, centroid)
聚类结果图如下:
上图为在VOC和COCO数据集上的聚类分析结果,随着聚类中心数目的增加,平均IOU值是增加的,但是综合考虑模型复杂度和召回率,最终选取5个聚类中心作为先验框,其相对于图片的大小如右边图所示。
COCO: (0.57273, 0.677385), (1.87446, 2.06253), (3.33843, 5.47434), (7.88282, 3.52778), (9.77052, 9.16828)
VOC: (1.3221, 1.73145), (3.19275, 4.00944), (5.05587, 8.09892), (9.47112, 4.84053), (11.2364, 10.0071)
2.5 New Network:Darknet-19
YOLOv2采用了一个新的网络结构,称为Darknet-19,包括19个卷积层和5个maxpooling层:
Darknet-19与VGG16模型设计原则是一致的,主要采用3*3卷积,采用2*2的maxpooling层之后,特征图维度降低2倍。Darknet-19最终采用global avgpooling做预测,并且在3*3卷积之间使用1*1卷积来压缩特征图channles以降低模型计算量和参数。Darknet-19每个卷积层后面同样使用了batch norm层以加快收敛速度,降低模型过拟合。在ImageNet分类数据集上。使用Darknet-19之后,YOLOv2的mAP值没有显著提升,但是计算量却可以减少约33%。
2.6 Direct location prediction
在YOLO中使用anchor boxes的过程中遇到的一个问题就是模型不稳定,尤其是在训练的早期迭代。不稳定的主要因素来自对bounding box中心坐标x,y的预测。在Faster R-CNN网络结构中,使用RPN预测出偏移量tx,ty,然后计算bounding box中心坐标x,y:
公式中,xa,ya为anchor的坐标,wa,ha为anchor的长宽。如果tx大于0,bounding box会向右移动anchor宽的tx倍;如果tx小于0,bounding box会向左移动anchor宽的tx倍。由于tx和ty没有限制,预测出的bounding box的中心可以在图像上的任意一点,即便这个点落在别的栅格中,应当由别的栅格来预测。导致模型的不稳定性,在训练时需要很长时间来预测出正确的offsets。
YOLOv2弃用了这种预测方式,而是沿用YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内。根据边界框预测的四个offsets: tx, ty, tw, th,然后按照如下公式计算边界框实际位置和大小:
其中cx,cy为当前cell左上角的坐标,pw,ph为先验框的宽度与高度。
约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值提升了约5%。
2.7 Fine-Grained Features
YOLOv2经过卷积池化操作最终得到一个13x13的卷积特征图,13x13大小的对于检测大物体是足够了,但是对于小物体还需要更精细的特征图(Fine-Grained Features)。YOLOv2所利用的Fine-Grained Features是26*26大小的特征图(最后一个maxpooling层的输入),对于Darknet-19模型来说就是大小为26*26*512的特征图。
YOLOv2提出了一种passthrough层来利用更精细的特征图。passthrough层与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个2*2的局部区域,然后将其转化为channel维度,对于26*26*512的特征图,经passthrough层处理之后就变成了13*13*2048的新特征图。这样就可以与后面的13*13*1024特征图连接在一起形成13*13*3072的特征图,然后在此特征图基础上卷积做预测。
使用Fine-Grained Features之后YOLOv2的性能有1%的提升。
2.8 Multi-Scale Training
由于YOLOv2模型中只有卷积层和池化层,所以YOLOv2的输入可以不限于416*416大小的图片。为了增强模型的鲁棒性,YOLOv2采用了多尺度输入训练策略
在VOC 2007数据集上的效果如下图所示(均使用 Geforce GTX Titan X )。可以看到采用较小分辨率时,YOLOv2的mAP值略低,但是速度更快,而采用高分辨输入时,mAP值更高,但是速度略有下降,对于544*544,mAP高达78.6%。
3、训练
YOLOv2的训练主要包括三个阶段:
第一阶段就是先在ImageNet分类数据集上预训练Darknet-19,此时模型输入为224*224,共训练160个epochs。
第二阶段将网络的输入调整为448*448,继续在ImageNet数据集上finetune分类模型,训练10个epochs。
第三个阶段就是修改Darknet-19分类模型为检测模型,并在检测数据集上继续finetune网络。
网络修改包括:移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个3*3*2014卷积层,同时增加了一个passthrough层,最后使用1*1卷积层输出预测结果,输出的channels数为:num_anchor x (5+num_classes).
4、K-Means 计算 anchor boxes
4.1 K-Means算法
K-Means算法可以简单演示如下图:
具体算法如下:
1. 随机在图中取K(这里K=2)个种子点。
2. 然后对图中的所有点求到这K个种子点的距离,假如点Pi离种子点Si最近,那么Pi属于Si点群。(上图中,我们可以看到A,B属于上面的种子点,C,D,E属于下面中部的种子点)
3. 接下来,我们要移动种子点到属于他的“点群”的中心。(见图上的第三步)
4. 然后重复第2)和第3)步,直到,种子点没有移动(我们可以看到图中的第四步上面的种子点聚合了A,B,C,下面的种子点聚 合了D,E)。
4.2 K-Means++算法
K-Means算法需要用初始随机种子,随机种子的选择非常重要,不同的随机种子点会有得到完全不同的结果。K-Means++算法可以用来解决这个问题,有效地选择初始点。
K-Means++算法步骤如下:
1. 从我们的数据库随机挑个随机点当“种子点”。
2. 对于数据集中的每一个点x,计算它与最近聚类中心(指已选择的聚类中心)的距离D(x)。
3. 选择一个新的数据点作为新的聚类中心,选择的原则是:D(x)较大的点,被选取作为聚类中心的概率较大。
4. 重复第(2)和第(3)步直到所有的K个种子点都被选出来。
5. 进行K-Means算法。
a.对于每个点,我们都计算其和最近的一个“种子点”的距离D(x)并保存在一个数组里,然后把这些距离加起来得Sum(D(x))。
b.然后,再取一个随机值,用权重的方式来取计算下一个“种子点”。这个算法的实现是,先用Sum(D(x))乘以随机值Random得到值r,然后用currSum += D(x),直到其currSum>r,此时的点就是下一个“种子点”。
4.3 k-Means 计算 anchor boxes
YOLO中关于boxes位置信息的参数有x,y,w,h。我们希望能通过anchor boxes获得好的IOU scores,故使用如下距离公式:
d(box, centroid) = 1 − IOU(box, centroid)
又因为计算anchor boxes我们只关心boxes的大小,而位置信息x,y值是无关紧要的。所以可以直接忽视x,y值,仅关注w,h值。YOLO中将x,y赋值0。
参考文献:
[1] https://blog.csdn.net/l7H9JA4/article/details/79955903
[2] http://www.360doc.com/content/17/1017/09/42392246_695618898.shtml
[3] https://blog.csdn.net/hrsstudy/article/details/71173305?utm_source=itdadao&utm_medium=referral
[4] https://coolshell.cn/articles/7779.html
[5] https://github.com/PaulChongPeng/darknet/blob/master/tools/k_means_yolo.py