单阶段检测器-yolo v1、v2、v3多图详解

简介

单阶段目标检测是指没有显式给出提取候选区域的过程,直接得到最终的检测结果,将提取和检测合二为一,直接得到物体检测的结果,因此其速度往往会更快一些。            

非常典型的就是yolo形式的,可以发现其网络结构是从头到底都是网络的形式,经典的单阶段检测器的变换过程为:                                         YOLO(v1、v2、v3)   ->  SDD   ->   DSSD    ->    RetinaNet  

三种单阶段检测器的特点是:              

         [1]YOLO整合了整张图的信息来预测每个位置的物体,其将整张图作为输入预测得到原图中7*7的区域上每个部分所属的类别和定位相关的信息。包括yolo(2015年)、yolo v2(2016年)、yolo v3(2018年)              

         [2]SSD吸收了两阶段检测器的优良设计,并进行改进,包括SSD(2015年)、DSSD(2017年)              

         [3]RetinaNet对单阶段检测器的精度进行大幅度的提升,使得单阶段检测器能够超越双阶段检测器。

YOLO v1

1.Yolo  v1的基本思想是将整个图片作为网络的输入,针对图片先设定一个划分尺寸k*k,之后我们会按照划分的尺寸,针对图片划分后的每个小块进行判断预测,分别去预测这一小块所属的类别的概率、这个块所属的检测框的xywh数值。

下图是从输入到输出的例子,从最左侧的输入图,我们会按照k*k的方式进行图像划分(如7*7),划分出49个网格区域,后经过一系列卷积操作,我们最后会输出得到厚度为 (类别数+预测边框数B*4)、大小为k*k的预测结果特征图,根据这个图计算误差并训练。

2.下图是非常好的对Yolo  v1思想进行介绍的例子,左侧是输入的图像,首先进行网格的划分,根据最后得到的预测结果,我们能够得到上面预测出的边框和每个网格位置的分类概率(注意每个位置可能不止预测出一个边框、下面的颜色代表不同的类别),这样根据类别和边框就可以对不同类别进行边框圈定,得到最右侧的类别检测结果。 但是这里要注意的是每个网格点只能对应一个类别,但是可以有多个边界框预测结果,这是这些框并不是都要的,如果单元框缺失存在结果,则只选择与ground truth最大的边界框去预测目标,其他的框认为没有目标。这会导致如果格子内存在多个目标时,yolo也只能选一个训练,这是其缺点。

3.yolo v1对应的网络结构如下1图所示,其使用卷积层来提取特征,使用全连接层得到预测值,卷积层主要使用1*1和3*3尺寸的卷积,对于全连接层和全基层主要使用Leaky Rulu激活函数,最后用线性激活输出。

下2是对预测结果的解释,其厚度为30,其中包括对20个类别的概率预测,两个边框的x、y、w、h、confidence。(confidence 代表了所预测的 box 中含有 object 的置信度和这个 box 预测的有多准这两重信息),长度共30。

4.接下来对训练过程和预测过程进行分析。

在训练时其网络是如下的体系,输入高清448*448图片,先经过在Imagenet上预训练好的20层GoogleNet网络,之后经过随机初始化的4个卷积层和2个全连接层,得到最后下图的检测结果。

 

yolo进行训练时首先会计算损失,损失包括定位损失和分类损失两部分,两者是有所区别,对于定位误差相对于分类误差使用更大的权值,针对回归问题使用的均方差损失函数,下式是综合定位参数x、y、w、h和分类参数c的损失累加计算(误差解释参考https://www.bilibili.com/video/av23354360/?p=2),前两个是坐标误差,后俩是IOU误差,最后是分类误差。

在进行预测时,主要使用了之前提到的非极大值抑制算法(non maximum suppression, NMS),针对一个目标会被多次检测的问题,如图中左边很多框都圈定了人脸,但是我们只需要最好的红色检测框检测出的结果,为了保留最好的,我们使用NMS方法根据交并比IOU不断计算出去冗余的检测框(首先从所有的检测框中找到置信度最大的那个框【置信度是计算出的】,然后挨个计算其与剩余框的IOU,如果其值大于一定阈值(重合度过高),那么就将该框剔除;然后对剩余的检测框重复上述过程,直到处理完所有的检测框。)。

5.以上完成了对yolo结构的介绍,在优点上,其可以在较高的mAP上达到较快的检测速度,时间上最快能达到155FPS(FPS越大越快),并且因为其可以对整张图片做卷积,因此有更大的视野,不容易对背景造成误判(全连接层可以帮助attention),此外yolo有较好的泛化能力,可以在迁移时保持较好的鲁棒性。

                         

缺点如之前所述,Yolo仅仅预测两个边界框,且属于一个类别,因此对于小物体检测,其效果并不好,因为一个格子内可能包括多个物体,后面会再介绍。

YOLO v2

1.Yolo v1存在以下问题:

           [1]输入尺寸固定。由于输出层为全连接层,因此在检测时,YOLO 训练模型只支持与训练图像相同的输入分辨率。其它分辨率需要缩放成此固定分辨率。

           [2]占比较小的目标检测效果不好。虽然每个格子可以预测 B 个 bounding box,但是最终只选择只选择 IOU 最高的 bounding box 作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。

2.Yolo v2相对于yolo v1改进太多了,Yolo不断改进的过程就是集大家所长的过程,其思想太值得学习了,在这篇文章(https://blog.csdn.net/lwplwf/article/details/82895409,另一个还不错(https://blog.csdn.net/l7H9JA4/article/details/79955903)中有很好的v2与v1相对比改进的说明,简单解释下,分别是:            

         [1]引入Batch Normalization层。对网络每一层的输入都做归一化,这样网络就不需要每层都去学数据的分布,收敛会快点。为每个卷积层都添加了BN层,由于BN可以规范模型,所以加入BN后就把dropout去掉了,实验证明添加了BN层可以提高2%的mAP。

          [2]分类任务分辨率转换。对图像尺寸进行调整,之前的v1方式使用ImageNet进行分类模型的预训练时是使用224*224尺寸的图像输入,而在具体检测时则使用的是448*448的尺寸进行训练,这样会导致从分类模型到检测模型切换时,要适应分辨率的改变。          

          针对这一问题,v2将预训练过程分为两步,先用Imagenet上224*224的输入从头训练网络160个epoch,之后用Imagenet中448*448尺寸的图像训练10个epoch,之后再进行检测是用448*448的训练,从而不会有之前那种大的切换适应。                           

         [3]Convolutional With Anchor Boxes方式。首先v2模型删除了全连接层和最后一个pooling层,使得模型只有卷积层和池化层,这样就不必固定输入图片的大小,引入Faster R-CNN中anchor boxes的思想,使用anchor的方式产生更大数量的box生成框,这里不同于v1版本,划分的区域尺寸为13*13,在每个区域位置上都会产生5个anchor box区域,这五个先验框的选取并不是人工设定的,而是通过聚类算法计算出来的(固定的,对于不同数据集框大小不同),这样增大box数量能提升定位准确率。

          [4]使用k-means聚类算法来找到更好的边框先验,设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,所以聚类分析使用box与聚类中的box之间的IOU值作为距离指标。结果上这种先验方法 得到先验框的效果比手动设置的先验框平均IoU更高,更好训练,效果更好。

           [5]v1版本使用的训练网络是GoogleNet,其计算复杂度要优于VGG16,在Yolo v2中,使用了新的Darketnet-19网络作为基础网络(网上搜下,发现Darketnet其实就是在yolo这里配对提出的),网络包含19个卷积层和5个max pooling层,相对于包含24个卷积层和2个全连接层的Googlenet,其能大量减少计算量,最后使用average pooling代替v1中的全连接层产生预测结果。

           [6]因为模型为全连接层,因此不需要对输入尺寸进行限制,为了增加模型的泛化能力,我们使用多scale训练的方式,每隔10个batch选择一个新的image size进行训练。            

   以上等等,方式还有很多,就不一一介绍了....

3.接下来在训练时,针对分类网络和检测网络是不同的训练方式,会进行联合训练。

            [1]对于分类网络,其使用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%。

            [2]对于检测网络,作者去掉了原网络最后一个卷积层,转而增加了三个3 * 3 * 1024的卷积层(可参考darknet中cfg文件),并且在每一个上述卷积层后面跟一个1 * 1的卷积层,输出维度是检测所需的数量。作者的检测模型以0.001的初始学习率训练了160次,在60次和90次的时候,学习率减为原来的十分之一。其他的方面,weight decay为0.0005,momentum为0.9,依然使用了类似于Faster-RCNN和SSD的数据扩充(data augmentation)策略。

4.以上就介绍了Yolo v2大致的思想,可以发现其是在v1基础上进行了非常多的技巧上的改进,网络并没找到明确的整体架构的图,只能找到每个技巧改进的解释图(可以针对这几个技巧去学习),使用这些数十个改进使得性能有非常大的提升。

此外在VOC 2007数据集上对模型作比较,发现其速度和精度都是非常高的,每秒能够处理很多数量的frame帧数,且其精度是非常高的。

 

YOLO v3

1.yolo v3相对于v2,产生性能提升很大一部分是依靠于backbone网络的提升,从原来的darknet-19换成darknet-53网络,这样加深的网络使得性能更加强悍,虽然速度有所下降,但是可以自选择吧 相对于之前版本的yolo,yolo3在之前版本上保留了如下东西:                [1]“分而治之”,从yolo_v1开始,yolo算法就是通过划分单元格来做检测,只是划分的数量不一样(每个方格内判断分类和边框)。

               [2]采用"leaky ReLU"作为激活函数(是relu的变体,带泄露修正线性单元函数)。

               [3]端到端进行训练。一个loss function搞定训练,只需关注输入端和输出端

               [4]从yolo_v2开始,yolo就用batch normalization作为正则化、加速收敛和避免过拟合的方法,把BN层和leaky relu层接到每一层卷积层之后。

                [5]多尺度训练。在速度和准确率之间tradeoff。想速度快点,可以牺牲准确率;想准确率高点儿,可以牺牲一点速度。

2.在下图的架构中,有很多符号概念,我们先分别介绍下:

              [1]DBL如左下角所示,是一种卷积+BN+Leaky relu组合的方式,其是yolo v3的基本组件,BN和leaky relu和卷积层共同构成了v3的最小组件。

             [2]resn是resnet的残差模块,下面写的是resn形式,n代表数字表示第几个模块,每个resn结构是v3内的大模块,包含了两个DBL结构,使用这种残差的方式可以让网络变得更深,其内基本组件是DBL。

            [3]concat是进行张量拼接,将darknet中间层和后面的采样层进行拼接,拼接方式与残差层的add有所不同,其拼接会扩展张量的维度,而残差的add操作则是直接相加不会造成张量维度的改变。

3.整个网络结构共有252层,网络的组成形式如左边所示,先是Dark-53结构,之后是每个resn后跟着一个LeakyRelu,卷积层共有75层,其中72层卷积层会和BN、LeakyRelu一起组成基本组件DBL,此外每个res_block都会用一个零填充。

 4.针对于v3结构,我们分别介绍其特点:

                 [1]使用更为效果强悍的DarkNet-53作为其backbone,相对于Darket-19,其精度表现效果更好,但是速度不及darknet-19,可以看出v3并没有那么追求速度,而只是在保证实时性的基础上追求更好的performance精度表现,并且v3中去除了池化和全连接层,前向传播中尺寸的改变是通过改变卷积核的步长实现的。

                 [2]在输出上,yolo v3输出了三步不同尺寸的feature map,通过多尺度的输出来对不同size的目标进行检测,可以看到图中尺寸分别为13*13、26*26、52*52大小的网格划分,其厚度是255长度的,这个255是通过3*(5+80)计算出的,3表示每个网格单元要预测出3个box框,5表示每个box对应了x、y、w、h、confidence这5个相对基本参数,80是网格对应的分类,在coco数据集中80个类别,可以看出相对于v1,其能预测更多的box框,且box框能对应更多的类别,一个框能属于多个分类。

        [3]另一个是在v2版本上使用Bounding Box Prediction上再进行调整,对于v2而言,b-box prior数为5,在论文中并没有说明抛弃anchor机制之后是否抛弃了聚类得到的prior,如果prior数继续为5,那么v2需要对不同prior预测出 。对于v3而言,在prior这里的处理有明确解释:选用的b-box priors 的k=9,对于tiny-yolo的话,k=6。priors都是在数据集上聚类得来的,有确定的数值,如下

每个anchor prior(名字叫anchor prior,但并不是用anchor机制)就是两个数字组成的,一个代表高度另一个代表宽度。v3对b-box进行预测的时候,采用了logistic regression。这一波操作sao得就像RPN中的线性回归调整b-box。logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。

5.在另一个说法上,v3相对于v2进行了一些改进包括:

             [1]用logistic regression对方框置信度进行回归,对先验与实际方框IOU大于0.5的作为正例,与SSD不同的是,若有多个先验满足目标,只取一个IOU最大的先验。

             [2]对每个类别独立地使用logistic regression,用二分类交叉熵损失作为类别损失,可以很好地处理多标签任务。                         [3]利用多个scale进行预测,实际使用3个不同的scale。将前两层的feature-map进行上采样,与开始的feature-map进行concat起来,加一些卷积层,然后进行预测。

此外也说明了一些尝试,但是效果不好的方法:

            [1]使用线性激活函数回归x,y偏移,相对于方框长和宽的比例(YOLOv3中采用的是相对于方格的比例);这种方法降低了模型稳定性,并且效果不好;

            [2]使用线性激活函数直接预测x,y偏移,而不是logistic regression,导致map下降;

            [3]使用Focal Loss,map下降了2个点;

            [4]用两个阈值,IOU在0.3-0.7之间的忽略,小于0.3的作为负例。

6.在损失函数上,v3类似于v2,w和h的损失函数仍然采用平方误差,其他部分损失用二值交叉熵损失,从效果上看,v3毫无疑问现在成为了工程界首选的检测算法之一了,结构清晰,实时性好。并且yolo_v3给了近乎白痴的复现教程,不过很快的用上v3,但你不能很快地懂v3,需要一段时间的琢磨。

以下是实时下,物体检测和实例分割效果的展示,可以看到v3的效果真的是相当不错的。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值