YOLO系列网络原理

文章目录

    • 研究背景
    • 初代YOLO
      • 算法优点
      • 算法结构
      • 网络结构
      • 网络预测
      • 回顾汇总下YOLO的检测过程
      • 优缺点分析
    • YOLOv2
    • YOLOv3
      • 网络结构
    • YOLO和Faster RCNN的异同

研究背景

首先先介绍一下滑动窗口技术,这对我们理解Yolo算法是有帮助的。采用滑动窗口的目标检测算法思路非常简单,它将检测问题转化为了图像分类问题。其基本原理就是采用不同大小和窗口在整张图片上以一定的步长进行滑动,然后对这些窗口对应的区域做图像分类,这样就可以实现对整张图片的检测了,如下图3所示,如DPM就是采用这种思路。但是这个方法有致命的缺点,就是你并不知道要检测的目标大小是什么规模,所以你要设置不同大小的窗口去滑动,而且还要选取合适的步长。但是这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了selective search方法来找到最有可能包含目标的子区域(Region Proposal),其实可以看成采用启发式方法过滤掉很多子区域,这会提升效率。
近几年来,目标检测算法取得了很大的突破。比较流行的算法可以分为两类,一类是基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN, Faster R-CNN),它们是two-stage的,需要先使用启发式方法(selective search)或者CNN网络(RPN)产生Region Proposal,然后再在Region Proposal上做分类与回归。滑窗需要大的计算量,需要快速的CNN模型而另一类是Yolo,SSD这类one-stage算法,其仅仅使用一个CNN网络直接预测不同目标的类别与位置。第一类方法是准确度高一些,但是速度慢,但是第二类算法是速度快,但是准确性要低一些。

初代YOLO

论文地址:https://arxiv.org/abs/1506.02640
研究代码地址:https://pjreddie.com/darknet/yolo/

算法优点

1,速度非常快,在Titan X GPU上的速度是45fps(一秒钟45张图像);
2,基于图像的全局信息进行预测的,与Fast R-CNN相比,YOLO在误检方面的错误率能降低一半多;
3,YOLO可以学到物体的生成规律,泛化能力强
4,准确率高

算法结构

1,resize图像大小至标准大小 448 × \times × 448
2,卷积神经网络
3,根据模型置信度预测目标位置:算法首先将图像划分为SxS个格子(grid cell),每个格子预测B个框(bounding box),每个格子都包含预测的五个值:x,y,w,h和置信度confidence
x,y是预测的框的中心坐标,相对于格子的重心坐标的偏移量,w,h是预测框的大小,分别除以图像的w,h进行归一化,值在0-1之间。
最后每个格子预测所有类别的概率,比如PASCAL VOC数据有20个类别
YOLO系列网络原理_第1张图片
图像说明:每个预测框都对应一个置信度,如果格子里没有目标,则置信度为0,C为类别可能性。预测编码程S × \times ×S × \times ×(B × \times × 5+C)的向量
所谓置信度其实包含两个方面,一是这个边界框含有目标的可能性大小,二是这个边界框的准确度。前者记为Pr(object),当该边界框是背景时(即不包含目标),此时Pr(object)=0。而当该边界框包含目标时,Pr(object)=1。边界框的准确度可以用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征,记为IOU。
置信度计算公式代表所预测的box中含有的object中含有object的置信度以及这个box预测的多准两种信息Pr(Object) × \times ×IOU
每个预测框对应一个置信度,如果有目标为Pr为1否则为0,置信度预测的预测框和ground truth 的IOU值。
IOU:模型产生的目标串口和原来标记窗口的交叠率:面积交集/面积并集
如何判断格子里包含物体呢?如果一个物体的ground turth 的中心坐标在一个grid cell中,那么这个格子里就包含这个物体,就说这个object的预测由该格子负责
置信度矩阵:得到20 × \times ×(7 × \times × 7 × \times × 2)=20 × \times × 98的置信度矩阵
20是类别个数,7 × \times × 7是切割格子数,2是在每个格子预测的框的个数
接下来的操作在20个类别轮流进行:
在某个类别中(矩阵中的某一行),将得分少于阈值的设置为0(论文中是0.2),然后在按得分由高到低排序。再用NMS算法去掉重复率较大的预测框。最后每个预测框的20个置信度取最大的值,如果大于0,则这个预测框就是这个置信度对应的类别。得到 class probability map

网络结构

网络主要采用GoogLeNet,包含24个卷积层和2个全连接层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数:max(x,0)。但是最后一层却采用线性激活函数。卷积层主要用来提取特征,全连接层用来预测概率与坐标。最后输出7 × \times × 7 × \times × 30,30=(B × \times × 5+C),5是5个参数:x,y,w,h,confindence
对于每一个单元格,前20个元素是类别概率值,然后2个元素是边界框置信度,两者相乘可以得到类别置信度,最后8个元素是边界框的(x,y,w,h)。大家可能会感到奇怪,对于边界框为什么把置信度c和(x,y,w,h)都分开排列,而不是按照(x,y,w,h)这样排列,其实纯粹是为了计算方便,因为实际上这30个元素都是对应一个单元格,其排列是可以任意的。
YOLO系列网络原理_第2张图片
两个细节:
1,作者先在ImageNet数据集上预训练网络,而且网络只采用前面的20个卷积层,输入是224*224的图像。然后在检测的时候再加上随机初始化的4个卷积层和2个全连接层,同时输入改为更高分辨率的448 × \times × 448.
2,Relu层改为pRelu,即当想x<0时,激活值是0.1 × \times × x,而不是传统的0.
损失函数
Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同的部分采用了不同的权重值。首先区分定位误差和分类误差。对于定位误差,即边界框坐标预测误差,采用较大的权重5。然后其区分不包含目标的边界框与含有目标的边界框的置信度,对于前者,采用较小的权重值0.5.
其它权重值均设为1。然后采用均方误差,其同等对待大小不同的边界框,但是实际上较小的边界框的坐标误差应该要比较大的边界框要更敏感。为了保证这一点,将网络的边界框的宽与高预测改为对其平方根的预测,即预测值变为(x,y , w \sqrt{ w } w , h \sqrt{ h } h )
综合以上误差函数为:
YOLO系列网络原理_第3张图片
其中第一项是边界框中心坐标的误差项,指的是第i个单元格存在目标,且该单元格中的第j个边界框负责预测该目标。第二项是边界框的高与宽的误差项。第三项是包含目标的边界框的置信度误差项。第四项是不包含目标的边界框的置信度误差项。而最后一项是包含目标的单元格的分类误差项,指的是第i个单元格存在目标。

网络预测

用到了一个极大值抑制算法:解决一个目标被多次检测的问题。我们希望最后仅仅输出其中一个最好的预测框。那么可以采用NMS算法来实现这样的效果:首先从所有的检测框中找到置信度最大的那个框,然后挨个计算其与剩余框的IOU,如果其值大于一定阈值(重合度过高),那么就将该框剔除;然后对剩余的检测框重复上述过程,直到处理完所有的检测框。

回顾汇总下YOLO的检测过程

1,在YOLO网络中,首先通过一组CNN提取feature maps
2,然后通过最后一个全连接层生成SxSx(5B+C)=7x7x(52+20)=1470长的向量
3,最终的去网络输出是7 × \times × 7 × \times × 30,但是我们可以将其分割成三个部分:类别概率部分为[7,7,20],置信度部分为[7,7,2,2],而边界框部分为[7,7,2,4](对于这部分不要忘记根据原始图片计算出其真实值)。然后将前两项相乘可以得到类别置信度值为[7,7,2,20],这里总共预测了7 × \times × 7 × \times × 2=98边界框。
然后将边际框进行筛选:
普通方式
首先,对于每个预测框根据类别置信度选取置信度最大的那个类别作为其预测标签,经过这层处理我们得到各个预测框的预测类别及对应的置信度值,其大小都是[7,7,2],
Ng在deeplearning.ai中讲应该区分每个类别分别使用NMS,但是看了很多实现,其实还是同等对待所有的框,我觉得可能是不同类别的目标出现在相同位置这种概率很低吧。
YOLO
其区别就是先使用NMS,然后再确定各个box的类别。其基本过程如图12所示。对于98个boxes,首先将小于置信度阈值的值归0,然后分类别地对置信度值采用NMS,这里NMS处理结果不是剔除,而是将其置信度值归为0。最后才是确定各个box的类别,当其置信度值不为0时才做出检测结果输出。这个策略不是很直接,但是貌似Yolo源码就是这样做的。Yolo论文里面说NMS算法对Yolo的性能是影响很大的,所以可能这种策略对Yolo更好。

优缺点分析

可以看到,Yolo的Correct的是低于Fast R-CNN。另外Yolo的Localization误差偏高,即定位不是很准确。但是Yolo的Background误差很低,说明其对背景的误判率较低。Yolo的那篇文章中还有更多性能对比,感兴趣可以看看。

现在来总结一下Yolo的优缺点。首先是优点,Yolo采用一个CNN网络来实现检测,是单管道策略,其训练与预测都是end-to-end,所以Yolo算法比较简洁且速度快。第二点由于Yolo是对整张图片做卷积,所以其在检测目标有更大的视野,它不容易对背景误判。其实我觉得全连接层也是对这个有贡献的,因为全连接起到了attention的作用。另外,Yolo的泛化能力强,在做迁移时,模型鲁棒性高。

最后不得不谈一下Yolo的缺点,首先Yolo各个单元格仅仅预测两个边界框,而且属于一个类别。对于小物体,Yolo的表现会不如人意。这方面的改进可以看SSD,其采用多尺度单元格。也可以看Faster R-CNN,其采用了anchor boxes。Yolo对于在物体的宽高比方面泛化率低,就是无法定位不寻常比例的物体。当然Yolo的定位不准确也是很大的问题。

YOLOv2

论文地址:https://arxiv.org/abs/1612.08242
是YOLO系列变化的重要一步
YOLOv1具有速度快的优势,但是定位不够准,召回率低,为了提升定位准确度,提高找回度,YOLOv2的改进如下:

1.** 批量归一化**
在每个卷积层后面增加VB层,去掉全连接的dropout,使得BN(batch normallization)策略(类似于正则化)map值提高2%。
2. 高分辨率
YOLOv2将输入的分辨率提升到,同时,为了使网络适应高分辨率,YOLOv2先在ImageNet上高分辨率对网络进行10个epoch的微调,让网络适应高分辨率的输入。 通过使用高分辨率的输入,YOLOv2将map值提高了约4%。
3. 基于卷积的Anchor机制 是启发Faster R-CNN的 anchor boxes。
YOLOv1利用全连接层直接对边界框进行预测,导致丢失较多空间信息,定位不准。YOLOv2去掉了YOLOv1中的全连接层,使用Anchor Boxes预测边界框,同时为了得到更高分辨率的特征图,YOLOv2还去掉了一个池化层。由于图片中的物体都倾向于出现在图片的中心位置,若特征图恰好有一个中心位置,利用这个中心位置预测中心点落入该位置的物体,对这些物体的检测会更容易。所以总希望得到的特征图的宽高都为奇数。YOLOv2通过缩减网络,使用416x416的输入,模型下采样的总步长为32,最后得到13x13的特征图,然后对13x13的特征图的每个cell预测5个anchor boxes,对每个anchor box预测边界框的位置信息、置信度和一套分类概率值。使用anchor boxes之后,YOLOv2可以预测13x13x5=845个边界框,模型的召回率由原来的81%提升到88%,mAP由原来的69.5%降低到69.2%.召回率提升了7%,准确率下降了0.3%。这里我们和SSD以及Faster-RCNN做个对比,Faster RCNN输入大小为1000*600时的boxes数量大概是6000,在SSD300中boxes数量是8732。显然增加box数量是为了提高object的定位准确率。
4. 维度聚类
在Faster-RCNN中,Anchor都是手动设定的,YOLOv2使用k-means聚类算法对训练集中的边界框做了聚类分析,尝试找到合适尺寸的Anchor。另外作者发现如果采用标准的k-means聚类,在box的尺寸比较大的时候其误差也更大,而我们希望的是误差和box的尺寸没有太大关系。所以通过IOU定义了如下的距离函数,使得误差和box的大小无关。论文最后选择聚类的簇个数为k=5.在结果测试时,YOLOv2采用的5种Anchor可以达到的Avg IOU是61,而Faster-RCNN采用9种Anchor达到的平均IOU是60.9,也即是说本文仅仅选取5种Anchor就可以达到Faster-RCNN中9种Anchor的效果

  1. 新的Backbone:Darknet-19
    YOLOv2采用Darknet-19,其网络结构如下图所示,包括19个卷积层和5个max pooling层,主要采用卷积和卷积,这里卷积可以压缩特征图通道数以降低模型计算量和参数,每个卷积层后使用BN层以加快模型收敛同时防止过拟合。最终采用global avg pool 做预测。采用YOLOv2,模型的mAP值没有显著提升,但计算量减少了(提高了速度)。
    YOLO系列网络原理_第4张图片

  2. 直接位置预测
    虽然采用了Faster-RCNN中的Anchor,但是预测值还是采用YOLO的方式,即直接预测相对于grid cell的坐标位置的方式。
    前面提到网络在最后一个卷积层输出13*13大小的特征图,然后每个cell预测5个bounding box,然后每个bounding box预测5个值:,,,和(这里的类似YOLOv1中的confidence)。和经过sigmoid函数处理后范围在0到1之间,这样的归一化处理使得模型训练更加稳定。和表示一个cell和图像左上角的横纵距离。和表示bounding box的宽高,这样bx和by就是cx和cy这个cell附近的anchor来预测tx和ty得到的结果。

  3. 细粒度特征
    YOLOv2提取Darknet-19最后一个max pool层的输入,得到26x26x512的特征图。经过1x1x64的卷积以降低特征图的维度,得到26x26x64的特征图,然后经过pass through层的处理变成13x13x256的特征图(抽取原特征图每个2x2的局部区域组成新的channel,即原特征图大小降低4倍,channel增加4倍),再与13x13x1024大小的特征图连接,变成13x13x1280的特征图,最后在这些特征图上做预测。使用Fine-Grained Features,YOLOv2的性能提升了1%。

  4. 多尺度训练(可以适应低分辨率和高分辨率图像 )
    网络结构只有卷积层和池化层,对输入图片的大小没有限制。YOLOv2采用多尺度输入的方式训练,在训练过程中每隔10个batches,重新随机选择输入图片的尺寸,由于Darknet-19下采样总步长为32,输入图片的尺寸一般选择32的倍数{320,352,…,608}。采用Multi-Scale Training, 可以适应不同大小的图片输入,当采用低分辨率的图片输入时,mAP值略有下降,但速度更快,当采用高分辨率的图片输入时,能得到较高mAP值,但速度有所下降。

  5. 训练
    主要包括分类网络和监测网络的训练
    第一阶段:作者使用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 * 448,然后又训练了10次,学习率调整到了0.001。高分辨率下训练的分类网络在top-1准确率76.5%,top-5准确率93.3%。
    第二个阶段:分类网络训练完后,就该训练检测网络了,作者去掉了原网络最后一个卷积层,转而增加了三个3 * 3 * 1024的卷积层(可参考darknet中cfg文件),并且在每一个上述卷积层后面跟一个1 * 1的卷积层,输出维度是检测所需的数量。对于VOC数据集,预测5种boxes大小,每个box包含5个坐标值和20个类别,所以总共是5 * (5+20)= 125个输出维度。同时也添加了转移层(passthrough layer ),从最后那个3 * 3 * 512的卷积层连到倒数第二层,使模型有了细粒度特征。作者的检测模型以0.001的初始学习率训练了160次,在60次和90次的时候,学习率减为原来的十分之一。其他的方面,weight decay为0.0005,momentum为0.9,依然使用了类似于Faster-RCNN和SSD的数据扩充(data augmentation)策略。
    改进方法对效果的提升:
    YOLO系列网络原理_第5张图片

YOLOv3

pytorch实现代码:https://www.jiqizhixin.com/articles/2018-04-23-3
tensorflow2.0实现的github:https://github.com/YunYang1994/TensorFlow2.0-Examples/tree/master/4-Object_Detection/YOLOV3
论文地址:https://arxiv.org/abs/1804.02767
相对于YOLOv2的完善如下:
1,继承了YOLOv2的bbox预测任务的方法,对bbox分类任务进行了修改,用简单的logistic替换了softmax
网络结构上就将原来用于单标签多分类的softmax层换成用于多标签多分类的逻辑回归层。为什么要做这样的修改,原来分类网络中的softmax层都是假设一张图像或一个object只属于一个类别,但是在一些复杂场景下,一个object可能属于多个类,比如你的类别中有woman和person这两个类,那么如果一张图像中有一个woman,那么你检测的结果中类别标签就要同时有woman和person两个类,这就是多标签分类,需要用逻辑回归层来对每个类别做二分类。逻辑回归层主要用到sigmoid函数,该函数可以将输入约束在0到1的范围内,因此当一张图像经过特征提取后的某一类输出经过sigmoid函数约束后如果大于0.5,就表示属于该类。
YOLOv3不使用Softmax对每个框进行分类,主要考虑因素有两个:

  1. Softmax使得每个框分配一个类别(score最大的一个),而对于Open Images这种数据集,目标可能有重叠的类别标签,因此Softmax不适用于多标签分类。
  2. Softmax可被独立的多个logistic分类器替代,且准确率不会下降。分类损失采用binary cross-entropy loss.

**2,YOLO v3采用多个scale融合的方式做预测——predictions across scales **多尺度预测
原来的YOLO v2有一个层叫:passthrough layer,假设最后提取的feature map的size是1313,那么这个层的作用就是将前面一层的2626的feature map和本层的1313的feature map进行连接,有点像ResNet。当时这么操作也是为了加强YOLO算法对小目标检测的精确度。
有一个概念叫做:bounding box prior,其实就是实现聚类得到的几个检测边框,YOLO V2和YOLO V3均采用了这种方式,但是又有所不同。
关于bounding box的初始尺寸还是采用YOLO v2中的k-means聚类的方式来做,这种先验知识对于bounding box的初始化帮助还是很大的,毕竟过多的bounding box虽然对于效果来说有保障,但是对于算法速度影响还是比较大的。作者在COCO数据集上得到的9种聚类结果:(10
13); (1630); (3323); (3061); (6245); (59119); (11690); (156198); (373326),这应该是按照输入图像的尺寸是416416计算得到的。
回顾前面的YOLO V2是怎么做的,YOLO V2一共有13
13个cell,每一个cell预测5个候选框,故而总的Box数目为:
但是由于YOLO V3采用了多个不同的尺度的特征图,每一张特征图上均采用3个候选框,
对于1313的特征图,有13133;
对于26
26的特征图,有26263;
对于5252的特征图,有5252*3;
将9个的预测框都使用了。很明显,YOLO V3的措施单从数量上来说就已经比V2版本多了很多,不仅如此,由于V3版本特征图的尺度是不一样的,而且应用在每一个特征图上的候选框的大小也是不一样的,这样对于不同尺寸的目标的适应能力自然更强了。
3,加深了DarkNet(19->53) ,速度慢了些,但是更好的抽取特征和保留小物体的位置信息

Yolov3延续YOLOv2是基于一款小众的深度学习框架——darknet的目标检测开源项目,darknet短小精悍,虽然功能和复用性不如当前大火的深度学习框架Tensorflow和Caffe2,但由于其源码都是用纯C语言和CUDA底层编写的,所以它的特点让它在Yolov3项目中大放光彩:速度快,充分发挥多核处理器和GPU并行运算的功能。所以,Yolov3的快速检测正好适合我们这种需要实时检测视频帧的项目;此外,它的准确度也非常高,在尺寸中等偏小的物体上有非常高的准确率,这得益于它的训练方式(会在下面介绍),但在大尺寸的物体,比如占到了整个图片百分之60的物体,识别率则不尽如人意。
特点:c语言实现
没有依赖项
容易安装
移植性好
支持cpu和GPU两种训练模式
网络特点

  1. darknet-53中无池化层,全连接层,特征图的缩小是通过增加卷积核的步长实现的;一方面基本采用全卷积(YOLO v2中采用pooling层做feature map的sample,这里都换成卷积层来做了)
  2. darknet-53中 CNN Kernel+BN+LeakyRelu 成为了标准组件;
  3. darknet-53采用了残差的设计思想;

一张416416大小的图片输入,会经过很多层的深度卷积(图片中略过了层数)一直降维到52,26和13。
在52,26和13维分别有三个全卷积特征提取器,对应的是右边的Convolutional Set,这就是特征提取器的内部卷积核结构,1
1的卷积核用于降维,3*3的卷积核用于提取特征,多个卷积核交错达到目的。每个全卷积特征层是有连接的,在图中为Concatenate标志,意味着当前特征层的输入有来自于上一层的输出的一部分。每个特征层都有一个输出Predict,即预测结果,最后根据置信度大小对结果进行回归,得到最终的预测结果。

这就是整个Yolov3中Darknet网络算法的特点和流程。

网络结构

Yolov3最重要的内容就是一个庞大而丰富的深度卷积神经网络模型,它一共有53个全连接卷积层,所以作者在Github上又将该项目称为Darknet-53,但实际上卷积层不止53层,因为特征提取也用到了大量的卷积核。
YOLO系列网络原理_第6张图片

YOLO和Faster RCNN的异同

1.Faster RCNN将目标检测分解为分类问题和回归为题分别求解:首先采用独立的RPN网络专门求取region proposal,计算图中物体位置,然后利用 bounding box 回归对提取的region propasal进行位置修正,最后采用
softmax进行分类,识别物体类别。
2,YOLO将物体检测作为一个回归问题进行求解:输入图像经过一次网络,便能得到图像中所有物体的位置和所属类别及相应的置信概率。
总结:YOLO将整个检测问题整合为一个回归问题,使得网络结构简单,检测速度大大加快;由于网络没有分支,所以训练也只需要一次即可完成。这种“把检测问题转化为回归问题”的思路非常高效,之后的很多检测算法(包括SSD)都借鉴了此思路。

你可能感兴趣的:(目标检测,图像处理,算法)