目标检测 YOLO系列——YOLO v1

目标检测 YOLO系列——YOLO v1,第1张

YOLO v1:You Only Look Once: Unified, Real-Time Object Detection

YOLO v2:YOLO9000:Better,Faster,Stronger

YOLO v3:YOLOv3: An Incremental Improvement

近几年来,目标检测算法取得了很大的突破。比较流行的算法可以分为两类,一类是基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN, Faster R-CNN),它们是two-stage的,需要先使用启发式方法(selective search)或者CNN网络(RPN)产生Region Proposal,然后再在Region Proposal上做分类与回归。而另一类是Yolo,SSD这类one-stage算法,其仅仅使用一个CNN网络直接预测不同目标的类别与位置。第一类方法是准确度高一些,但是速度慢,但是第二类算法是速度快,但是准确性要低一些。这里我们谈的是Yolo-v1版本算法,其性能是差于后来的SSD算法的,但是Yolo后来也继续进行改进,产生了Yolo9000、YOLO v3算法。

传统方法常采用滑动窗口法,滑动窗口的目标检测算法思路非常简单,它将检测问题转化为了图像分类问题。其基本原理就是采用不同大小和比例(宽高比)的窗口在整张图片上以一定的步长进行滑动,然后对这些窗口对应的区域做图像分类,这样就可以实现对整张图片的检测了,如 DPM 就是采用这种思路。但是这个方法有致命的缺点,就是你并不知道要检测的目标大小是什么规模,所以你要设置不同大小和比例的窗口去滑动,而且还要选取合适的步长。但是这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了 selective search 方法来找到最有可能包含目标的子区域(Region Proposal),其实可以看成采用启发式方法过滤掉很多子区域,这会提升效率。

如果你使用的是CNN分类器,那么滑动窗口是非常耗时的。但是结合卷积运算的特点,我们可以使用CNN实现更高效的滑动窗口方法。这里要介绍的是一种全卷积的方法,简单来说就是网络中用卷积层代替了全连接层,如图所示。输入图片大小是16x16,经过一系列卷积 *** 作,提取了2x2的特征图,但是这个2x2的图上每个元素都是和原图是一一对应的,如图上蓝色的格子对应蓝色的区域,这不就是相当于在原图上做大小为14x14的窗口滑动,且步长为2,共产生4个字区域。最终输出的通道数为4,可以看成4个类别的预测概率值,这样一次CNN计算就可以实现窗口滑动的所有子区域的分类预测。这其实是overfeat算法的思路。之所可以CNN可以实现这样的效果是因为卷积 *** 作的特性,就是图片的空间位置信息的不变性,尽管卷积过程中图片大小减少,但是位置对应关系还是保存的。这个思路也被R-CNN借鉴,从而诞生了Fast R-cNN算法。

上面尽管可以减少滑动窗口的计算量,但是只是针对一个固定大小与步长的窗口,这是远远不够的。Yolo算法很好的解决了这个问题,它不再是窗口滑动了,而是直接将原始图片分割成互不重合的小方块,然后通过卷积最后生产这样大小的特征图,基于上面的分析,可以认为特征图的每个元素也是对应原始图片的一个小方块,然后用每个元素来可以预测那些中心点在该小方格内的目标,这就是Yolo算法的朴素思想。

整体来看,Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测,整个系统如图所示:首先将输入图片resize到448x448,然后送入CNN网络,最后处理网络预测结果得到检测的目标。相比R-CNN算法,其是一个统一的框架,其速度更快,而且Yolo的训练过程也是end-to-end的。

具体来说,Yolo的CNN网络将输入的图片分割成 网格,然后每个单元格负责去检测那些中心点落在该格子内的目标,如图所示,可以看到狗这个目标的中心落在左下角一个单元格内,那么该单元格负责预测这个狗。每个单元格会预测B个边界框(bounding box)以及边界框的 置信度 (confidence score)。所谓置信度其实包含两个方面,一是这个边界框含有目标的可能性大小,二是这个边界框的准确度。前者记为 ,当该边界框是背景时(即不包含目标),此时 。而当该边界框包含目标时, 。边界框的准确度可以用预测框与实际框(ground truth)的 IOU (intersection over union,交并比)来表征,记为 IOU 。因此置信度可以定义为 。

很多人可能将Yolo的置信度看成边界框是否含有目标的概率,但是其实它是两个因子的乘积,预测框的准确度也反映在里面。边界框的大小与位置可以用4个值来表征:(x,y,h,w),其中(x,y)是边界框的中心坐标,而w和h是边界框的宽与高。还有一点要注意,中心坐标的预测值(x,y)是相对于每个单元格左上角坐标点的偏移值,并且单位是相对于单元格大小的,单元格的坐标定义如图所示。而边界框的w和h预测值是相对于整个图片的宽与高的比例,这样理论上4个元素的大小应该在[0,1]范围。这样,每个边界框的预测值实际上包含5个元素:(x,y,w,h,c),其中前4个表征边界框的大小与位置,而最后一个值是置信度。

值得注意的是,不管一个单元格预测多少个边界框,其只预测一组类别概率值,这是Yolo算法的一个缺点,在后来的改进版本中,Yolo9000是把类别概率预测值与边界框是绑定在一起的。同时,我们可以计算出各个边界框类别置信度(class-specificconfidence scores):

边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。后面会说,一般会根据类别置信度来过滤网络的预测框。

总结一下,每个单元格需要预测 个值。如果将输入图片划分为 网格,那么最终预测值为 大小的张量。整个模型的预测值结构如下图所示。对于PASCALVOC数据,其共有20个类别,如果使用S=7,B=2,那么最终的预测结果就是 大小的张量。在下面的网络结构中我们会详细讲述每个单元格的预测值的分布位置。

Yolo采用卷积网络来提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层,如图所示。对于卷积层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数:max(x,0)。但是最后一层却采用线性激活函数。除了上面这个结构,文章还提出了一个轻量级版本Fast Yolo,其仅使用9个卷积层,并且卷积层中使用更少的卷积核。

可以看到网络的最后输出为 大小的张量。这和前面的讨论是一致的。这个张量所代表的具体含义如图所示。对于每一个单元格,前20个元素是类别概率值,然后2个元素是边界框置信度,两者相乘可以得到类别置信度,最后8个元素是边界框的(x,y,w,h)。大家可能会感到奇怪,对于边界框为什么把置信度c和(x,y,w,h)都分开排列,而不是按照(x,y,w,h,c)这样排列,其实纯粹是为了计算方便,因为实际上这30个元素都是对应一个单元格,其排列是可以任意的。但是分离排布,可以方便地提取每一个部分。这里来解释一下,首先网络的预测值是一个二维张量P,其shape为 。

采用切片,那么 就是类别概率部分 是置信度部分 是边界框的预测结果。这样,提取每个部分是非常方便的,这会方面后面的训练及预测时的计算。

在训练之前,先在ImageNet上进行了预训练,其预训练的分类模型采用图中前20个卷积层,然后添加一个average-pool层和全连接层。预训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。整个网络的流程如下图所示:

损失函数计算如下:

其中第一项是边界框中心坐标的误差项, 指的是第i个单元格存在目标,且该单元格中的第j个边界框负责预测该目标。第二项是边界框的高与宽的误差项。第三项是包含目标的边界框的置信度误差项。第四项是不包含目标的边界框的置信度误差项。而最后一项是包含目标的单元格的分类误差项, 指的是第i个单元格存在目标。

在说明Yolo算法的预测过程之前,这里先介绍一下非极大值抑制算法(non maximum suppression, NMS),这个算法不单单是针对Yolo算法的,而是所有的检测算法中都会用到。NMS算法主要解决的是一个目标被多次检测的问题,如图中人脸检测,可以看到人脸被多次检测,但是其实我们希望最后仅仅输出其中一个最好的预测框,比如对于美女,只想要红色那个检测结果。那么可以采用NMS算法来实现这样的效果:首先从所有的检测框中找到置信度最大的那个框,然后挨个计算其与剩余框的IOU,如果其值大于一定阈值(重合度过高),那么就将该框剔除;然后对剩余的检测框重复上述过程,直到处理完所有的检测框。

下面就来分析Yolo的预测过程,这里我们不考虑batch,认为只是预测一张输入图片。根据前面的分析,最终的网络输出是 ,但是我们可以将其分割成三个部分:类别概率部分为 ,置信度部分为 ,而边界框部分为 (对于这部分不要忘记根据原始图片计算出其真实值)。然后将前两项相乘可以得到 类别置信度值为 ,这里总共预测了 边界框。

所有的准备数据已经得到了,那么先说第一种策略来得到检测框的结果。首先,对于每个预测框根据类别置信度选取置信度最大的那个类别作为其预测标签,经过这层处理我们得到各个预测框的预测类别及对应的置信度值,其大小都是[7,7,2]。一般情况下,会设置置信度阈值,就是将置信度小于该阈值的box过滤掉,所以经过这层处理,剩余的是置信度比较高的预测框。最后再对这些预测框使用NMS算法,最后留下来的就是检测结果。一个值得注意的点是NMS是对所有预测框一视同仁,还是区分每个类别,分别使用NMS。Ng在deeplearning.ai中讲应该区分每个类别分别使用NMS,但是看了很多实现,其实还是同等对待所有的框,可能是不同类别的目标出现在相同位置这种概率很低吧。

上面的预测方法应该非常简单明了,但是对于Yolo算法,其却采用了另外一个不同的处理思路(至少从C源码看是这样的),其区别就是先使用NMS,然后再确定各个box的类别。其基本过程如图所示。对于98个boxes,首先将小于置信度阈值的值归0,然后分类别地对置信度值采用NMS,这里NMS处理结果不是剔除,而是将其置信度值归为0。最后才是确定各个box的类别,当其置信度值不为0时才做出检测结果输出。这个策略不是很直接,但是貌似Yolo源码就是这样做的。Yolo论文里面说NMS算法对Yolo的性能是影响很大的,所以可能这种策略对Yolo更好。

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

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

参考链接

YOLO算法的原理与实现

https://cloud.tencent.com/developer/article/1058057

传统的目标检测算法适用的场景有限,而且维护成本很大。深度学习方法应用于目标检测,不仅算法适应性好,还可以进行迁移学习,降低成本。

深度学习目标检测算法中,基于锚框(Anchor)的方法主要分为 一阶段 方法和 两阶段 方法。

两阶段 方法先对感兴趣的区域进行选择,然后进一步对候选框内做分类和回归,最终输出选择的框以及对应的分类。两阶段的模型有R-CNN系列,比如 R-CNN,Fast-RCNN,Faster-RCNN 等。两阶段模型的优点是精度高,但是速度及较慢。

一阶段 方法直接对anchor进行回归和分类,得到最终目标框和类别,算法有 YOLOv2,v3,SSD,RetinaNet 等。一阶段模型的推理速度较快,但是相对的精度会下降一些。

此外还有一些 anchor-free 的方法,包括基于关键点的检测算法以及基于中心检测算法等。

下面是一些基础概念和缩写:

BBox :Bounding Box 边界框

Anchor :锚框

RoI : Region of Interest 特定的感兴趣区域

Region Proposal : 候选区域

RPN : Region proposal network 提取候选区域的网络

IoU : Intersaction over Union (Area of Overlap/ Area of Union) 交并比,预测框的质量

mAP :mean average precision

NMS :non-maximum suppression 非极大值抑制

YOLO系列的模型在保有一定精度的基础上拥有很快的推理速度,在下面图中YOLOv3的推理速度远超其他模型,因此在实时监测领域中有很好的应用。

YOLO的名字来源于you only look once,从名字上就道出了YOLO的精髓。

YOLOv1将图像划分为S*S个网络,物体真实框的中心落在哪个网格上,哪个网格对应的锚框就负责检测物体。

每个网格会预测一个边界框以及对应的置信度,这里的置信度反映的是模型认为这个框里包含着物体的把握以及它预测到这个物体的精确程度。所以置信度就等于 。如果物体不存在,那么置信度应该等于零。

每个边界框会预测5个值 。(x,y)坐标表示框相对于网格单元边界的中心。 w,y是相对于整个图像预测宽度和高度。 最后,置信度预测表示预测框与任何真实框之间的IOU。

YOLOv2在v1的基础上进行了优化,骨干网络使用了DarkNet19,并且将输入图片给尺寸从224增大到448,并且将网络结构设为全卷积网络结构加上Batch Norm,使用了Kmeans聚类方法来计算anchor,引入了多尺度训练,使网络在训练过程中学习不同尺度的图像。不过待改进的地方有在小目标上召回率不高,靠近的群体目标检测效果不好,检测精度还有优化空间。

YOLOv3使用了更加深的骨干网络DarkNet53,同时加入了多尺度预测,在COCO数据集上聚类; 9中不同尺度的anchor,在分类上使用sigmoid激活函数,支持了目标的多分类。YOLOv3的优点是推理速度快,性价比高,通用性强;缺点是召回率较低,定位精度较差,对于靠近或者遮挡的群体、小物体的检测能力相对较弱。

YOLOv3在v1的基础上做了很多改动。

边界框预测

YOLOv3使用聚类预测到的边界框作为锚框。网络为边界框预测4个坐标值 ,如果单元格从图像的左上角偏移了 ,并且先验边界框的宽度和高度为 ,则预测如下图:

YOLOv3给每个边界框用逻辑回归预测一个objectness score,如果某个边界框和真实框重合度比其他都高,那么它的objectness score应该是1。而其他框虽然也与真实框有重叠,会被忽略掉。

类别预测

使用的是sigmoid函数,没有用softmax因为没必要。

不同尺度的预测

YOLOv3使用k-means聚类来确定bounding box priors,选择了9个clusters和3个scales,然后在整个scales上均匀分割clusters。在COCO数据集上,9个cluster分别为(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90) ,(156×198),(373×326)。

特征提取

YOLOv3使用了Darknet-53,特点是加入了残差,比之前的网络更深了(有53层卷积层所以叫Darknet-53)。

借一张图看一下YOLOv3的整个流程:

每个输出分支上对应着三个尺寸的先验框(总共3 3=9种尺度)。经过32倍下采样的网格,每一个网格对应着输入图像上32 32的区域,适合检测尺寸较大的目标,而8倍下采样的网格适合检测尺寸小的目标。

输出特征的高度H和宽度W,相当于将图像划分为H*W个网格,而不是直接在图像上画网格。也就是说32倍下采样之后得到的 ,相当于在输入图像上划一个 的网格,每一个网格对应着输出特征图上的一个点。

特征图的C通道上表示预测框的信息,包括坐标信息 ,目标置信度,分类。

C=B*(1+4+class_num),B为特征图上分配的锚框个数。

损失函数有三个,分类损失,定位损失和objectness损失。分类使用sigmoid激活函数,loss是sigmoid cross entropy。定位损失在x,y上使用sigmoid函数和sigmoid cross entropy损失,在w,h上使用L1损失。objectness损失用的是sigmoid激活函数和sigmoid cross entropy损失。

对于与真实框重叠的框,三种损失都要计算

对于没有真实框重叠的框,只计算objectness(0);对于与真实框重叠但不是最匹配的框,忽略它们。

目标检测是与计算机视觉和图像处理相关的计算机技术,用于在一张图片中识别出些物体的种类,同时要求标出物体的位置。目标检测已被广泛应用于人脸检测、自动驾驶和视频监控等图像领域。

目标检测中的常见方法,分为one-stage和two-stage两类。One-stage方法首先输入图片,输出Bounding box (bbox)和分类标签,由一个网络完成,该方法以YOLO、SSD为主要代表。Two-stage方法则以Faster-RCNN为代表,输入图片后,首先生成建议区域(Region Proposal),再输入分类器进行分类,两个任务由不同网络完成。

其中,YOLO目标检测是一种突出且优秀的算法,其为“you only look once”的缩写,意为只需浏览一次即可识别出图中物体的类别与位置,且完美地平衡了检测速度和精度之间的关系。YOLO也由最初的YOLO v1发展到现在最新的YOLO v5。

2015年提出了第一版YOLO v1,YOLO借鉴GoogleNet而提出了Darknet网络。Darknet是用C语言和CUDA编写的开源神经网络框架,用1x1卷积层+3x3卷积层替代GoogleNet的Inception模块。网络由24 层卷积层接2层全连接组成,如图1:

YOLO v1的框架如图2所示:首先调整图像大小为448×448,随后将图像输入CNN,最后通过非极大值抑制(NMS)保留最终标定框。

YOLO v1 的核心思想在于将目标检测视为回归问题,其将图片划分成 SxS 个网格,如果目标中心落入某网格单元,则该网格就负责检测该目标。每个网格单元预测 B个边界框(bbox)和类别信息。此外,每个bbox需要预测(x, y, w, h)和置信度共5个值。因此,最终每个网格应预测B个bbox和C个类别,最终输出S x S x (5*B+C)的tensor。

优点:

YOLO v2在YOLO v1基础上进行了一系列的改进,在保持分类精度的同时,提高了目标定位的精度以及召回率。首先,YOLO v2能够适应不同的输入尺寸,并可根据需要自行权衡检测准确率和检测速度;其次,根据层级分类提出了WordTree来混合检测数据集与分类数据集;最后,提出了可同时在检测和分类数据集上进行的联合训练方式,使用检测数据集训练模型识别部分,使用分类数据集训练模型分类部分,扩充检测种类。

对于YOLO v1更为具体的改进包括以下几点:

不过YOLO v2仍然无法解决同一个网格内物体重叠的问题。YOLO v3则继续在YOLO v2上做了些许改进:

2020年4月,YOLO v4重磅发布。其在MS COCO数据集上的精度达到了43.5% AP,速度达到65FPS,与 YOLO v3相比分别提高了 10% 和 12%。

YOLO v4首先对相关工作进行总结,并对目标检测框架拆分:

Object Detection = Backbone + Neck + Head

此外,将所有所有的调优手段分为两类:“Bag of freebies”和“Bag of specials”。

YOLO v4总结了以上各种调优技巧,从中寻找最优组合。并在训练过程中,验证了Bag-of-Freebies和Bag-of-Specials对于YOLO v4的影响。

自YOLO v4发布的40余天后, Ultralytics公司开源了非官方的YOLO v5,其完全基于PyTorch实现。值得注意的是,每个图像的推理时间达到140 FPS,并且YOLOv5的权重文件大小仅为YOLOv4的1/9。YOLO v5更快,也更小巧!

由以上YOLO的发展历程可看出, YOLO系列的发展后期更重视应用落地,没有提出非常新颖的创新点。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11980768.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存