YOLO五部曲之YOLO v2: Better Stronger

2020-09-23  本文已影响0人  未不明不知不觉

在上篇文章YOLO五部曲二之YOLO v1:Unified, Real-Time Object Detection中我们学习了YOLO v1的内容,在文章结尾我们点出来YOLO v1存在的一些问题,主要为以下两点:

  1. 定位不够准确
  2. 和Fast R-CNN等region proposal方法相比召回率更低

针对上面的问题,YOLO的作者做了下面的改进:

1. BatchNormalization

每个卷积层后面添加BN
实验结果:mAP提升了2%

2 High Resolution Classifier

YOLOV1预训练的时候使用的输入,检测的时候采用的是的输入,这会导致分类切换到检测的时候,模型需要适应图像分辨率的改变。
YOLOV2中将预训练分成两步:首先用的输入来训练大概160个,然后再把输入调整到再训练10个,然后再与训练好的模型上进行fine-tuning,检测的时候用就可以顺利过渡了。

实验结果:mAP提升了4%

Convolutions with Anchor Boxes

  1. YOLO v2移除了最后的全连接层,使用Anchor预测bouding box
  2. 移除了一个Pooling 层,增大了输出分辨率
  3. 使用416x416的图像训练网路,经过Pooling会得到一个13x13的网格输出
  4. 不使用anchor box的网络得到了69.5%mAP和81%Recall,
  5. 使用anchor box的网络获得了69.2%mAP和88%Recall,mAP少量下降,Recall大量提升,遂用之

Dimension Clusters

上面提到了使用Anchor,但是有两个问题 ,一是使用Anchor的尺寸,二是Anchor如何表示更容易学习,在Faster R-CNN和SSD中,先验框的维度(长和宽)都是手动设定的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测。因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析。比较了复杂度和精确度后,选用了K值为5,也就是选取了5中Anchor.

418分辨率下的五个Anchor大小[(0.57273, 0.677385), (1.87446, 2.06253), (3.33843, 5.47434), (7.88282, 3.52778), (9.77052, 9.16828)]

Direct Location Prediction

YOLO v1对Location没有做出约束,导致模型在训练的早期会不稳定,因为预测的bounding box 可能与原本的grid位置偏差很多
YOLO v2使用logistic激活函数σ对location进行了范围约束。

上面提到,每个格子有5个Anchor,每个Anchor预测五个值:t_x,t_y,t_w,t_h,conf,其中c_x,c_y是当前网格相对于左上角的坐标,Anchor的先验宽高为p_w,p_h,那么对Anchor进行微调后的bounding box(b_x,b_y,b_w,b_h),计算公式如下图:

实验结果: mAP提升了5%

Fine Grained Features

YOLO v2采用了416\times416的输入,这个尺度对于大的物体差不多够用,但是小物体可能还有问题,于是作者把前一层较高分辨率的特征图也加入了进来,前一层为2626512,当前为13\times13\times1024,作者将26 \times 26\times512映射成13\times 13\times 2048然后与13\times13\times1024链接,得到13\times13\times(1024+2048)的特征图,最后在此特征图进行卷积预测.

作者在后期的实现中借鉴了ResNet网络,不是直接对高分辨特征图处理,而是增加了一个中间卷积层,先采用64个 1\times1 卷积核进行卷积,然后再进行passthrough处理,这样 26\times26\times512的特征图得到 13\times13\times256的特征图。这算是实现上的一个小细节。使用Fine-Grained Features之后YOLOv2的性能有1%的提升。

实验结果:精度提升了1%

Multi-Scale Training

YOLO v2去掉了全链接层,理论上可以接受任意尺寸的输入,YOLO v2进行了5此最大池化,下采样32倍,所以YOLO v2使用了下面的策略进行多尺度训练:
每10个bach,随机使用新的分辨率图像进行训练,分辨率为等差32的数列{320,352,..,608}。

New BackBone (Faster)

使用Darknet-19,其对224\times244图像做一次前向传播需要55.8亿次浮点计算,比YOLO v1使用的VGG卷积网络更快,精度更高

Darknet-19
Darknet-19对精度和速度做好很好的tradeoff

Training for classification
作者使用Darknet-19在标准1000类的ImageNet上训练了160次,用的随机梯度下降法,starting learning rate 为0.1,polynomial rate decay 为4,weight decay为0.0005 ,momentum 为0.9。训练的时候仍然使用了很多常见的数据扩充方法(data augmentation),包括random crops, rotations, and hue, saturation, and exposure shifts。 (这些训练参数是基于darknet框架,和caffe不尽相同)

初始的224 * 224训练后,作者把分辨率上调到了448 \times 448,然后又训练了10次,学习率调整到了0.001。高分辨率下训练的分类网络在top-1准确率76.5%,top-5准确率93.3%。

Training for detection
分类网络训练完后,就该训练检测网络了,除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个 3\times3\times1024卷积层,同时增加了一passthrough层,最后使用 1\times1卷积层输出预测结果。对于VOC数据集,预测5种boxes大小,每个box包含5个坐标值和20个类别,所以总共是5 \times(5+20)= 125个输出维度。同时也添加了转移层(passthrough layer ),从最后那个3 \times 3 \times 512的卷积层连到倒数第二层,使模型有了细粒度特征。

作者的检测模型以0.001的初始学习率训练了160次,在60次和90次的时候,学习率减为原来的十分之一。其他的方面,weight decay为0.0005,momentum为0.9,依然使用了类似于Faster-RCNN和SSD的数据扩充(data augmentation)策略。

其他

YOLOv2的网络结构以及训练参数我们都知道了,但是貌似少了点东西。仔细一想,原来作者并没有给出YOLOv2的训练过程的两个最重要方面,即先验框匹配(样本选择)以及训练的损失函数,难怪Ng说YOLO论文很难懂,没有这两方面的说明我们确实不知道YOLOv2到底是怎么训练起来的。不过默认按照YOLOv1的处理方式也是可以处理,我看了YOLO在TensorFlow上的实现,发现它就是如此处理的:和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\times13的宽与高,而 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置信度时,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的 wh误差时,YOLOv1中采用的是平方根以降低boxes的大小对误差的影响,而YOLOv2是直接计算,但是根据ground truth的大小对权重系数进行修正:l.coord_scale * (2 - truth.w*truth.h)(这里w和h都归一化到(0,1)),这样对于尺度较小的boxes其权重系数会更大一些,可以放大误差,起到和YOLOv1计算平方根相似的效果

参考

  1. 小小将:目标检测|YOLOv2原理与实现
  2. 和蔼的zhxing:YOLO系列算法详解1:YOLOV2
  3. Sik-Ho Tsang:Review: YOLOv2 & YOLO9000 — You Only Look Once (Object Detection)
上一篇下一篇

猜你喜欢

热点阅读