目标检测YOLOv2最详细解释!

在这里插入图片描述
我们来回顾一下Yolov1,设计其实还是有问题的。

1.7 * 7的卷积层,AlexNet和ZFNet就是7 * 7的,大卷积核的好处是有更大的感受野,能将图像中更多的像素点作一个统计分析,但是当网络结构变深的时候,图像的感受野会在卷积过程中不断变大,所以早层用大的卷积核没有必要,VGG,GoogLeNet用的3 * 3的filter,7 * 7比3 * 3有更大的计算量,同时7 * 7的时候用了stride=2,说明经过stride之后的feature map的尺寸缩小为原来的一半,紧接着7 * 7的max pooling层,stride=2,说明经过一层后feature map变为原来的1/4,在原图像中,物体在图像中的位置与这个物体的feature在feature map这个的位置是一一对应的,但是在图像中过早地下采样(只要是stride就会对图像下采样),这种过分下采样会损坏物体在图像中的位置信息,所以设计网络的时候一般把下采样maxpooling往后延,在后面那基层做下采样,这样对整个物体的位置信息损害会少点。

2.检测的问题,用的全连接fc层,这样完全把物体的定位信息给打破了,7*7可以映射图像的像素区域,经过全连接层这样的映射关系完全就没有了,所以Yolov1是希望用1位fc层来分析出物体的位置信息,但实际上很难。

1.Batch Normalization
Yolov2——Backbone,由原来的24层,减少为原来的18层,第一层conv-filter为3*3,第一层的stride设置为1,不会下采样,在每一层后面都加上batch-norm层,就有了更快的收敛速度,初始化的时候相对v1更加的简单,BN有一部分正则化的效果,分类的正确率会有所提升。

2.High Resolution Classifier
不仅改进了backbone的网络,还改进了训练方法,一般会在ImageNet上做一个pretrain,再把backbone放到检测网络当中去,pretrain一般用224 * 224,v2输入一般是416 * 416或者448 * 448,所以训练和测试的不一样,这样不匹配可能会使检测精度降低,所以v2的训练方法是用448 * 448(原来的2倍)去训练backbone,把448 * 448这样训练的分类结果放在检测网络中,这样使mAP提升了4%

3.Convolutional With Anchor Box
v2的Convolutional With Anchor Boxes继承了Faster RCNN的RPN层的Anchor。对于fasterRCNN来说每一次预测,RPN都是基于一个Anchor Box预测结果是在Anchor Box基础上做一个差值,anchor box的宽高加上预测的差值,最终能得到检测结果,继承了fasterrcnn的9个anchor,分3组,有相同的面积,内部3个anchor有不同的宽高比。

v2的检测网络中把所有全连接层都去掉了,后面只跟上卷积层,对图像的下采样也往后移了,使得前面的网络能充分利用定位信息。
在这里插入图片描述
v2使用了卷积层降采样(factor为32),使得输入卷积网络416*416图片最终得到13 * 13的卷积特征图。

加入anchor box后,可以预料是召回率上升,准确率下降。实际上准确率只有小幅度下降,但是召回率提升了7%。

4.Dimension Clusters
v2中anchor是根据自己的数据集来定的,会遍历一遍我的整个数据集,把所有图片的ground truth的bbox给拿出来,对这些ground truth做一个统计,统计有多少类别的框,找到不同类的框就要对框进行聚类,核心问题就是如何计算两类之间的距离,两个框的overlap(IOU)足够大的话,就认为两个框是一个类别的,不断对ground truth框做聚类的话,最终会得到我们想要的聚类中心的框,cluster超过5之后增长越来越慢,只需要5个不同的anchor就能达到9个anchor能达到的效果。
在这里插入图片描述
也就是说,如果一开始就选择了更好的,更具有代表性的先验boxes维度,那么网络就更容易学到准确的预测位置。

传统的Kmeans是用欧氏距离,也就意味着较大的boxes会比较小的boxes产生更多的error。所以这里采用的评判标准是IOU得分(也就是boxes之间的交集除以并集),这样的话,error就和box的尺度无关了,最终的距离函数为:
d ( b o x , c e n t r o i d ) = 1 − I O U ( b o x , c e n t r o i d ) d(box,centroid) = 1 - IOU(box,centroid) d(box,centroid)=1IOU(box,centroid)

5.New Network: Darknet-19
v2采用了一个新的特征提取器,包括19个卷积层和5个maxpooling层,Darknet19和VGG16模型设计原则是一致的,主要采用3 * 3卷积,采用2 * 2的maxpooling层之后,特征图维度降低2倍,而同时将特征图的channels增加两倍。与NIN类似,Darknet19最终采用global avgpooling做预测,并且在3 * 3卷积层之间使用1 * 1卷积来压缩特征图channels以降低模型计算量和参数。每个卷积层后面同样使用了BN层来加快收敛速度,降低模型过拟合。mAP没有显著提升,但是计算量少了。

6.Direct location prediction
前面讲到,YOLOv2借鉴RPN网络使用anchor boxes来预测边界框相对先验框的offsets。边界框的实际中心位置 (x,y) ,需要根据预测的坐标偏移值 ( t x , t y ) (t_x, t_y) (tx,ty) ,先验框的尺度 ( w a , h a ) (w_a, h_a) (wa,ha) 以及中心坐标 ( x a , y a ) (x_a, y_a) (xa,ya) (特征图每个位置的中心点)来计算:
x = ( t x × w a ) − x a \\x = (t_x\times w_a)-x_a x=(tx×wa)xa

y = ( t y × h a ) − y a \\y=(t_y\times h_a) - y_a y=(ty×ha)ya

但是上面的公式是无约束的,预测的边界框很容易向任何方向偏移,如当 t x = 1 t_x=1 tx=1 时边界框将向右偏移先验框的一个宽度大小,而当 t x = − 1 t_x=-1 tx=1 时边界框将向左偏移先验框的一个宽度大小,因此每个位置预测的边界框可以落在图片任何位置,这导致模型的不稳定性,在训练时需要很长时间来预测出正确的offsets。所以,YOLOv2弃用了这种预测方式,而是沿用YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内(每个cell的尺度看做1)。总结来看,根据边界框预测的4个offsets t x , t y , t w , t h t_x, t_y, t_w, t_h tx,ty,tw,th ,可以按如下公式计算出边界框实际位置和大小:

b x = σ ( t x ) + c x \\b_x = \sigma (t_x)+c_x bx=σ(tx)+cx

b y = σ ( t y ) + c y \\b_y = \sigma (t_y) + c_y by=σ(ty)+cy

b w = p w e t w \\b_w = p_we^{t_w} bw=pwetw

b h = p h e t h \\b_h = p_he^{t_h} bh=pheth

其中 ( c x , x y ) (c_x, x_y) (cx,xy) 为cell的左上角坐标,如图5所示,在计算时每个cell的尺度为1,所以当前cell的左上角坐标为 (1,1) 。由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多。而 p w p_w pw p h p_h ph 是先验框的宽度与长度,前面说过它们的值也是相对于特征图大小的,在特征图中每个cell的长和宽均为1。这里记特征图的大小为 (W, H) (在文中是 (13, 13) ),这样我们可以将边界框相对于整张图片的位置和大小计算出来(4个值均在0和1之间):
b x = ( σ ( t x ) + c x ) / W b_x = (\sigma (t_x)+c_x)/W bx=(σ(tx)+cx)/W

b y = ( σ ( t y ) + c y ) / H \\ b_y = (\sigma (t_y) + c_y)/H by=(σ(ty)+cy)/H

b w = p w e t w / W \\b_w = p_we^{t_w}/W bw=pwetw/W

b h = p h e t h / H \\b_h = p_he^{t_h}/H bh=pheth/H

如果再将上面的4个值分别乘以图片的宽度和长度(像素点值)就可以得到边界框的最终位置和大小了。这就是YOLOv2边界框的整个解码过程。约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值提升了约5%。
在这里插入图片描述
7.Fine-Grained Features
同时Yolov2也参考了SSD的思路,输出定位信息是利用了前面好几层的定位信息的,v2也是如此,backbone输入320 * 320,最后输出是10 * 10,相当于32倍下采样,若按照v1的思想10 * 10会直接用来产生定位信息,而v2不止用了最后一层的feature map来产生定位信息,仿照SSD,v2用前面好几层卷积层产生的定位信息得到最后的结果,在backbone之后,加了两层卷积层,把第9层的输出拿出来(Route(-9)),(Route就是拿前面的层Route(-9)往前推9层),也就是第13层卷积层,输出大小是20 * 20,对于这个需要和第18层的输出10*10的结果和在一起,但是他们分辨率不一样,所以这里有个Reorg层就是做这个事情,它会把20 * 20拆分成4个10 * 10的,所以来自13层的20 * 20会重新组合成10 * 10的feature map,和来自18层卷积层输出的feature map拼在一起,最终形成一个10 * 10的feature map,contact之后再用卷积层去卷积,最后第23层的卷积结果用来输出定位结果。像这种Route的操作我们称为passthrough层,好处是:13层的20 * 20,14层的10 * 10,每做一次下采样定位信息都会被损害一次,若最后输出的结果能利用不同层之间的feature map的话,会对物体的定位结果有增强效果。

8.Multi-Scale Training

由于YOLOv2模型中只有卷积层和池化层,所以YOLOv2的输入可以不限于 416 × 416 416\times416 416×416 大小的图片。为了增强模型的鲁棒性,YOLOv2采用了多尺度输入训练策略,具体来说就是在训练过程中每间隔一定的iterations之后改变模型的输入图片大小。由于YOLOv2的下采样总步长为32,输入图片大小选择一系列为32倍数的值: { 320 , 352 , . . . , 608 } \{320, 352,..., 608\} {320,352,...,608} ,输入图片最小为 320 × 320 320\times320 320×320 ,此时对应的特征图大小为 10 × 10 10\times10 10×10 (不是奇数了,确实有点尴尬),而输入图片最大为 608 × 608 608\times608 608×608 ,对应的特征图大小为 19 × 19 19\times19 19×19 。在训练过程,每隔10个iterations随机选择一种输入图片大小,然后只需要修改对最后检测层的处理就可以重新训练。
在这里插入图片描述
总结来看,虽然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策略,这样同一个模型其实就可以适应多种大小的图片了。

YOLOv2的训练
YOLOv2的训练主要包括三个阶段。第一阶段就是先在ImageNet分类数据集上预训练Darknet-19,此时模型输入为 224 × 224 224\times224 224×224 ,共训练160个epochs。然后第二阶段将网络的输入调整为 448 × 448 448\times448 448×448 ,继续在ImageNet数据集上finetune分类模型,训练10个epochs,此时分类模型的top-1准确度为76.5%,而top-5准确度为93.3%。第三个阶段就是修改Darknet-19分类模型为检测模型,并在检测数据集上继续finetune网络。网络修改包括(网路结构可视化):移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个 3 × 3 × 2014 3\times3\times2014 3×3×2014卷积层,同时增加了一个passthrough层,最后使用 1 × 1 1\times1 1×1 卷积层输出预测结果,输出的channels数为 num anchors × ( 5 + num classes ) \text{num anchors}\times(5+\text{num classes}) num anchors×(5+num classes) ,和训练采用的数据集有关系。由于anchors数为5,对于VOC数据集输出的channels数就是125,而对于COCO数据集则为425。这里以VOC数据集为例,最终的预测矩阵为 T (shape为 ( batchsize \text{batchsize} batchsize, 13, 13, 125)),可以先将其reshape为 ( batchsize \text{batchsize} batchsize, 13, 13, 5, 25) ,其中 T[:, :, :, :, 0:4] 为边界框的位置和大小 ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th), T[:, :, :, :, 4] 为边界框的置信度,而 T[:, :, :, :, 5:] 为类别预测值。
在这里插入图片描述
在这里插入图片描述

YOLOv2的网络结构以及训练参数我们都知道了,但是貌似少了点东西。仔细一想,原来作者并没有给出YOLOv2的训练过程的两个最重要方面,即先验框匹配(样本选择)以及训练的损失函数,难怪Ng说YOLO论文很难懂,没有这两方面的说明我们确实不知道YOLOv2到底是怎么训练起来的。不过默认按照YOLOv1的处理方式也是可以处理,我看了YOLO在TensorFlow上的实现darkflow,发现它就是如此处理的:和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 13\times13 13×13 )的宽与高,而 A 指的是先验框数目(这里是5),各个 λ \lambda λ 值是各个loss部分的权重系数。第一项loss是计算background的置信度误差,但是哪些预测框来预测背景呢,需要先计算各个预测框和所有ground truth的IOU值,并且取最大值 M a x I O U Max_{IOU} MaxIOU,如果该值小于一定的阈值(YOLOv2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差。第二项是计算先验框与预测宽的坐标误差,但是只在前12800个iterations间计算,我觉得这项应该是在训练前期使预测框快速学习到先验框的形状。第三大项计算与某个ground truth匹配的预测框各部分loss值,包括坐标误差、置信度误差以及分类误差。先说一下匹配原则,对于某个ground truth,首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground truth的IOU值(YOLOv2中 b i a s m a t c h = 1 bias_{match}=1 biasmatch=1),计算IOU值时不考虑坐标,只考虑形状,所以先将先验框与ground truth的中心点都偏移到同一位置(原点),然后计算出对应的IOU值,IOU值最大的那个先验框与ground truth匹配,对应的预测框用来预测这个ground truth。在计算obj置信度时,target=1,但与YOLOv1一样而增加了一个控制参数rescore,当其为1时,target取预测框与ground truth的真实IOU值(cfg文件中默认采用这种方式)。对于那些没有与ground truth匹配的先验框(与预测框对应),除去那些Max_IOU低于阈值的,其它的就全部忽略,不计算任何误差。这点在YOLOv3论文中也有相关说明:YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了。这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框。尽管YOLOv2和YOLOv1计算loss处理上有不同,但都是采用均方差来计算loss。另外需要注意的一点是,在计算boxes的 w 和 h 误差时,YOLOv1中采用的是平方根以降低boxes的大小对误差的影响,而YOLOv2是直接计算,但是根据ground truth的大小对权重系数进行修正:l.coord_scale * (2 - truth.w*truth.h)(这里w和h都归一化到(0,1)),这样对于尺度较小的boxes其权重系数会更大一些,可以放大误差,起到和YOLOv1计算平方根相似的效果。

最终的YOLOv2模型在速度上比YOLOv1还快(采用了计算量更少的Darknet-19模型),而且模型的准确度比YOLOv1有显著提升,详情见paper。

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值