【论文笔记】YOLO v2

全文转载,侵删。
YOLO有两个缺点:
(1)定位不准确
(2)和基于region proposal的方法相比召回率较低。
因此YOLOv2主要是要在这两方面做提升。另外YOLOv2并不是通过加深或加宽网络达到效果提升,反而是简化了网络。
下面就是使用的一些手段。

1 添加了BN(Batch Normalization)层,map提高了2%

Batch Normalization可以提升模型收敛速度,而且可以起到一定正则化效果,降低模型的过拟合。在YOLOv2中,每个卷积层后面都添加了Batch Normalization层,并且不再使用droput。使用Batch Normalization后,YOLOv2的mAP提升了2.4%。

droput和Batch Normalization的目的都是防止过拟合的发生。Dropout是过去几年非常流行的正则化技术,可有效防止过拟合的发生。但从深度学习的发展趋势看,Batch Normalizaton(简称BN)正在逐步取代Dropout技术,特别是在卷积层。
关于dropout具体可以参考: https://www.cnblogs.com/hutao722/p/9946047.html
关于Batch Normalization具体可以参考: https://www.cnblogs.com/hutao722/p/9842199.html

2 用448x448的输入分辨率在ImageNet上进行参数微调,map提高了4%。

fine-tuning:用已经训练好的模型,加上自己的数据集,来训练新的模型。即使用别人的模型的前几层,来提取浅层特征,而非完全重新训练模型,从而提高效率。一般新训练模型准确率都会从很低的值开始慢慢上升,但是fine-tuning能够让我们在比较少的迭代次数之后得到一个比较好的效果。

目前大部分的检测模型都会在先在ImageNet分类数据集预训练模型的主体部分(CNN特征提取器),由于历史原因,ImageNet分类模型基本采用大小为224x224的图片作为输入,分辨率相对较低,不利于检测模型。

YOLOv1在预训练时采用的是224*224的输入(在ImageNet数据集上进行)进行预训练后,将分辨率增加至448x448,并使用这个高分辨率在检测数据集上finetune。这会导致从分类模型切换到检测模型的时候,模型还要适应图像分辨率的改变
YOLOv2则将预训练分成两步
(1)先用224x224的输入在ImageNet数据集训练分类网络,大概160个epoch(将所有训练数据循环跑160次)后
(2)将输入调整到448x448,再训练10个epoch(这两步都是在ImageNet数据集上操作)。
(3)然后利用预训练得到的模型在检测数据集上fine-tuning。
这样训练得到的模型,在检测时用448x448的图像作为输入可以顺利检测。

3 Convolutional With Anchor Boxes

在YOLOv1中,输入图片最终被划分为7*7网格,每个单元格预测2个边界框。YOLOv1最后采用的是全连接层直接对边界框进行预测,其中边界框的宽与高是相对整张图片大小的,而由于各个图片中存在不同尺度和长宽比(scales and ratios)的物体,YOLOv1在训练过程中学习适应不同物体的形状是比较困难的,这也导致YOLOv1在精确定位方面表现较差。

在YOLOv2中借鉴了Faster R-CNN中RPN网络的先验框(anchor boxes,prior boxes,SSD也采用了先验框)策略。

RPN对CNN特征提取器得到的特征图(feature map)进行卷积来预测每个位置的边界框以及置信度(是否含有物体),并且各个位置设置不同尺度和比例的先验框,所以RPN预测的是边界框相对于先验框的offsets值(其实是transform值,详细见Faster R_CNN论文),采用先验框使得模型更容易学习。

所以YOLOv2 移除了YOLOv1中的全连接层而采用了卷积和anchor boxes来预测边界框。为了使检测所用的特征图分辨率更高,移除其中的一个pool层。在检测模型中,YOLOv2不是采481x418图片作为输入,而是采用416x416大小。因为YOLOv2模型下采样的总步长为32,对于416x416大小的图片,最终得到的特征图大小为13x13,维度是奇数,这样特征图恰好只有一个中心位置。对于一些大物体,它们中心点往往落入图片中心位置,此时使用特征图的一个中心点去预测这些物体的边界框相对容易些。所以在YOLOv2设计中要保证最终的特征图有奇数个位置。

对于YOLOv1,每个cell都预测**2个boxes,每个boxes包含5个值:(x,y,w.h.c)**前4个值是边界框位置与大小,最后一个值是置信度(confidence scores,包含两部分:含有物体的概率以及预测框与ground truth的IOU)

在 test 的时候,每个网格预测的 class 信息和 bounding box 预测的 confidence信息相乘,就得到每个 bounding box 的 class-specific confidence score]。但是每个cell只预测一套分类概率值(class predictions,其实是置信度下的条件概率值),供2个boxes共享。

YOLOv2使用了anchor boxes之后,每个位置的各个anchor box都单独预测一套分类概率值,这和SSD比较类似(但SSD没有预测置信度,而是把background作为一个类别来处理)。YOLOv1只能预测98个边界框(7x7x2),而YOLOv2使用anchor boxes之后可以预测上千个边界框(13x13cnum_anchors)。所以使用anchor boxes之后,YOLOv2的召回率大大提升,由原来的81%升至88%。使用anchor boxes之后,YOLOv2的mAP有稍微下降(这里下降的原因,我猜想是YOLOv2虽然使用了anchor boxes,但是依然采用YOLOv1的训练方法)。

4 Dimension Clusters

聚类,是针对所有标注的图片进行聚类的 ,最终产生几种w和h,来决定候选框大小。

Faster R-CNN中anchor box的大小和比例是按经验设定的,然后网络会在训练过程中调整anchor box的尺寸。
如果一开始就能选择到合适尺寸的anchor box,那肯定可以帮助网络更好地预测。所以作者采用k-means的方式对训练集的bounding boxes做聚类,试图找到合适的anchor box。

作者发现采用标准的k-means(即用欧式距离来衡量差异),在box的尺寸比较大的时候其误差也更大,而我们希望的是误差和box的尺寸没有太大关系。所以通过IOU定义了距离函数,使得误差和box的大小无关:
d(box,centroid)=1-IOU(box,centroid)
设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,所以聚类分析师使用box与聚类中的box之间的IOU值作为距离指标。
在VOC和COCO数据集上的聚类分析结果,随着聚类中心数目的增加,平均IOU值(各个边界框与聚类中心的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)

这里先验框的大小具体指什么作者在论文中并没有说明,从代码实现上看,应该是相对于13x13的特征图的大小。

如下图,左边是聚类的簇个数核 IOU 的关系,两条曲线分别代表两个不同的数据集。在分析了聚类的结果并平衡了模型复杂度与 recall 值,作者选择了 K=5,这也就是图中右边的示意图是选出来的 5 个 box 的大小,这里紫色和黑色也是分别表示两个不同的数据集,可以看出其基本形状是类似的。而且发现聚类的结果和手动设置的 anchor box 大小差别显著。聚类的结果中多是高瘦的 box,而矮胖的 box 数量较少。
在这里插入图片描述
实验对比:
(1)采用聚类分析得到的先验框比手动设置的先验框平均IOU值更高,因此模型更容易训练学习。
(2)仅选取5种box就能达到Faster RCNN的9种box的效果。

以前的方法都是一个点对应原图的一个区域,每个点在原图上产生特定比例的候选框。现在通过对真值gt的聚类,产生更合适的比例的候选框。

YOLOv2的聚类具体可以参考: https://blog.csdn.net/shiheyingzhe/article/details/83995213

5 New Network:Darknet-19

YOLOv2采用了一个新的基础模型(特征提取器),称为Darknet-19,包括19个卷积层和5个maxpooling层,如下图所示。Darknet-19与VGG16模型设计原则是一致的,主要采用3x3卷积,采用2x2的maxpooling层之后,特征图维度降低2倍,而同时将特征图的channles增加两倍。与NIN(Network in Network)类似,Darknet-19最终采用global avgpooling做预测,并且在3x3卷积之间使用1x1卷积来压缩特征图channles以降低模型计算量和参数。Darknet-19每个卷积层后面同样使用了batch norm层以加快收敛速度,降低模型过拟合。在ImageNet分类数据集上,Darknet-19的top-1准确度为72.9%,top-5准确度为91.2%,但是模型参数相对小一些。使用Darknet-19之后,YOLOv2的mAP值没有显著提升,但是计算量却可以减少约33%。
在这里插入图片描述
(1)1x1的卷积核:比如128个filter,卷积核3x3,最终的输出也就是128x56x56。
这时候加一个1x1x128的卷积核64个,使得输出就是56x56x64。压缩特征图channles以降低模型计算量和参数
(2)关于GAP的具体信息可以参考: https://www.jianshu.com/p/04f7771f4da2 和
http://spytensor.com/index.php/archives/19/?zcfwbs=zbiwg1&bsbifq=v5teg1

6 Direct Location prediction

作者在引入anchor box的时候遇到的第二个问题:模型不稳定,尤其是在训练刚开始的时候。作者认为这种不稳定主要来自预测box的中心坐标(x,y)值。在基于region proposal的目标检测算法中,是通过预测tx和ty来得到(x,y)值,也就是预测的是offsets。
在这里插入图片描述
这个公式是无约束的,预测的边界框很容易向任何方向偏移。
当tx=1时,box将向右偏移一个anchor box的宽度;
当tx=-1时,box将向左偏移一个anchor box的宽度;
因此,每个位置预测的边界框可以落在图片任何位置,这导致模型的不稳定性,在训练时需要很长时间来预测出正确的offsets。

YOLOv2中没有采用这种预测方式,而是沿用了YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值
在这里插入图片描述网络在最后一个卷积层输出13x13的feature map,有13x13个cell,每个cell有5个anchor box来预测5个bounding box,每个bounding box预测得到5个值。**分别为:tx、ty、tw、th和to(类似YOLOv1的confidence)**为了将bounding box的中心点约束在当前cell中,使用sigmoid函数将tx、ty归一化处理,将值约束在0~1,这使得模型训练更稳定。
在这里插入图片描述

7 Fine-Grained Features

YOLOv2的输入图片大小为416x416,经过5次maxpooling之后得到13x13大小的特征图,并以此特征图采用卷积做预测。13x13大小的特征图对检测大物体是足够了,但是对于小物体还需要更精细的特征图(Fine-Grained Features)。因此SSD使用了多尺度的特征图来分别检测不同大小的物体,前面更精细的特征图可以用来预测小物体。

YOLOv2提出了一种**passthrough层(直通层)**来利用更精细的特征图。YOLOv2所利用的Fine-Grained Features是26x26大小的特征图(最后一个maxpooling层的输入),对于Darknet-19模型来说就是大小为26x26x512的特征图。(注意上面我放的Darknet输入的是224x224,而YOLOv2的输入是416x416,所以输出的是13x13)。passthrough层与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个2x2的局部区域,然后将其转化为channel维度,对于26x26x512的特征图,经passthrough层处理之后就变成了13x13x2048的新特征图(特征图大小降低4倍,而channles增加4倍,下图为一个实例)。
在这里插入图片描述
这样就可以与后面的13x13x1024特征图连接在一起形成13x13x3072的特征图,然后在此特征图基础上卷积做预测。在YOLO的C源码中,passthrough层称为reorg layer。在TensorFlow中,可以使用tf.extract_image_patches或者tf.space_to_depth来实现passthrough层。

out = tf.extract_image_patches(in, [1, stride, stride, 1], [1, stride, stride, 1], [1,1,1,1], padding="VALID")
// or use tf.space_to_depth
out = tf.space_to_depth(in, 2)

8 Multi-Scale Training

YOLOv2中只有卷积层和池化层,因此不需要固定的输入图片的大小。
为了让模型更有鲁棒性,作者引入了多尺度训练。就是在训练过程中,每迭代一定的次数,改变模型的输入图片大小。

注意:这一步是在检测数据集上fine-tuning时候采用的,不要跟前面在Imagenet数据集上的两步预训练分类模型混淆。

具体操作:在训练时,每10个batch,网络就会随机选择另一种size的输入。
网络输入是416x416,经过5次max pooling之后会输出13x13的feature map,也就是下采样32倍,因此作者采用32的倍数作为输入的size,具体采用320、352、384、416、448、480、512、544、576、608共10种size。
输入图片大小为320x320时,特征图大小为10x10,输入图片大小为608x608时,特征图大小为19x19。
每次改变输入图片大小还需要对最后检测层进行处理,然后开始训练。
在这里插入图片描述

608/19=32,各个倍数还是32,说明,利用32这个步长,去画候选框,所以画得的候选框大小是不变的。

采用Multi-Scale Training策略,YOLOv2可以适应不同大小的图片,并且预测出很好的结果。在测试时,YOLOv2可以采用不同大小的图片作为输入。

总结:

总结来看,虽然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策略,这样同一个模型其实就可以适应多种大小的图片了。

训练

Training for Classification

这里的Training for Classification都是在ImageNet上进行预训练。
YOLOv2的训练主要包括三个阶段:
第一阶段:在ImageNet分类数据集上从头开始预训练Darknet-19,训练160个epoch。输入图像的大小是224x224,初始学习率为0.1。另外在训练的时候采用了标准的数据增加方式比如随机裁剪,旋转以及色度,亮度的调整等。

(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
第二阶段:将网络的输入调整为448x448,继续在ImageNet数据集上fine-tuning分类模型,训练10个epoch。参数的除了epoch和learning rate改变外,其他都没变,这里learning rate改为0.001。

第二阶段:将网络的输入调整为448*448,继续在ImageNet数据集上fine-tuning分类模型,训练10个epoch。参数的除了epoch和learning rate改变外,其他都没变,这里learning rate改为0.001。

(3)多分辨率训练
通过初始的224x224训练后,把分辨率上调到了448x448,同样的参数又训练了10个epochs,然后将学习率调整到了0.001。

Training for Detection

第三阶段:修改Darknet-19分类模型为检测模型,并在检测数据集上继续fine-tuning网络。
网络修改包括:移除最后一个卷积层、global avgpooling层以及softmax层,新增了三个332014卷积层,同时增加了一个passthrough层,最后使用1*1卷积层输出预测结果。输出通道数计算如下。
对于VOC数据,每个cell预测num=5个bounding box,每个bounding box有5个坐标值和20个类别值,所以每个cell有125个filter。即:filter_num = num * (classes + 5) = 5 * (20 + 5) = 125
注意
(1)这里filter_num的计算和YOLOv1不同,在YOLOv1中filter_num = classes + num * (coords + confidence) = 20 + 2 * (4 + 1) = 30,在YOLOv1中,类别概率是由cell来预测的,一个cell对应的两个box的类别概率是一样的,但是在YOLOv2中,类别概率是属于box的,每个box对应一个类别概率,而不是由cell决定,因此这边每个box对应25个预测值(5个坐标加20个类别值)。
(2)YOLOv2和YOLOv3的计算方式是一致的。
在这里插入图片描述

作者并没有给出YOLOv2的训练过程的两个最重要方面,即先验框匹配(样本选择)以及训练的损失函数。
(1)和YOLOv1一样,对于训练图片中的ground truth,若其中心点落在某个cell内,那么该cell内的5个先验框所对应的边界框负责预测它,具体是哪个边界框预测它,需要在训练中确定,即由那个与ground truth的IOU最大的边界框预测它,而剩余的4个边界框不与该ground truth匹配。YOLOv2同样需要假定每个cell至多含有一个grounth truth,而在实际上基本不会出现多于1个的情况。与ground truth匹配的先验框计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的边界框只计算置信度误差(此时target为0)。
(2)YOLOv2和YOLOv1的损失函数一样,为均方差函数。但是看了YOLOv2的源码(训练样本处理与loss计算都包含在文件region_layer.c中),并且参考国外的blog以及allanzelener/YAD2K(Ng深度学习教程所参考的那个Keras实现)上的实现,发现YOLOv2的处理比原来的v1版本更加复杂。
在这里插入图片描述
(1)W,H分别指的是特征图(13x13)的宽与高;
(2)A指的是先验框数目(这里是5);
(3)各个λ值是各个loss的权重系数,参考YOLOv1的loss;
(4)第一项loss是计算background的置信度误差,但是哪些预测框来预测背景呢,需要先计算各个预测框和所有ground truth的IOU值,并且取最大值Max_IOU,如果该值小于一定的阈值(YOLOv2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差;
(5)第二项是计算先验框与预测宽的坐标误差,但是只在前12800个iterations间计算,我觉得这项应该是在训练前期使预测框快速学习到先验框的形状;
(6)第三大项计算与某个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 x (2 - truth.w x truth.h),这样对于尺度较小的boxes其权重系数会更大一些,起到和YOLOv1计算平方根相似的效果。

参考:
https://blog.csdn.net/lwplwf/article/details/82895409
https://blog.csdn.net/l7H9JA4/article/details/79955903

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值