您现在的位置是:主页 > news > 建设工程招投标网站/谷歌网页版入口
建设工程招投标网站/谷歌网页版入口
admin2025/6/5 21:20:56【news】
简介建设工程招投标网站,谷歌网页版入口,镇江个人网站制作,微信公众号网页设计看了各路大神的分享整合下来的。。。。 原文: 链接:https://zhuanlan.zhihu.com/p/32525231 链接:https://blog.csdn.net/shengyan5515/article/details/84036734 链接:https://zhuanlan.zhihu.com/p/37850811 前言 目标检测可以看成图像分…
看了各路大神的分享整合下来的。。。。
原文:
链接:https://zhuanlan.zhihu.com/p/32525231
链接:https://blog.csdn.net/shengyan5515/article/details/84036734
链接:https://zhuanlan.zhihu.com/p/37850811
前言
目标检测可以看成图像分类与定位的结合,给定一张图片,目标检测系统要能够识别出图片的目标并给出其位置,由于图片中目标数是不定的,且要给出目标的精确位置,目标检测相比分类任务更复杂。
目标检测算法可以分为两类:
一类是基于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网络直接预测不同目标的类别与位置。
如图1,第一类方法是准确度高一些,但是速度慢,第二类算法则相反。

图1
题外话
目标检测就是要找出图片中物体的bounding box(边界框),并判定框内物体的类别。比如图2中有一只猫,要将这只猫用一个bounding box框出来(bounding box可以用中心坐标(x,y)(x,y)(x,y)和矩形的宽高(w,h)(w,h)(w,h)来表示)。
这种任务怎么做?自然的想法就是,把图片喂给深度模型,让网络学习出bounding box的xywhxywhxywh四个值以及图片类别。但如果图片上除了一只猫外还有一只狗,甚至更多物体,想把它们框出来,那么这时候网络不仅要输出猫的预测,还要输出其他物体的预测,模型的输出维度是没法固定的,图片中目标越多,输出维度就越大。

图2
既然模型输出需要固定维度,那能不能设计一个有固定维度大小输出的网络,输出维度足够大,足以囊括图像中所有物体呢?yolo就是这么做的。yolo固定维度的办法是把模型输出划分成网格状,每个网格中的cell(格子)都可以输出物体的类别和bounding box的坐标,如图3所示:

图3
问题关键是,怎么知道cell需要预测图片中的哪个物体呢?这其实取决于怎么去设置模型的训练目标,就是,你要教它去预测哪个物体。具体来说,yolo是这么做的:
将输入图像按照模型的输出网格(7x7)划分,划分之后就有很多cell。图片中物体的中心是落在哪个cell里面,哪个cell就负责预测这个物体。比如图4中,狗的中心落在了红色cell内,则这个cell负责预测狗。

图4
“物体的中心是落在哪个cell里面,哪个cell就负责预测这个物体”分两个阶段来看:
- 训练阶段:如果物体中心落在这个cell,就给这个cell打上这个物体的label(包括xywhxywhxywh和类别)。换言之,在训练阶段,就教会cell要预测图像中的哪个物体。
- 测试阶段:因为训练阶段已经教会了cell去预测中心落在该cell中的物体,那么cell自然也会这么做。
以上就是yolo的核心思想。不过原文都是按照测试阶段来解说的,不容易理解。其实,知道训练阶段的意义更重要,因为训练阶段你告诉网络去预测什么,然后测试阶段才能按照你训练阶段教它的去做,如果你只知道测试阶段网络输出的意义,你就很可能会问:凭什么物体的中心落在这个cell它就负责预测这个物体?
滑动窗口与CNN(还是题外话)
采用滑动窗口的目标检测算法思路非常简单,将检测问题转化为图像分类问题。基本原理就是采用不同大小和比例(宽高比)的窗口在整张图片上以一定的步长滑动,然后对窗口对应区域做图像分类,这样就可以实现对整张图片的检测。但是这个方法有致命缺点,不知道要检测的目标大小是什么规模,所以要设置不同大小和比例的窗口,还要选取合适的步长。这样会产生很多的子区域,都要经过分类器去做预测,需要很大的计算量。解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了selective search方法来找到最有可能包含目标的子区域(Region Proposal),可以看成采用启发式方法过滤掉很多子区域。

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

图6
尽管可以减少滑动窗口的计算量,但只是针对一个固定大小与步长的窗口,还是远远不够的。Yolo算法很好的解决了这个问题,它不再是窗口滑动,而是将原始图片分割成互不重合的小方块,然后通过卷积最后产生特征图。可以认为特征图的每个元素也是对应原始图片的一个小方块,然后用每个元素来预测那些中心点在该小方格内的目标。
yolo设计理念
Yolo算法采用一个单独的CNN模型实现end-to-end的目标检测,整个系统如图7:首先将输入图片resize到448x448,然后送入CNN网络,最后处理网络预测结果得到检测的目标。相比R-CNN算法,是一个统一的框架,其速度更快,而且Yolo的训练过程也是end-to-end 的。

图7
具体来说,Yolo的CNN网络将输入的图片分割成 S∗SS*SS∗S 个网格(cell),每个单元格负责检测那些中心点落在该格子内的目标。每个单元格会预测 BBB 个边界框(bounding box)以及边界框的置信度(confidence score)。
所谓置信度其实包含两个方面:
- 边界框含有目标的可能性大小,记为Pr(object)Pr(object)Pr(object):
Pr(object)=0Pr(object)=0Pr(object)=0:当该边界框是背景时(即不包含目标)
Pr(object)=1Pr(object)=1Pr(object)=1:当该边界框包含目标时。
- 边界框的准确度
边界框的准确度可以用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征**,记为 IOUpredtruth{IOU}^{truth}_{pred}IOUpredtruth。
因此置信度可以定义为 : Pr(object)∗IOUpredtruthPr(object)*{IOU}^{truth}_{pred}Pr(object)∗IOUpredtruth 。
边界框的大小与位置用4个值来表征:(x,y,w,h)(x,y,w,h)(x,y,w,h) ,(x,y)(x,y)(x,y)是边界框的中心坐标,而www和hhh是边界框的宽与高。
要注意,中心坐标(x,y)(x,y)(x,y)的预测值是相对于每个单元格左上角坐标点的偏移值,并且单位是相对于单元格大小的,单元格的坐标定义如下图所示。而边界框的预测值www和hhh是相对于整个图片的宽与高的比例,这样理论上4个元素的大小应该在 [0,1][0,1][0,1] 范围。
这样,每个边界框的预测值实际上包含5个元素:(x,y,w,h,c)(x,y,w,h,c)(x,y,w,h,c),前4个表征边界框的大小与位置,最后一个是置信度。

图8
对于分类问题,每一个单元格还要预测出 CCC 个类别概率值,表征由该单元格负责预测的边界框中的目标属于各个类别的概率。这些概率值其实是在各个边界框置信度下的条件概率,即 Pr(classi∣object)Pr(class_{i}|object)Pr(classi∣object) (首先得包含物体,再谈概率)。不管一个单元格预测多少个边界框,其只预测一组类别概率值,也即是说这一组类别概率值是该cell预测的所有边界框共享的,这是Yolo算法的一个缺点。可以计算出各个边界框类别置信度(class-specific confidence scores):
Pr(classi∣object)∗Pr(object)∗IOUpredtruth=Pr(classi)∗IOUpredtruthPr(class_{i}|object)*Pr(object)*\text{IOU}^{truth}_{pred}=Pr(class_{i})*\text{IOU}^{truth}_{pred}Pr(classi∣object)∗Pr(object)∗IOUpredtruth=Pr(classi)∗IOUpredtruth。
边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏(准不准)。
总结一下,每个单元格需要预测(B∗5+C)(B*5+C)(B∗5+C)个值。如果输入图片划分为S×SS\times SS×S 网格,那么最终预测值为S×S×(B∗5+C)S\times S\times (B*5+C)S×S×(B∗5+C)大小的张量。整个模型的预测值结构如图9所示。对于PASCAL VOC数据,其共有20个类别,如果使用S=7,B=2S=7,B=2S=7,B=2 ,那么最终的预测结果就是7×7×307\times 7\times 307×7×30 大小的张量。下面的网络结构中会详细讲述每个单元格的预测值的分布位置。

图9
网络设计
Yolo采用卷积网络提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层。对于卷积层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数:max(x,0.1x)max(x, 0.1x)max(x,0.1x),但最后一层采用线性激活函数。 如图:

图10
网络最后输出为7×7×307\times 7\times 307×7×30大小的张量。这个张量所代表的具体含义如下图所示。
对于每一个单元格,前20个元素是类别概率值,然后2个元素是边界框置信度(两个边界框),两者相乘可以得到类别置信度(这样相乘是合理的,后面会提到),最后8个元素是边界框的 (x,y,w,h)(x, y,w,h)(x,y,w,h) 。
也就是说,每个cell有两个predictor,每个predictor分别预测一个bounding box的(x,y,w,h)(x, y,w,h)(x,y,w,h)和相应的confidence。但分类部分的预测却是共享的,所以,同一个cell是没法预测多个目标的。
现在考虑两个问题:
1、假设类别预测不是共享的,cell中两个predictor都有各自的类别预测,这样能否在一个cell中预测两个目标?
2、为什么要预测两个bounding box?
对于第一个问题,答案是否定的。如果一个cell要预测两个目标,那么这两个predictor要怎么分工?谁负责谁?不知道,所以没法预测。而像faster rcnn这类算法,可以根据anchor与ground truth的IOU大小来安排anchor负责预测哪个物体,所以后来yolo2也采用了anchor思想,同个cell才能预测多个目标。
对于第二个问题,既然一个cell只能预测一个目标,为什么还要预测两个bounding box(或者更多)?这还要从训练阶段怎么给两个predictor安排训练目标来说,在训练的时候会在线计算每个predictor预测的bounding box和ground truth的IOU,计算出来的IOU大的那个predictor,就会负责预测这个物体,另外一个则不预测。这么做有什么好处?实际上有两个predictor来一起进行预测,然后网络会选择预测得好的那个predictor(也就是IOU大)来进行预测。通俗说,就是我找一堆人来并行地干一件事,然后我选干的最好的那个。
对于边界框把置信度 ccc 和 (x,y,w,h)(x, y,w,h)(x,y,w,h) 都分开排列,而不是(x,y,w,h,c)(x, y,w,h,c)(x,y,w,h,c) 这样排列,是为了方便地提取每一个部分。网络的预测值是一个二维张量PPP ,其shape为[batch,7×7×30][batch, 7\times 7\times 30][batch,7×7×30] 。那么P[:,0:7∗7∗20]P_{[:,0:7*7*20]}P[:,0:7∗7∗20] 就是类别概率部分,而P[:,7∗7∗20:7∗7∗(20+2)]P_{[:,7*7*20:7*7*(20+2)]}P[:,7∗7∗20:7∗7∗(20+2)] 是置信度部分,最后剩余部分P[:,7∗7∗(20+2):]P_{[:,7*7*(20+2):]}P[:,7∗7∗(20+2):] 是边界框的预测结果。
网络训练
在训练之前,先在ImageNet上进行了预训练,其预训练的分类模型采用图8中前20个卷积层,然后添加一个average-pool层和全连接层。预训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。整个网络的流程如图11所示:

图11
训练损失函数的分析:
Yolo算法将目标检测看成回归问题,采用的是均方差损失函数(仔细想想也是合理的,由预测框到真实框变换,可以由一个缩放因子和一个平移因子近似),但是对不同的部分采用了不同的权重值。 首先区分定位误差和分类误差。
对于定位误差,即边界框坐标预测误差(中心坐标与高宽,以及边界框置信度)。
对于中心坐标与高宽,采用较大权重λcoord=5\lambda _{coord}=5λcoord=5 。考虑到较小边界框的坐标误差应该要比较大边界框坐标误差要更敏感,所以将边界框的宽高预测改为对其平方根的预测,即预测值变为(x,y,w,h)(x,y,\sqrt{w}, \sqrt{h})(x,y,w,h)。比如:大小为10和100的目标,预测大小分别为20和110,损失一样但显然小目标检测的更差一点,通过开根号,相当于强化了小目标的w和h损失。
对于边界框置信度,区分不含目标的边界框与含目标的边界框的置信度。前者采用较小的权重值λnoobj=0.5\lambda _{noobj}=0.5λnoobj=0.5 ,后者权重为1。
然后采用均方误差,同等对待大小不同的边界框。
前面提到,每个单元格预测多个边界框(比如此处的2个),但是预测类别只有一组,这一组类别概率值是该cell预测的所有边界框共享的。那么怎么知道选择哪个边界框来进行预测呢?在训练时,如果该单元格内确实存在目标,那么只选择与ground truth的IOU最大的那个边界框来负责预测该目标,而剩下的边界框认为不存在目标(lijobjl^{obj}_{ij}lijobj=0)。大家可能会想如果一个单元格内存在多个目标怎么办,其实这时候Yolo算法就只能选择其中一个来训练,这也是Yolo算法的缺点之一。要注意的一点时,对于不存在目标的边界框,其误差项就是只有置信度,坐标项误差是没法计算的。而只有当一个单元格内确实存在目标时,才计算分类误差项,否则该项也是无法计算的。
综上讨论,最终的损失函数计算如下:

1. 对预测的中心坐标做损失
该等式计算相对于预测的边界框位置(x,y)的loss,计算了每一个网格单元(i=0,...,S2)(i=0,...,S^2 )(i=0,...,S2)的每⼀个边界框预测值(j=0,...,B)(j=0,...,B)(j=0,...,B)的总和。lijobjl^{obj}_{ij}lijobj定义如下:
- 1,如果⽹网格单元i中存在⽬标,则第j个边界框预测值对该预测有效。
- 0,如果⽹网格单元i中不不存在目标
总的来说,预测的bounding box与ground truth IOU比较大的那个predictor,需要计算xywhxywhxywh loss。
2. 对预测边界框的宽高做损失
采用根号项的原因前面提到了。同样,预测的bounding box与ground truth IOU比较大的那个predictor,需要计算xywhxywhxywh loss。
3. 对预测的置信度做损失
包含目标的边界框的置信度误差项,加上不包含目标的边界框的置信度误差项。值CiC_iCi,如果cell内不存在目标,此时由于Pr(object)=0Pr(object)=0Pr(object)=0,那么Ci=0C_i=0Ci=0。如果存在目标,Pr(object)=1Pr(object)=1Pr(object)=1 ,此时需要确定 IOUpredtruth{IOU}^{truth}_{pred}IOUpredtruth ,可以将IOU取1,这样Ci=1C_i=1Ci=1 。但是在YOLO实现中,使用了一个控制参数rescore(默认为1),当其为1时,IOU不是设置为1,而是计算truth和pred之间的真实IOU。不过很多复现YOLO的项目还是取Ci=1C_i=1Ci=1 ,这个差异应该不会太影响结果。
各个λ参数⽤于损失函数的不同加权部分,相当于进行惩罚。最高惩罚是对于坐标预测(λcoord=5)(λ_{coord} = 5)(λcoord=5),当没有探测到目标时,有最低的置信度预测惩罚(λnoobj=0.5)(λ_{noobj} = 0.5)(λnoobj=0.5)。
- 有物体中心落入的cell(确实存在目标,才会分类),需要计算分类loss,两个predictor都要计算confidence loss
- 没有物体中心落入的cell(坐标误差、分类误差都是没法计算的),只需要计算置信度confidence loss
4. 对预测的类别做损失
liobjl^{obj}_{i}liobj的意思是,有物体中心落入的cell,才需要计算分类loss,即惩罚分类误差。
模型输出
非极大值抑制算法(non maximum suppression, NMS),主要解决的是一个目标被多次检测的问题。如图12中人脸检测,人脸被多次检测,但是希望最后仅仅输出其中一个最好的预测框,比如对于女性,只想要红色那个检测结果。可以采用NMS算法来实现:首先从所有的检测框中找到置信度最大的那个框,然后计算该框与剩余框的IOU,如果IOU大于一定阈值(重合度过高),那么就将该框剔除;然后对剩余的检测框重复上述过程,直到处理完所有的检测框。

图12
置信度预测:
首先看cell预测的bounding box中condifence这个维度。confidence表示:cell预测的bounding box包含一个物体的置信度有多高并且该bounding box预测准确度有多大,用公式表示为: Pr(Object)∗IOUpredtruthPr(Object) * IOU^{truth}_{pred}Pr(Object)∗IOUpredtruth 。分两个阶段来考虑:
1、对于训练阶段来说,要给每个bounding box的confidence打label,那这个label怎么算?
- 如果一个物体中心没有落在cell之内,那么每个bounding box的Pr(Object)=0Pr(Object)=0Pr(Object)=0 ,IOU就没有算的必要了,因为Pr(Object)∗IOUpredtruthPr(Object) * IOU^{truth}_{pred}Pr(Object)∗IOUpredtruth 肯定为于0,因此confidence的label就设置为0。
- 如果物体的中心落在了这个cell之内,这个时候Pr(Object)=1Pr(Object)=1Pr(Object)=1 ,因此confidence变成了1∗IOUpredtruth1*IOU^{truth}_{pred}1∗IOUpredtruth 。注意这个IOU是在训练过程中不断计算出来的,网络在训练过程中预测的bounding box每次都不一样,所以和ground truth计算出来的IOU每次也会不一样。
2、对于预测阶段,网络只输出一个confidence值,它实际上隐含地包含了¥IOU^{truth}_{pred}$ 。
- 疑问:在测试阶段,输出的confidece怎么算?还是通过Pr(Object)∗IOUpredtruthPr(Object) * IOU^{truth}_{pred}Pr(Object)∗IOUpredtruth 计算吗?如果这样的话,测试阶段根本没有ground truth,怎么计算IOU?实际上,在测试阶段,网络只是输出了confidece这个值,但它已经包含了Pr(Object)∗IOUpredtruthPr(Object) * IOU^{truth}_{pred}Pr(Object)∗IOUpredtruth ,并不需要分别计算Pr(object)和IOU(也没办法算)。为什么?因为你在训练阶段你给confidence打label的时候,给的是Pr(Object)∗IOUpredtruthPr(Object) * IOU^{truth}_{pred}Pr(Object)∗IOUpredtruth 这个值,你在测试的时候,网络吐出来的也就是这个值。
Bounding box预测
bounding box的预测包括xywhxywhxywh四个值。xy表示bounding box的中心相对于cell左上角坐标偏移,宽高则是相对于整张图片的宽高进行归一化的。偏移的计算方法如下图所示:
实际上经过这么表示之后,xywhxywhxywh都归一化了,值都是在0-1之间。做回归问题时都会将输出进行归一化,否则可能导致各个输出维度的取值范围差别很大,进而导致训练的时候,网络更关注数值大的维度。因为数值大的维度,loss相应会比较大,为了让这个loss减小,那么网络就会尽量学习让这个维度loss变小,调整权重就会偏向这边,最终导致区别对待。
类别预测
物体类别是一个条件概率Pr(Classi/Object)Pr(Class_i/Object)Pr(Classi/Object)。这个怎么理解?也分两个阶段:
1、对于训练阶段,也就是打label阶段,怎么打label?对于一个cell,如果物体的中心落在了这个cell,那么我们给它打上这个物体的类别label,并设置概率为1。换句话说,这个概率是存在条件的,条件就是cell存在物体。
2、对于测试阶段来说,网络直接输出Pr(Classi/Object)Pr(Class_i/Object)Pr(Classi/Object),就已经可以代表有物体存在的条件下类别概率。但是在测试阶段,作者还把这个概率乘上了confidence。
论文中的公式是这样的:

也就是说我们预测的条件概率还要乘以confidence。为什么这么做呢?举个例子,对于某个cell来说,在预测阶段,即使这个cell不存在物体(即confidence的值为0),也存在一种可能:输出的条件概率p(class/object)=0.9p(class/object)=0.9p(class/object)=0.9,但将confidence和p(class/object)p(class/object)p(class/object) 乘起来就变成0了,这个是很合理的,因为你得确保cell中有物体(即confidence大),你算类别概率才有意义。
网络预测
分析yolo的预测过程,不考虑batch,认为只预测一张输入图片。根网络输出是 7×7×307\times 7 \times 307×7×30 ,将其分割成三个部分:类别概率部分为[7,7,20][7, 7, 20][7,7,20] ,置信度部分为[7,7,2][7,7,2][7,7,2] ,而边界框部分为[7,7,2,4][7,7,2,4][7,7,2,4] (对于这部分不要忘记根据原始图片计算其真实值)。然后将前两项相乘(矩阵[7,7,20][7, 7, 20][7,7,20] 乘以[7,7,2][7,7,2][7,7,2] 可以各补一个维度来完成[7,7,1,20]×[7,7,2,1][7,7,1,20]\times [7,7,2,1][7,7,1,20]×[7,7,2,1] )可以得到==类别置信度(前面提到了,类别置信度是两项相乘的)==值为[7,7,2,20][7, 7,2,20][7,7,2,20] ,总共预测了7∗7∗2=987*7*2=987∗7∗2=98 个边界框。
准备数据已经得到,先说第一种策略来得到检测框的结果。首先,对于每个预测框根据上面计算的类别置信度选取置信度最大的那个类别作为其预测标签,经过这层处理得到各个预测框的预测类别及对应的置信度值,其大小都是[7,7,2][7,7,2][7,7,2] 。一般情况会设置置信度阈值,将置信度小于该阈值的box过滤掉,经过这层处理,剩余置信度比较高的预测框。最后再对这些预测框使用NMS算法,最后留下来的就是检测结果。一个值得注意的点是NMS是对所有预测框一视同仁,还是区分每个类别,分别使用NMS。Ng在deeplearning.ai中讲应该区分每个类别分别使用NMS,但是看了很多实现,其实还是同等对待所有的框,我觉得可能是不同类别的目标出现在相同位置这种概率很低吧。
上面的预测方法应该非常简单明了,但Yolo算法,却采用了另外一个不同的处理思路(至少从C源码看是这样的),区别就是先使用NMS,然后再确定各个box的类别。其基本过程如图13所示。对于98个boxes,先将小于置信度阈值的值归0,然后分类别地对置信度值采用NMS,NMS处理结果不是剔除,而是将其置信度值归为0。最后才是确定各个box的类别,当其置信度值不为0时才做出检测结果输出。Yolo论文里面说NMS算法对Yolo的性能是影响很大的,所以可能这种策略对Yolo更好。但是我测试了普通的图片检测,两种策略结果是一样的。

图13
算法性能分析
看一下Yolo算法在PASCAL VOC 2007数据集上的性能,Yolo与其它检测算法做了对比,包括DPM,R-CNN,Fast R-CNN以及Faster R-CNN。其对比结果如表1所示。与实时性检测方法DPM对比,可以看到Yolo算法可以在较高的mAP上达到较快的检测速度,其中Fast Yolo算法比快速DPM还快,而且mAP是远高于DPM。但是相比Faster R-CNN,Yolo的mAP稍低,但是速度更快。所以。Yolo算法算是在速度与准确度上做了折中。

表1
为了进一步分析Yolo算法,文章还做了误差分析,将预测结果按照分类与定位准确性分成以下5类:
- Correct:类别正确,IOU>0.5;(准确度)
- Localization:类别正确,0.1 < IOU<0.5(定位不准);
- Similar:类别相似,IOU>0.1;
- Other:类别错误,IOU>0.1;
- Background:对任何目标其IOU<0.1。(误把背景当物体)
- Yolo与Fast R-CNN的误差对比分析如下图所示:

表1
可以看到,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的定位不准确也是很大的问题。