YOLO入门教程(番外):目标检测的一阶段学习方法
- 学习资料:《基于深度学习的目标检测原理与应用》
- 作者:翟中华 孙云龙 陆澍旸 编著
看的我云里雾里!!!
前面章节深入细致地讲解了R-CNN系列的目标检测方法。
在R-CNN系列中,目标检测通过两个阶段完成:
- 第一阶段是候选框产生阶段,产生可能有目标的边界框;
- 第二阶段是分类与回归阶段,用于从第一阶段粗略的候选框到真正框住物体的边界框。
本章将讲解一阶段目标检测方法的代表——YOLO系列的目标检测方法。
YOLO统一了目标检测的所有阶段,是一种更简单的算法,训练速度也更快,使用单个深度卷积网络直接预测类别概率和边界框。
使用一幅简单的图像作为讲解YOLO的例子,如图6-1-1所示。
YOLO系列最初为v1版本,之后逐渐进化,形成v2版本、v3版本、v4版本,现已出至v5版。
如图6-1-2所示,该结果显示YOLOv1检验出了人(person)、货车(truck)、交通信号灯(traffic light)、汽车(car)、自行车(bicycle)。
1 YOLO目标检测思想
YOLO源自论文You Only Look Once:Unified,Real-Time ObjectDetection,是一阶段目标检测方法,与两阶段检测方法不同。
如图6-1-3所示,在R-CNN系列中,目标检测需要两个阶段完成:第一,输入图像经过候选框生成阶段,例如,利用选择搜索或者RPN产生候选框;第二,将候选框对应的图像输入卷积网络,提取特征,再进行分类。
两阶段深度学习方法有如下两个缺点。
- (1)速度慢,实时检测效果差。因为需要大量候选框选择定位可能的目标物体,然后才进行分类识别,所以,不能一步到位。
- (2)训练慢。RPN和分类网络被隔离开来,导致训练过程烦琐:在训练RPN的时候不能训练分类网络,在训练分类网络的时候不能训练候选框选择网络。
YOLO目标检测方法统一两阶段网络来进行目标检测,是对两阶段方法的极大创新改进,实现端到端的训练网络。
如图6-1-3所示,YOLO算法直接将原始图像分割成互不重合的小方块,然后通过卷积;最后产生特征图。
特征图的每个单元格对应原始图像的一个小方块,用每个单元格可以预测那些中心点在该小方格内的目标,这就是YOLO算法的朴素思想。
1.1 改进思想
YOLO将输入图像划分为S×S个网格,每个网格单元仅预测一个对象。
如图6-1-4所示,白色网格单元试图预测中心点落在其内部的“人”(对象)。
这是YOLO算法实现一阶段端到端检测的最关键的原理。
YOLO在进行预测时会对图像进行全局推理。
与基于滑动窗口和区域提议的技术不同,YOLO在训练和测试期间看到整个图像,因此,它隐式编码了关于类及其外观的上下文信息。Fast R-CNN是一种顶级检测方法,由于无法看到更多的上下文,所以,会出现将图像中的背景误认为是对象的错误。
与Fast R-CNN相比,YOLO的背景错误数量不到Fast R-CNN的一半。YOLO是在2016年5月被提出的,而Fast R-CNN是在2015年9月被提出的,因此,YOLO的改进,经常被拿来与Fast R-CNN比较。
YOLO像人一样一眼看全整张图再做判断,而Fast R-CNN像先盯着一个个局部猜再看全图,所以YOLO更不容易把背景里的东西误认成物体。
通俗解释背后的原理:
-
YOLO的“一眼看全”:它将整张图像一次性输入神经网络,直接在多个位置同时预测物体的边界框和类别。这个过程是全局(Global) 的,模型能利用图像中所有区域的信息(上下文)来做决策。例如,它看到“天空”区域的某个东西,结合上下文就知道它更可能是“鸟”或“飞机”,而不是“鱼”。
-
Fast R-CNN的“先盯局部”:它依赖于区域提议(Region Proposal),先找出可能包含物体的一个个局部区域(候选框),再对这些区域进行分类。这个过程是局部(Local) 的,模型在判断单个候选框时,无法充分利用图像其他部分的上下文信息。因此,一个看起来像物体的背景(比如一朵奇形怪状的云),就很容易被错误地检测成物体(如“汽车”)。
1.2 网格单元
YOLO统一两阶段的关键就是YOLO的网格化思想。
这个思想也是解决候选框产生问题的关键,思路更加规整、简洁,相当于从单元格视角看图像的“细胞”。
每个网格单元都预测固定数量的边界框,注意这里边界框与上述“对象”的区别。
在此示例中,黄色单元格进行两个边界框的预测(蓝色框)以定位人的位置,如图6-1-5所示。
这样,以单元格作为图像“细胞”,相当于对图像进行一次遍历,然后在每个遍历位置(单元格)检测可能的对象,为了确定对象大小,又设置不同的边界框,考虑可能的不同形状,这样,以非常利索的方式解决R-CNN中的选择搜索或RPN问题。
想象一下,你要在一张图上找东西:
选择搜索/RPN:就像先派一个助手在整张图上粗略地扫描一遍,找出所有“可能藏了东西”的角落(候选框),然后你再对这些角落进行仔细鉴别。这是两个独立的步骤。
YOLO的网格:没有这个助手。你自己把图划分成一个个小格子,然后直接对每个格子判断“这里有什么东西以及它的准确位置”。这是一个统一的步骤。
但是,单元格的单对象规则限制了所检测对象的接近程度。为此,YOLO在对象距离很接近时,确实会有部分对象检测不到的情况。对于图6-1-6,左下角有9个圣诞老人,但YOLO只能检测到5个,这是需要改进的。
1.3 YOLO创新细节
YOLO使用B个边界框,共进行S×S个对象预测,如图6-1-7所示。
对于每个网格单元:
- 预测B个边界框,每个框都有一个置信度分数。
- 预测C个类的概率,对应检测目标的C个类别的概率。YOLO使用7×7(S×S)个网格,每个网格只负责检测一个目标。同时每个网格输出2(B)个边界框。
每个边界框包含5个元素:x、y、w、h和一个框的置信度分数。
- (x,y)坐标表示相对于网格单元边界的框中心;
- 宽度w和高度h是相对于整个图像预测的;
- 置信度得分反映了框包含对象的可能性及边界框的准确性,如果手动计算,则用P(Object)×IoU表示,这里的IoU是预测框与真值框的IoU。
注意,由于YOLO没有锚框,每个单元格的两个框都是直接预测的,所以,上述IoU是预测框与真值框的IoU。
- 每个网格输出两个边界框,相当于让模型对同一位置进行两次猜测,最终只采纳更准确的那个结果,以此提升定位目标的成功率。
- 宽高相对于整个图像预测,是指模型预测的框的大小是相对于图片尺寸的比例值,而非绝对像素,这保证了无论图像如何缩放,预测的框都能自动适应其大小。
通过图像的宽度和高度对边界框的宽度w和高度h进行归一化,因此,x、y、w和h都在0和1之间。
每个框都有20个类的概率。该概率是检测到的对象属于特定类别的概率,每个类别都有一个概率。所以,一个单元格预测两个框共10个数值,再加20个类别,共30个,因此,YOLO的预测形状为(S,S,B×5+C)=(7,7,2×5+20)=(7,7,30)。
每个类别概率表示为:
框内某个类别对象的置信分数为联合概率乘以IoU,即:
P(Classi,Object)×IoU=
不着急,咱们把这两个公式搞懂
第一个公式:P(Classᵢ | Object)
- 这是什么? 这是一个条件概率。
- 通俗解释: “在肯定这个网格里包含一个物体的前提下(Object),这个物体具体是第 i 类(例如‘猫’或‘狗’)的概率有多大?”
- 关键点: 这个概率是针对整个网格的。无论一个网格预测多少个边界框(B=2),这个网格只输出一组类别概率,即共C个概率值(例如20类),每个值代表该网格内的物体属于某一类的可能性。
第二个公式:P(Classᵢ, Object) × IoU = P(Object) × P(Classᵢ | Object) × IoU
这个公式是YOLO置信度计算的精髓,它将三个信息融合成一个最终分数。
-
P(Object):
- 是什么? 每个边界框的对象置信度。可以理解为“这个框里含有任何物体的可能性有多大?”。
- 值范围: 0到1。越接近1,说明这个框越可能框住了某个东西。
-
P(Classᵢ | Object):
- 就是第一个公式,代表“如果框里有东西,那这个东西是特定类别 i 的概率”。
-
IoU(Intersection over Union,交并比):
- 预测的边界框与真实的标注框之间的重叠程度。衡量的是“框得准不准”。
- 值范围: 0到1。IoU=1表示预测框和真实框完全重合,非常完美;IoU=0表示完全没有重叠。
-
公式整合(为何要乘在一起?)
这个公式计算的是“类别 i” 的最终置信度分数。它综合了三大信息:- 有无物体: P(Object)(这个框里有东西吗?)
- 是什么物体: P(Classᵢ | Object)(如果真有,它是啥?)
- 定位精度: IoU(框的位置准不准?)
最终的这个分数越高,就意味着: “我(模型)非常自信地认为,这个框里确实有一个物体,它极大概率是类别 i,而且我框得非常准”。
结合输出张量理解 (7, 7, 30)
下面计算文字解释了YOLOv1的实际输出结构,这是对上述理论的实现。
-
S = 7: 图像被划分为 7×7 个网格。
-
B = 2: 每个网格预测 2 个边界框(Bounding Box)。
-
每个边界框预测 5 个值:
- 4 个定位值:(x, y, w, h) (框的中心点坐标和宽高)
- 1 个置信度:P(Object) × IoU (即公式中 P(Object) 和 IoU 的乘积,注意这里还没有乘以类别概率)
-
每个网格预测 C = 20 个值:
- 一组条件类别概率:[P(Class₁|Object), P(Class₂|Object), …, P(Class₂₀|Object)]
-
所以,每个网格的总输出长度是:B × 5 + C = 2×5 + 20 = 30
-
整个模型的输出就是一个 7×7×30 的张量(Tensor)。
举例
假设有一个网格在预测一只猫:
- 它的第一个边界框计算得到 P(Object) × IoU = 0.9 (很有信心框里有个东西且框得准)。
- 该网格的类别概率中,P(Classᵢ=“猫” | Object) = 0.8。
- 那么,这个框对于“猫”这个类别的最终置信度分数就是:
0.9 × 0.8 = 0.72
(模型72%的信心认为这里有一只被准确定位的猫)。
而另一个可能框偏了的边界框,它的 IoU 很低,导致 P(Object) × IoU 也很低(比如0.1),那么即使它处在同一个网格(共享同样的类别概率0.8),其最终分数 0.1 × 0.8 = 0.08 也会很低,在后续处理中会被过滤掉。
这就是YOLO高效且巧妙的设计:它将目标检测的分类和定位问题统一到了一个单一的回归问题中,通过一个网络直接预测出所有需要的值。
刚刚开始我理解不了这个7×7×30
想象一张 7×7 的网格纸,盖在输入图像上。这张网格纸的每一个小格子里,都塞进了一张小小的、包含了30个信息的“体检报告”。而这整张纸,就是模型对整个图像的完整预测。
- 2个边界框的定位信息 (占10个数)
- 1组类别信息 (占20个数)
因此,“总输出长度30”的本质是:YOLO为图像上的每一个预设区域(网格),都配备了足够的信息量,使其能够独立完成“预测边框”和“猜测类别”这两大核心任务。 整个张量就是所有这些区域预测结果的集合。
不好意思,罗嗦了!
现在总结一下YOLO的具体步骤,如图6-1-8所示。
- (1)将图像分成S×S个网格(此处S=7),这个不用实际操作,在最后的特征图上划分即可。如果有对象中心落入网格中,则该网格就负责该对象的检测。
- (2)每个网格预测B个框(框1、框2)和该框的置信度。每个边界框由5个元素组成:x、y、宽度w、高度h和置信度。置信度表示预测框与任何真值框之间的IoU;每个网格单元还预测条件类概率P(Classi Object)。
- (3)因为多个框可能预测同一个物体,所以,还需要通过阈值去除可能性较低的框,最后通过非极大值抑制(NMS)去除冗余窗口即可。整个过程很简单,不再需要中间的候选区域,直接回归、分类合二为一,实现端到端、一步到位的目标检测。
另外,在YOLO中,S=7;B=2。总框的数量为7×7×(2×5+20)=1470。相对于S×S网格中1470个框,与Faster R-CNN的17000多个框比起来,真是“小巫见大巫”。因此,YOLO有3个优秀特征:
- ①极快(每秒45帧);
- ②在整幅图像上进行全局推导,不是滑动窗口在图像上滑动以获得局部特征;
- ③YOLO学到的图像特征更为通用。
2 YOLO的网络结构、网络与损失函数
上一节介绍了YOLO目标检测思想,即通过将输入图像分成S×S个网格,每个单元格预测B个框,每个框有x、y、w、h和置信度5个元素,同时,每个单元格预测C个类别,最终输出S×S×(B×5+C)的张量。
2.1 YOLO的网络结构
YOLO具有24个卷积层,其后是两个全连接层。
一些卷积层交替使用1×1卷积来减少特征图的深度。
对于最后一个卷积层,它输出形状为(7,7,1024)的张量,然后将张量展平。
使用两个完全连接的层作为线性回归的形式,它输出7×7×30个参数,然后重塑为(7,7,30),即每个位置两个边界框预测,如图6-2-1所示。
YOLO每层组成如表6-2-1所示。
该表展示了YOLO整个网络详细尺寸的计算过程,“大小”是卷积池化及尺寸,“/2”表示步长为2;“输入”是输入张量的尺寸。
“输出”是输出张量的尺寸。注意,YOLOv1仍然保留全连接层,这一状况在后续版本有优化。
2.2 YOLO的网络训练与损失函数
首先看看训练目标是什么。
显而易见,真值框(Ground Truth)是训练目标。
但在通常情况下,一幅图像中真值框是极少的,大多数仅为背景。
如图6-2-2所示,真值框只有3个,分别为狗、自行车及小轿车。
然而,每幅图像有7×7个网格,每个网格有两个框,共有7×7×2=98个框需要预测。
对于一个对象,希望有一个预测框恰到好处地框住它,因此,我们用与真值框拥有最大IoU的锚框来预测它,同时计算位置损失和置信度损失。
对于其他的锚框,只计算其置信度损失;对于分类损失,不用框来计算,而是针对单元格,计算所有单元格的分类损失。
原始YOLOv1没有锚框。图片中的“锚框”可能是术语上的泛用。而“损失”指的是YOLO模型训练时,用于衡量预测结果(框的位置、置信度、类别)与真实值之间差异的函数,它由位置损失、置信度损失和分类损失三部分组成,是驱动模型学习如何准确检测目标的核心机制。
YOLO的损失函数为:
损失函数中有5项,重点介绍3个指示函数:
-
表示框(i,j)负责中心落在单元格i的对象,即与真值框IoU最大的
-
=1表示框(i,j)不负责预测任何对象,否则为0。
-
表示有对象出现在单元格i中,否则为0。
其中框(i,j)表示单元格i的第j个预测框。
- (1)在式(6-1)中,第一项和第二项是定位损失。定位损失测量了预测的边界框位置和大小中的误差。我们只计算负责检测物体的框的平方误差和(SSE)。在式(6-1)中,第一项(x,y):边界框x和y坐标被参数化为特定网格单元位置的偏移量,因此在0和1之间。在式(6-1)中,第二项(w,h):边界框的宽度和高度,是以整个图像为参照的,由图像宽度和高度归一化,使其介于0和1。由于小偏差对大框比小框的影响小,所以,通过取平方根可以在一定程度上降低这种差异。例如,大边框边长为10单位,小边框边长为1单位,如果两者梯度都变化1单位,则对大边框而言是10%的变化,但对小边框而言就是100%的变化,如图6-2-3所示。
- (2)第3项和第4项是置信度损失:如果在框中检测到物体,则计算置信度损失。由于大多数单元格不包含任何对象的中心点,即不预测任何对象,这会导致类不平衡问题,即训练模型会比检测对象时更频繁地检测到背景。为了解决这个问题,将对应的损失乘以一个小于1的因子予以降低,减少不包含对象的框的置信度预测的损失,因子默认值为λnoobj=0.5。同理,对于第1项中的λcoord,设置为5,增加边界框坐标预测的损失。
- (3)第5项是分类损失,如果该单元格有对象,每个单元格的分类损失是每个类别的概率的SSE。
Faster R-CNN物体分类损失函数用的是交叉熵损失,边框回归用的是平滑L1损失,而YOLO与Faster R-CNN不同,YOLO使用的全是平方损失。
总结如下:
- (1)更重视坐标预测,给这些损失前面赋予更大的权重,乘以λcoord。
- (2)对于不负责预测对象的框的置信度损失,赋予小的λnoobj。
- (3)对于负责预测对象的框的置信度损失和分类损失,正常取1
来吧
来深入浅出地解析一下YOLOv1的这个核心损失函数。这个函数是YOLO训练过程中的“指挥棒”,它告诉模型应该如何调整参数,以做出更准确的预测。
整个损失函数由五个部分相加而成,我们可以把它们分为三大任务:定位任务(框得准不准)、置信度任务(框里有没有东西)、分类任务(框里是什么东西)。
为了让解释更直观,我们用一个比喻:
想象你是一名教练,在训练一个由
S×S
(如7×7=49
)名学员组成的团队进行目标检测。每个学员(网格)有B
(如2
)次投篮机会(预测框)。你的任务是制定评分标准(损失函数),让他们投得又准又自信。
损失函数详解
第一部分:定位损失(Localization Loss) - 【让框更准】
这部分对应公式的前两项,目的是让边界框的中心点和宽高尽可能接近真实值。
1. 中心坐标损失:
λ_coord * ΣΣ 1_ij^obj [(x_i - x̂_i)² + (y_i - ŷ_i)²]
1_ij^obj
:这是一个指示函数,是理解整个损失函数的关键。它像是一个“责任人”开关:- = 1:当第
i
个网格的第j
个预测框被指定负责预测一个真实物体时。 - = 0:对于其他所有不负责预测的框。
- 这就解决了你上一个问题中的疑惑:只让与真实物体最匹配的那个框来计算定位损失。
- = 1:当第
(x_i - x̂_i)²
:计算预测的中心点横坐标x_i
与真实值x̂_i
的平方误差。(y_i - ŷ_i)²
同理。λ_coord
(通常设为5):一个权重系数。为什么需要它? 因为在一张图片中,包含物体的网格(正样本)远少于不包含的网格(负样本)。这个权重用来放大定位误差的重要性,防止模型只专注于优化数量庞大的负样本的置信度,而忽略了更重要的框的位置。
2. 宽高损失:
λ_coord * ΣΣ 1_ij^obj [(√w_i - √ŵ_i)² + (√h_i - √ĥ_i)²]
- 与中心坐标损失类似,只对“责任人”框计算。
- 关键点:为什么对宽高取平方根?
- 直接计算
(w_i - ŵ_i)²
会带来一个问题:对大尺寸框的误差惩罚远大于对小尺寸框的同样误差。 - 取平方根后,削弱了大框的绝对尺寸优势,让小框的偏差也能得到足够的重视,使得模型对不同大小的物体都能进行稳定的学习。
- 直接计算
第二部分:置信度损失(Confidence Loss) - 【判断有无】
这部分对应公式的第三和第四项,目的是让模型对“有物体”的框给出高置信度,对“没有物体”的框给出低置信度。
3. 正样本置信度损失:
ΣΣ 1_ij^obj (C_i - Ĉ_i)²
C_i
:模型预测的置信度。Ĉ_i
:真实置信度。对于“责任人”框,它的真实值就是这个预测框与真实框的IoU值( Intersection over Union,交并比)。理想情况是1。- 这项损失鼓励那些框住了物体的预测框,提高它们的置信度,直到接近1。
4. 负样本置信度损失:
λ_noobj * ΣΣ 1_ij^noobj (C_i - Ĉ_i)²
1_ij^noobj
:另一个“责任人”开关,= 1 当第i
个网格的第j
个预测框不包含任何物体时。Ĉ_i
:对于这些框,它们的真实置信度应该是 0。λ_noobj
(通常设为0.5):一个权重系数。为什么需要它? 因为不包含物体的框(负样本)数量远多于包含物体的框(正样本)。这个权重(<1)用来降低负样本置信度损失的重要性,防止模型被大量的“简单负样本”主导训练过程,变成只会说“这里没东西”的模型。
第三部分:分类损失(Classification Loss) - 【识别类别】
ΣΣ 1_i^obj * Σ (p_i(c) - p̂_i(c))²
1_i^obj
:注意这里的下标没有j
。这个指示函数 = 1 当第i
个网格(而不是某个框)包含物体时。p_i(c)
:模型预测的该网格物体属于类别c
的概率。p̂_i(c)
:真实的类别概率(是一个one-hot向量,真实类别为1,其他为0)。- 关键点:如你之前所问,分类损失是按网格计算的,而不是按框。一个网格里的所有预测框共享同一组类别概率。这项损失只关心“这个网格里有没有物体?有的话它应该是哪个类别?”,而不关心是哪个框框住的。
总结与设计哲学
YOLO的损失函数设计得非常精巧,它同时解决了目标检测中的多个核心挑战:
- 多任务学习:将定位、置信度判断、分类三个子任务统一到一个损失函数中,进行端到端训练。
- 正负样本不平衡:通过
λ_coord
和λ_noobj
两个权重,巧妙地平衡了稀少但重要的正样本和大量但简单的负样本对训练过程的影响。 - 多尺度目标:通过对宽高取平方根,平衡了大物体和小物体的定位误差权重。
最终,这个损失函数引导模型:
- 对于每个物体,只有一个“责任人”预测框会去精细地调整它的位置和大小(定位损失)。
- 所有预测框都要学会判断自己框里有没有东西(置信度损失)。
- 每个包含物体的网格都要学会识别里面是什么(分类损失)。
这就是YOLO能够快速且准确地完成目标检测任务的核心秘诀所在。
3 YOLO模型评估、优劣势分析
本节介绍YOLO的优点、缺点,以及如何进一步改进,以方便理解以后的YOLO各版本改进过程和思路,以及为自己设计目标检测网络提供借鉴。
3.1 YOLO数据集
YOLO使用Pascal VOC 2007和VOC 2012数据集。
- (1)VOC 2007共有20个分类。人物分类是各类人像;动物分类是鸟类、猫、狗、马、羊;交通工具分类是飞机、自行车、船、巴士、小轿车、摩托车、火车;室内物品是瓶子、椅子、餐桌、盆栽植物、沙发、电视/显示器;训练集/验证集/测试集共有9963幅图像,包含24640个标注目标。
- (2)VOC 2012同样有20个分类。训练集/验证集数据有11530幅图像,包含27450个RoI标注目标和6929个分割样本。Pascal VOC 2007/2012数据集的20个类别如图6-3-1所示。这20个类别都是比较常见的。介绍完数据集,下面对比YOLO与其他目标检测网络的优劣,以方便评估YOLO。
3.2 YOLO模型评估
下面通过比较“准确率”“检测速度”“泛化能力”来看从传统DPM(Deformable Part Model,可变形的组件模型)到YOLO各目标检测网络改进和效果,以便对YOLO进行整体评估。
首先看一下R-CNN与DPMv5在数据集Pascal 2007上的mAP和检测速度,如表6-3-1所示。之后的比较都是在该数据集上进行的。
很明显,R-CNN检测的mAP增加了32.3个百分点,但是检测速度却明显降低了,按在高速公路上的速度100km/h算,自动驾驶汽车在20s内将行驶556m左右,如图6-3-2所示,路况变化非常大。
表6-3-2所示为R-CNN系列目标检测算法检测速度对比。虽然Fast R-CNN的mAP比R-CNN仅增加4个百分点,但速度是R-CNN的10倍,达到2秒/帧。不过用在自动驾驶上还是不太现实。在高速公路上,检测一帧图像的时间,自动驾驶汽车已经行驶了56m。
Faster R-CNN相比于DPMv5,速度变为100倍,mAP提高近40%;相比于Fast R-CNN,mAP增加了3.2个百分点,速度提高为Fast R-CNN的14倍。同样拿汽车速度做比较,检测一帧图像的时间,汽车行驶约3.88m的距离,效果非常明显。
表6-3-3所示为YOLO检测速度。
可以看出YOLO的准确率虽然没有Faster R-CNN和R-CNN好,但是速度是极快的,为22毫秒/帧,是Fast R-CNN的6倍还多,这意味着车辆行驶0.6m即可检测一帧图像。
3.3 YOLO模型优缺点
由图6-3-3所示的Fast R-CNN与YOLO的对比可看出,Fast R-CNN的正确率为71.6%,而YOLO的正确率为65.5%。YOLO的误差有两个特点:
- 一是位置错误率相对较高;
- 二是背景错误率相对其他较低。
YOLO位置错误大的原因是B个框尺度取值只有2,对于小物体检测不明显。
背景检测效果好是因为在损失函数中,背景错误前添加一个参数λnoobj(6.2.2节);因为在目标检测中,背景通常数量是很多的,而目标是很少的,所以,这个参数可用来处理样本不平衡问题。
YOLO最大的优点,就是泛化性能很好,可以推广到新领域(如艺术领域),如图6-3-4所示。另外,YOLO比DPM和R-CNN等方法在推广到人的检测时有更好的性能,如图6-3-5及表6-3-4所示。在图6-3-5中可以看出YOLO的性能明显优于其他模型,但相比于人类水平,仍差一些。
在目标检测任务中,大多数是人的检测,然而,由于人物站立位置较远或不清晰,所以,后排人物无法检测到。除人物检测不全外,YOLO还会出现无法检测其他目标的问题,这是由于YOLO训练数据集分类数量少等原因,所以,与改进版本YOLOv2和YOLOv3相比,就逊色得多。
综合而言,YOLO的优势有如下4点:速度快、端到端训练、背景错误率低、泛化能力强。YOLO的不足之处有如下3点:准确率不高、位置错误率高、对小目标不敏感。YOLO还有如下局限性:
- (1)YOLO对相互靠得很近的物体(如挨在一起且中心点都落在同一个格子上的情况),以及很小的群体聚集的情况检测效果不好,这是因为一个网络(也称单元格)只负责预测一个目标。
- (2)在测试图像中,当同类物体出现不常见的长宽比和其他情况时,泛化能力偏弱。因为没有预设锚框,模型预测框的尺度完全受训练集数据驱动,所以,对不常见的长宽比和其他情况泛化能力弱。
- (3)由于损失函数的问题,定位误差是影响检测效果的主要原因,尤其是大小物体的处理上,还有待加强。
深入解析一下YOLO(特别是原始版本YOLOv1)的这些缺点和局限性。这些缺点并非YOLO理念不好,而是其第一代设计在追求“极速”时所做的权衡和妥协。
- 对密集和小目标检测效果差
核心原因:“一个网格只预测一个目标”的设计限制。
-
工作机制回顾:YOLOv1将图像划分为
S×S
(如7×7
)的网格。每个网格只负责预测一个其中心点落在该网格内的物体。 -
问题产生场景:
- 场景一:密集小目标。当图像中存在一群挨得很近的人或车时(例如一支足球队),多个物体的中心点很可能落入同一个网格中。根据设计,这个网格只能“选择”其中一个目标进行预测,其他目标就会被漏检。
- 场景二:小目标。一个小目标(如远处的一只鸟)在图像中可能只占据几个像素。经过多层卷积下采样后,在最后的特征图上,可能连一个网格都占不满,特征信息变得非常微弱,导致模型难以学习其 pattern,从而被忽略。
-
与后续版本的对比:YOLOv2及之后的版本通过引入锚框(Anchor Boxes) 和多尺度预测 极大地缓解了这个问题。锚框机制让一个网格可以预测多个不同形状的框,提高了检测密集目标的能力。多尺度预测则通过不同分辨率的特征图来分别检测大、中、小物体。
- 对不常见长宽比泛化能力弱
核心原因:边界框预测方式不够灵活。
-
YOLOv1的预测方式:YOLOv1的每个网格直接预测边界框的宽
(w)
和高(h)
。这些宽高值是在训练过程中,网络从数据集中学习到的“平均”宽高。 -
问题产生场景:当测试中出现一个训练集中不常见的长宽比物体时(例如一个躺着的人、一个奇特角度的自行车),模型就会表现不佳。因为它从未学习过如何生成这样形状的框,它只能基于已有的“经验”去预测,导致预测框形状不准,从而拉低IoU,甚至造成误检或漏检。
-
与后续版本的对比:从YOLOv2开始,借鉴了Faster R-CNN的锚框机制。网络不再直接预测框的绝对宽高,而是预测相对于预先设定好的锚框(先验框)的偏移量。这些锚框是通过聚类训练集数据得到的几种最具代表性的宽高比例。这种方式让网络的学习任务变得更简单(只需学习微调),大大增强了对各种形状物体的泛化能力。
- 定位误差是主要误差来源
核心原因:损失函数对定位误差的权衡不足。
-
损失函数回顾:YOLO的损失函数同时优化分类、置信度和定位(坐标
x, y
和宽高w, h
)误差。 -
问题产生场景:
- 权重失衡:尽管使用了
λ_coord
来加重定位损失的权重,但在实际训练中,不包含物体的网格(负样本)远远多于包含物体的网格(正样本)。大量的负样本只会产生置信度损失,这可能导致模型更倾向于优先优化“简单”的置信度误差,而不是“困难”的定位误差。 - 平方误差(SSE)的弊端:YOLOv1对
x, y, w, h
均使用平方误差损失。这意味着对不同大小的框,同样的绝对误差会产生相同的损失值。然而,对于小框而言,几个像素的偏差对IoU的影响远大于大框。虽然对w, h
取平方根 (√w, √h
) 有所缓解,但未能根本解决。 - IoU与损失不直接挂钩:损失函数计算的是坐标值的误差,但最终评估指标是IoU。一个坐标上的小误差有时会导致IoU大幅下降,这种不对等关系也是定位不准的原因之一。
- 权重失衡:尽管使用了
-
与后续版本的对比:后续研究提出了如 IoU Loss、GIoU Loss 等直接基于IoU的损失函数,让网络的优化目标(损失)与评估指标(IoU)直接统一,显著提升了定位精度。
总结
YOLOv1的革命性在于其“一步到位”的思维,将目标检测转化为一个单一的回归问题,赢得了无与伦比的速度。
然而,这些优点也带来了相应的代价:
- 网格设计 ➜ 密集小目标漏检
- 直接预测框 ➜ 泛化能力弱
- 损失函数设计 ➜ 定位精度差
正是清晰地认识到这些局限性,才有了YOLOv2, v3等一系列精彩的改进,通过引入锚框、多尺度特征金字塔网络(FPN) 和更好的损失函数,在保持速度优势的同时,极大地弥补了YOLOv1的这些缺陷,使其成为至今仍被广泛使用的强大算法。
4 YOLOv2实现更好、更快、更强
YOLOv2是由Redmon等人对YOLO的改进版本。
YOLOv2具有YOLO没有的几个特性,例如,对不同分辨率的图像进行训练(Multi-Scale Training),从而在速度和准确性之间提供了一个简单的权衡。
此外,作者还谈到了另一个模型——YOLO9000(一个基于YOLOv2网络架构的实时检测模型),该模型利用WordTree组合检测数据集和分类数据集,实现同时在对象检测和图像分类数据集上训练模型,从而弥合这两种数据集之间的差距——可以预测没有标记检测数据的对象类的检测。YOLO9000可以检测超过9000种的对象。
YOLOv2还有一个名字:“YOLO9000,Better,Faster,Stronger”,“Better”指的是准确率更高,“Faster”表示检测速度更快,“Stronger”表示泛化能力更强,可以推广到更多领域。
5 YOLOv2改进YOLOv1——更好
更好,意味着更准确,也就是mAP更高。YOLOv2与YOLOv1对比如图6-5-1所示。
YOLOv2在提高准确率方面有以下改进措施。
- (1)使用批归一化。
- (2)使用高分辨率分类器。
- (3)使用带锚框的卷积。
- (4)使用框聚类。
- (5)使用约束边界框预测。
- (6)使用细粒度特征。
- (7)使用多尺度训练。
- (8)使用高分辨率检测。
5.1 批归一化
在训练过程中,CNN每层输入的分布一直在改变,会使训练过程难度加大,但可以通过规范化(Normalize)每层的输入解决这个问题。
新的YOLO网络在每个卷积层后添加批归一化(Batch Normalization),通过此方法,mAP获得2%的提升。批归一化也有助于规范化模型,可以在舍弃dropout优化后依然不会过拟合。
核心问题:为什么输入分布改变会让训练难度加大?
想象一下,你是一位老师,要教一群学生(神经网络)学习一套复杂的试卷(训练数据)。
- 正常情况:你每天给学生做难度稳定的练习题,今天教加法,明天教减法,循序渐进。学生们适应得很好,学得也快。
- 问题场景(内部协变量偏移):但有一天你突然发现,负责出题的助教(网络的底层)是个“疯子”。
- 他今天出的题全是超级难的微积分(分布A),明天出的题又变成幼稚园的1+1(分布B),后天又变成英语阅读理解(分布C)。
- 这样一来,学生(网络的高层)每天都得重新适应今天全新的、无法预测的题型难度。他们的学习进度变得极其缓慢且不稳定,因为他们的大部分精力都花在了“适应难度变化”上,而不是“学习知识本身”。
在神经网络中,每一层的输入都来自于前一层的输出。如果前一层的参数更新导致其输出数据分布发生剧烈变化,那么后一层就需要不断地去适应这个新分布。这就叫内部协变量偏移(Internal Covariate Shift),它大大增加了训练的难度和不确定性。
解决方案:批归一化(Batch Normalization)是什么?
为了解决这个问题,YOLO引入了一个“超级课代表”——批归一化(BN)。
这个超级课代表的工作流程如下:
- 收集作业:每次小测验(一个Batch的训练数据)后,他收齐所有学生的答案(该层的输出)。
- 计算平均分:他快速计算出这次测验的平均分(均值)和大家的分数差距有多大(方差)。
- 统一标准:他按照一个标准公式,把所有人的分数都归一化到同一个标准尺度上(比如都转换成平均分为70分,标准差为10的分布)。这样,无论助教出的题难还是易,经过课代表整理后,送到学生那里的题目难度都变得统一、稳定了。
- 再调整:课代表还很聪明,他知道有时候完全统一也不好。所以他还有两个可学习的参数(γ和β),可以稍微“放点水”或“压点分”,找到一个最适合当前学习进度的分数分布。
结果就是:学生们(网络的后层)再也不用关心助教(网络的前层)的“疯癫”状态了。他们每天都能收到难度稳定的习题,从而可以将所有精力都集中在学习核心知识(优化权重参数)上。训练过程因此变得更加快速、稳定和有效。
批归一化带来的两大好处
-
提升模型性能(mAP提升2%)
- 因为训练过程更稳定、更高效,模型能更好地收敛到更优的解。这直接体现在检测精度(mAP)上获得了2% 的提升。在目标检测领域,这是一个非常显著的进步。
-
取代Dropout,防止过拟合
- Dropout 是另一种防止模型死记硬背(过拟合)的技术,它通过在训练时随机“敲晕”一部分学生(神经元)来迫使其他学生学得更全面。
- 而批归一化本身引入的轻微随机性(因为每个Batch的统计量略有不同)就起到了类似的“正则化”效果,使得模型不会过度依赖任何一个神经元的输出。
- 因此,加了批归一化后,就可以舍弃Dropout了,使得模型结构更简洁,且依然能保证很好的泛化能力,不会过拟合。
总结
一句话概括:批归一化就是一个“稳定器”,它通过规范化每一层输入的数据分布,使得网络训练更快、更稳、效果更好,同时还能简化模型结构(省去Dropout)。 这就是YOLO引入它后性能获得显著提升的原因。
5.2 高分辨率分类器
在目标检测方法中,基本上都会使用ImageNet预训练过的模型来提取特征,例如,VGG系列的网络,输入图像会被重塑为224×224的大小,而检测过程中分辨率一般会是448×448,在训练时使用低分辨率,会给检测带来一定的困难。YOLOv2把分辨率直接提升到448×448,这意味着原有的网络模型必须进行调整以适应新的分辨率输入。
YOLOv2首先对以Darknet为主干的分类网络进行微调,分辨率改成448×448,在ImageNet数据集上训练10轮,训练后的网络就可以适应高分辨率的输入。然后对检测网络后半部分也进行微调。这样通过提升输入的分辨率,mAP获得4%的提升。
高的输入分辨率意味着图像包含更多的像素信息,细节更丰富
5.3 预设锚框并采用全卷积
YOLOv1存在定位问题,利用全连接层的数据完成边框的预测,导致丢失较多的空间信息,定位不准。这里借鉴Faster R-CNN的锚框思想。
如图6-5-2所示,在Faster R-CNN中,RPN生成锚框的关键步骤是,在卷积网络输出层的特征图的每个像素处产生9个尺度的锚框,这样定位问题有所改善。
其次,YOLOv1中只有B=2个框,尺度较少,所以,对小物体不敏感的问题也得到了解决。YOLOv2借鉴RPN的思想,具体如何操作呢?
- (1)去掉全连接层,使用全卷积网络。
- (2)去掉最后一个池化层,为了使输出分辨率更高。
- (3)缩减网络,使输入尺度为416×416,这样是为了使后面产生的卷积特征图的宽高为奇数(416/32=13),这样就产生一个中心单元格,因为大物体通常占据图像的中间位置,使用一个中间单元格可以来预测,否则就要使用中间4个单元格来预测。此技巧可以略微提高效率。
- (4)使用卷积层下采样,使416×416的图像最终输出13×13的特征。
增加锚框后,召回率上升,但是准确率下降。
假如每个单元预测9个锚框,则YOLOv2有1521(13×13×9=1521)个锚框;而YOLOv1直接预测98(7×7×2=98)个框,没有锚框,模型召回率为81%,mAP为69.5%;加入锚框后,模型召回率为88%,mAP为69.2%。这样看来,准确率小幅度下降,而召回率提升了7%,这是值得的。
一句话解释RPN思想
RPN(Region Proposal Network,区域提议网络)的核心思想是:让神经网络自己学习如何生成“可能包含物体的候选框”,而不是依赖人工设计的算法(如Selective Search)。
YOLOv1的痛点与RPN的解决方案
YOLOv1的 B=2
个直接预测的框,尺度少,灵活性差,是它对小物体和不常见长宽比物体检测不佳的主要原因。
YOLOv2的解决方案是:借鉴并简化RPN的“锚框(Anchor Box)”机制。
下面我们来看看YOLOv2是如何具体操作的:
第1步:网络结构调整(为引入锚框做准备)
(1) (2) (3) (4) 点,都是在为引入锚框做基础设施改造:
- (1)使用全卷积网络(FCN):去掉全连接层,使网络可以处理任意尺寸的输入图像,输出是一个特征图,这非常适合在特征图的每个点上预测固定数量的锚框。
- (2)&(4)获得更高分辨率的输出特征图:通过去掉最后一个池化层、使用卷积下采样,并将输入尺寸设为
416x416
,最终得到13x13
的输出特征图。13x13
比 YOLOv1 的7x7
网格多了一倍的网格数量,这意味着模型进行预测的“基点”更多了,天生就提升了检测小物体的潜力。 - (3)产生中心单元格:这是一个非常巧妙的工程技巧。大物体通常位于图像中心,
13x13
的奇数尺寸确保了有一个绝对的中央网格,由一个网格来预测中心物体比由四个网格协作更简单高效。
第2步:核心操作——引入锚框(Anchors)
这是借鉴RPN思想最直接的一步。
-
聚类得到先验框(Prior Boxes):
- RPN的锚框尺寸是手动设定的。
- YOLOv2更聪明:它对训练集中所有真实框的宽和高进行K-Means聚类(比如聚成9类),直接得到数据集中最常见的9种框的尺寸(如高瘦、宽扁、正方等),作为预设的先验框(Priors)。
- 好处:这些先验框的尺寸更符合实际数据分布,让网络学起来更容易。
-
改变预测目标:
- YOLOv1:直接预测框的绝对坐标
(x, y, w, h)
。 - YOLOv2:不再直接预测坐标,而是预测相对于预先设定的先验框的偏移量
(t_x, t_y, t_w, t_h)
和置信度。同时,每个网格还预测类别概率。 - 好处:网络的学习任务变简单了。它不再需要从零开始学习“框应该长什么样”,而是学习“在已知的这个大概模子上,如何进行微调才能更准”。这大大加快了训练速度并提升了稳定性。
- YOLOv1:直接预测框的绝对坐标
-
大幅增加预测框数量:
- YOLOv1:
7x7
网格,每个网格预测2
个框 -> 共98
个框。 - YOLOv2:
13x13
网格,每个网格预测9
个锚框 -> 共13 * 13 * 9 = 1521
个框! - 好处:召回率(Recall)大幅提升。模型“撒网”的密度大大增加,覆盖了图像中更多可能的位置和尺度,因此能捕捉到更多的物体,尤其是小物体。这就是您看到召回率从81%上升到88%的原因。
- YOLOv1:
为什么“召回率上升,准确率下降”?
这也是工程上的一种权衡(Trade-off)。
- 召回率(Recall)上升:因为“网”撒得更密了(1521个 vs 98个),能捞上来的“鱼”(物体)自然就多了,漏网之鱼变少。
- 准确率(Precision)略微下降:“网”密了,捞上来的“水草”和“垃圾”(背景错误)也可能会暂时变多。也就是说,模型找到了更多真物体,但也产生了更多的假正例(False Positives)。
为什么是“值得的”?
因为召回率提升(+7%)远大于准确率的下滑(-0.3%)。在目标检测中,召回率低意味着很多物体根本找不到,这是更致命的问题。而准确率略低,意味着框多了但有些框不准,这个问题可以通过后续网络更好的分类能力和边框回归能力来修复。事实上,YOLOv2通过其他改进(如Dimension Clusters、Direct location prediction等)很快就把准确率拉了回来,并实现了远超v1的mAP。
总结
YOLOv2借鉴的RPN思想,其具体操作就是:采用“锚框/先验框”机制,将预测目标从“直接回归绝对坐标”改为“预测相对于先验框的偏移量”,并通过增加网格数和锚框数量,极大地提高了模型的召回率,为检测小目标和密集目标奠定了基础。 这是一个用少量准确率换取大量召回率,最终显著提升整体性能的经典策略。
5.4 框聚类
有预设锚框后,还有两个问题:锚框尺度和宽高比问题。
在Faster R-CNN中,锚框尺度都是预定义的3个尺度,每个尺度有3个比例。
虽然在训练过程中网络也会学习调整锚框的宽高尺度和宽高比,最终得到准确的边界框,但是,如果一开始就选择更好的、更有代表性的先验框的尺度和宽高比,那么,网络就更容易学到准确的预测位置。
YOLOv2使用聚类方法来确定锚框的尺度和宽高比例。这里使用K-means聚类方法来训练边界框,这种方法可使mAP提升5%。
K-means聚类过程大致如下:**通过指定K个类,初始化类中心坐标,通过计算每个边界框与类中心距离,将每个边界框分到距离最近的第k类中(k的取值为0到K-1)**,然后重新计算每个类的类中心,更新类中心,循环迭代,直到类中心收敛完成聚类。
传统K-means聚类方法中的距离使用的是欧氏距离,如果在框聚类中使用,则较大的先验框会比较小的先验框产生更多的误差,聚类结果可能会偏离,因此,这里使用的是IoU指标的距离,公式如下:
聚类结果如图6-5-3所示,K个类中心就是K个锚框。
聚类得到的边框与预设先验框是不同的,聚类得到的框更加接近真实的物体框,即聚类得到的边框扁长的框较少,而瘦高的框更多(这符合行人的特征)。
与之前的1:2、1:1、1:1的宽高比完全不同。如表6-5-1所示,通过实验对比两种策略的优劣,使用聚类方法,仅5种框的召回率就和Faster R-CNN的9种相当,说明K-means方法的引入使生成的框更具有代表性。
锚框聚类可使mAP获得1%的提升。
5.5 约束边框位置
边框尺度和宽高比问题解决后,还有一个问题就是模型不稳定。
YOLOv1对位置预测没有限制,这使模型在早期迭代中不稳定。
预测的边界框可能远离原始网格位置。区域建议网络使用式(6-3)进行预测。
式中,
- x、y是预测框的中心;
- xa、ya是锚框的中心坐标;
- wa、ha是锚框的宽和高;
- tx、ty是要学习的参数。
由于tx、ty没有任何约束,所以,预测边框的中心可能会出现在任何位置。
例如,tx=1的预测会将框向右移动一个锚框宽度,tx=-1的预测会将其向左移动一个锚框宽度,因此,YOLOv2调整预测公式,将边框的中心约束在特征网格内,通过使用Sigmoid函数实现,此函数的输出正好是0~1的数值。Sigmoid函数用σ表示如下:
公式示意图如图6-5-4所示,其中,(Cx,Cy)是锚框中心所在的网格左上角的坐标;(tx,ty)是要学习的参数,经过Sigmoid之后是锚框中心相对网格左上角的坐标;(bx,by)是预测框中心坐标;(pw,ph)是聚类得到的锚框的宽高;(bw,bh)是预测框的宽高。
这种方法比YOLOv1的方法的mAP增加了5%。
5.6 细粒度特征
特征的颗粒度是与特征的下采样程度对应的。
下采样倍数越大,特征越模糊,颗粒度就越粗;
下采样倍数越小,特征图越清晰,颗粒度就越细。
在卷积过程中,输入图像的宽和高为416×416,最终输出32倍下采样,所得特征的大小为13×13。
虽然能够满足大尺度物体检测,但是在小物体检测上还有些不足。
如果加上细颗粒特征的话,对检测小目标物体是颇有帮助的。在R-CNN系列或者SSD中,都利用了不同粒度的特征图,如使用金字塔池化层。
YOLOv2使用了一个被称为穿越层(PassthroughLayer)的结构,即将前一层的26×26×512的特征图映射为13×13×2048的特征图,然后与原始13×13的特征图串接进行检测。
这个扩展的13×13×3072的特征图,提供了对细粒度特征的访问,如图6-5-5所示。
注意,YOLOv2的作者Redmon在后期的实现中借鉴了ResNet,不直接对高分辨特征图进行处理,而是增加了一个中间卷积层,先采用64个1×1 卷积核进行卷积,然后经过穿越层,这样就实现了由26×26×512的特征图到13×13×256的特征图的变换,这在后面介绍YOLOv2架构中各层细节时会有所体现。
5.7 多尺度训练
YOLOv1固定使用448×448(宽×高)的图像作为输入,现在输入变成416×416的图像。
YOLOv2去掉全连接层,替换成全局平均池化,只使用卷积层和池化层,因此,可以动态调整输入大小。
全局平均池化是指池化层输入特征的大小为S×S,无论S为多少,都输出1×1大小的特征,因此,可以动态调整输入图像的大小。
为了增加YOLOv2针对不同尺寸的图像的鲁棒性,使用多尺度的输入进行训练。
多尺度训练的好处是在小的图像上训练可以增加网络识别大目标物体的能力,在大的图像上训练可以增加网络识别小目标的能力,多尺度训练使得mAP提高1.5%,如图6-5-6所示。
可以看出,不同于固定大小的输入图像尺寸的方法,每训练10个批次,就会随机选择图像尺寸,调整网络大小并继续训练。
因为输出特征是经过32倍下采样后得到的,所以,YOLOv2使用32的倍数作为尺度的缩放倍数,尺寸范围为{320,352,…,608}。其中,最小尺度为320×320,最大尺度为608×608。
多尺度训练策略可以使网络更好地预测不同尺度的图像,意味着同一个网络可以进行不同分辨率的检测任务。
在小尺度图像上,YOLOv2运行更快,能够在速度和精度上达到平衡。如表6-5-2所示,当输入为228×228时,FPS(Frames Per Second,每秒传输帧数)达到91,mAP和FasterR-CNN一样。因此,其在低性能GPU、高帧率视频、多路视频场景中更加适用。在大尺度图像上,当输入为544×544时,YOLOv2的mAP达到78.6%,高于平均水准。
绘制成坐标图更加直观,如图6-5-7所示,显然YOLOv2几个尺寸的坐标离原点比较远,两个坐标值都比较大,说明性能均衡提高。
5.8 实验对比
以上改进策略都会使mAP显著增加(切换到带有锚框的完全卷积网络除外)。带锚框的全卷积网络,在基本不改变mAP的情况下增加了召回率。
表6-5-3所示为YOLOv2与各算法在Pascal VOC 2012数据集上的测试性能对比。YOLOv2的性能与带有ResNet的Faster R-CNN和SSD512不相上下。
表6-5-4所示为YOLOv2与各算法在COCO 2015数据集上的测试性能对比,表中的数据来源均为YOLOv2论文。
6 YOLOv2 使用Darknet-19——更快
本节介绍YOLOv2版本为什么会更快。
6.1 Darknet-19
大多数检测框架把VGG-16作为主干网络进行特征提取。VGG-16是一个强大、准确的分类网络,但它很复杂,其实没必要。VGG-16的卷积层需要306.9亿次浮点运算才能在224×224分辨率下对单幅图像完成处理,如表6-6-1所示。
YOLOv1使用基于GoogLeNet架构的自定义网络,该网络比VGG-16更快,前向传递需要85.2亿次操作。准确率略逊色,YOLOv1在ImageNet获得88.0%的top-5准确率,而VGG-16为90.0%。
在v2版本中,YOLO设计了一种Darknet-19的网络结构。Darknet-19使用19个卷积层和5个最大池化层。该网络借鉴VGG系列,使用较多的3×3卷积核,在每次池化操作后把通道数翻倍。
网络使用全局平均池化(Global Average Pooling),把1×1的卷积核置于3×3的卷积核之间,用来压缩特征。
同时使用批归一化来稳定模型训练。该网络结构比VGG-16小一些,精度不比VGG-16弱,但浮点运算量可约减少到1/5,以保证更快的运算速度。
速度之所以快还有一个最重要的原因,那就是Darknet-19没有全连接层,使用一个全局平均池化,避免全连接过程中大量运算。
YOLOv2只需要55.8亿次操作来处理图像,却在ImageNet上达到了72.9%的top-1准确率和91.2%的top-5准确率。
Darknet-19可以在准确率和模型复杂度之间取得很好的平衡,top-1和top-5错误接近ResNet-50,如表6-6-2所示。Darknet-19具有更低的模型复杂度的浮点运算数,因此,检测速度快得多。
核心摘要
这段话对比了YOLOv1和YOLOv2所使用的特征提取网络(主干网络),并阐述了Darknet-19的设计如何通过借鉴现代深度学习的最佳实践,在精度和速度之间取得了更优的平衡。
- 关于YOLOv1的网络
- 基础架构:YOLOv1采用了一个基于GoogLeNet的自定义网络。GoogLeNet的核心创新是“Inception模块”,它通过在同一层使用不同尺寸的卷积核并行计算,再聚合结果,从而高效地提取多尺度特征。
- 性能表现:
- 速度(85.2亿次操作):这个数字是计算复杂度的衡量标准,代表处理一张图片需要进行85.2亿次浮点运算。数值越低,速度越快。这表明YOLOv1的网络比当时的主流网络(如VGG-16)更轻量、更快速。
- 准确率(88.0% top-5):这是在ImageNet图像分类数据集上评估的分类精度。“Top-5准确率”是指模型预测概率最高的5个类别中包含正确标签的比率。作为对比,VGG-16达到了90.0%。这表明YOLOv1的网络在特征提取能力上略逊于更深或更复杂的网络,但这是为了追求速度而做出的合理权衡。
- 关于YOLOv2的网络:Darknet-19
为了提升性能,YOLOv2设计了一个新的主干网络——Darknet-19。
- 名称与结构:该网络包含19个卷积层和5个最大池化层。层数的增加本身有助于提取更复杂、更抽象的特征。
- 设计灵感(借鉴VGG):
- 大量使用3x3卷积核:这是VGG网络的经典设计。小尺寸卷积核串联使用,可以用更少的参数达到与大卷积核相同的感受野,使网络更深、更高效,同时减少计算量。
- 通道数翻倍:每次进行池化(下采样)后,空间尺寸(宽、高)减小,但通道数(深度)会翻倍。这是一种常见的做法,旨在随着空间信息的压缩,相应地增加特征图的维度以保留更多信息。
- 关键组件与技术:
- 1x1卷积核:被放置在3x3卷积之间,用于压缩特征通道数(降维),从而减少后续计算的参数量和计算量。
- 全局平均池化(GAP):在网络的最后,用全局平均池化层替代传统的全连接层。GAP将每个特征图直接取平均值,输出一个数值。这极大地减少了参数量,有效防止过拟合,并使网络能接受不同尺寸的输入。
- 批归一化(BN):在每个卷积层后加入批归一化。BN通过规范化每层的输入,稳定了训练过程,加速收敛,并在一定程度上起到了正则化的作用,因此可以舍弃Dropout等技术。
- 性能优势:
- 比VGG-16小:指网络参数总量更少,模型文件更小。
- 精度不弱:在ImageNet等数据集上,其分类精度与VGG-16相当。
- 浮点运算量减少到1/5:这是最关键的提升。Darknet-19仅需VGG-16约20%的计算量就能达到相近的精度,这意味着它的前向传播速度极快,完美契合YOLO实时目标检测的需求。
总结
特性 | YOLOv1 (基于GoogLeNet) | YOLOv2 (Darknet-19) | 优势 |
---|---|---|---|
核心目标 | 追求速度 | 速度与精度的更优平衡 | - |
设计理念 | 自定义、轻量 | 系统化设计,融合最佳实践 | 更科学、更强大 |
关键技术 | Inception模块 | 3x3卷积、1x1卷积、BN、GAP | 训练稳定、参数少、速度快 |
计算量 | 85.2亿次操作 | 远低于VGG-16 (约1/5) | 极快的推理速度 |
准确率 | 略低 (88.0%) | 与VGG-16相当 | 更强的特征提取能力 |
简而言之,Darknet-19是一个精心设计的、融合了多种现代网络设计技巧(VGG的深度、1x1卷积、BN、GAP)的高效特征提取器,它用更少的计算消耗获得了更强的性能,是YOLOv2相比v1实现全面升级的基础。
YOLOv1使用基于GoogLeNet架构的自定义网络,该网络比VGG-16更快,前向传递需要85.2亿次操作。
准确率略逊色,YOLOv1在ImageNet获得88.0%的top-5准确率,而VGG-16为90.0%。
在v2版本中,YOLO设计了一种Darknet-19的网络结构。
Darknet-19使用19个卷积层和5个最大池化层。该网络借鉴VGG系列,使用较多的3×3卷积核,在每次池化操作后把通道数翻倍。
网络使用全局平均池化(Global Average Pooling),把1×1的卷积核置于3×3的卷积核之间,用来压缩特征。
同时使用批归一化来稳定模型训练。
该网络结构比VGG-16小一些,精度不比VGG-16弱,但浮点运算量可约减少到1/5,以保证更快的运算速度。
三个问题
- 为什么池化操作后能把通道数翻倍?
这并非一个自然发生的现象,而是一种人为设计的、约定俗成的网络构建策略。其背后的逻辑是:在空间信息减少时,增加信息的深度(通道数)以维持模型的表征能力。
- 池化(Pooling)的作用:最大池化层的主要功能是下采样(Downsampling)。它将特征图的宽度和高度(例如从
224x224
变为112x112
),从而减少空间维度和计算量,并让后面的卷积层能够感知到更广阔的区域(增大感受野)。但这个过程会丢失一些细节信息。 - 翻倍通道数的逻辑:
- 信息补偿:当空间尺寸(宽、高)减半(
缩小2倍
)后,总的激活值(activation)数量会减少到原来的1/4
。为了在一定程度上维持网络的表征容量,一个巧妙的做法是将通道数(深度)翻倍(增大2倍
)。这样,整体信息量可以大致保持平衡(1/4 * 2 = 1/2
,虽未完全抵消,但是一种有效权衡)。 - 计算上的对称性:在卷积神经网络中,通常使用步长为2的卷积或池化进行下采样。将通道数翻倍(
2x
)与空间尺寸减半(1/2x
)配合使用,使得网络结构规整、对称,便于设计和理解。
- 信息补偿:当空间尺寸(宽、高)减半(
简单比喻:就像把一封信(图像信息)放进一个更小的信封(池化后的特征图)里,为了不让内容丢失太多,我们改用更细密的字和更薄的纸来写(通道数增加),从而在小信封里装下和原来差不多多的信息。
- 为什么把1×1的卷积核置于3×3的卷积核之间,可以用来压缩特征?
这里的“压缩特征”指的是减少特征图的通道数,而1x1卷积是实现这一目的的完美工具。
-
1x1卷积的核心功能:它是在深度(通道方向) 上进行的操作。一个
1x1 x C
的卷积核,会与输入特征图的一个1x1 x C
的局部区域做点积,输出一个单值。使用N
个这样的卷积核,就可以将输入特征图从C
个通道变为N
个通道。- 如果
N < C
,就实现了降维(压缩)。 - 如果
N > C
,就实现了升维。 - 如果
N = C
,则只是对原有通道信息进行一次线性组合。
- 如果
-
为何置于3x3卷积之前?—— “Bottleneck(瓶颈)”设计
假设输入有256个通道,紧跟一个3x3的卷积层(假设输出也是256通道)。- 计算量:
3 * 3 * 256 * 256 = 589,824
次运算(每个输出像素)。 - 如果中间插入1x1卷积进行压缩:
256 ->(1x1 conv,压缩到64通道) -> 64 ->(3x3 conv,扩展到256通道) -> 256
- 1x1卷积计算量:
1 * 1 * 256 * 64 = 16,384
- 3x3卷积计算量:
3 * 3 * 64 * 256 = 147,456
- 总计算量:
16,384 + 147,456 = 163,840
次运算。
- 1x1卷积计算量:
- 计算量:
-
对比:
163,840
vs589,824
,计算量减少了约 72%!而网络的非线性表达能力由于层数的增加和ReLU激活函数的存在,并未显著减弱。这就是1x1卷积“压缩”特征带来的巨大计算优势。
简单比喻:3x3卷积就像是一个大胃王,吃得很多(计算量大)。1x1卷积是一个高效的预处理厨师,它先把一大堆食材(256通道)精炼成一份浓缩高汤(64通道),再交给大胃王去处理。大胃王吃得轻松了,整体做饭效率就大大提升了。
- 为什么浮点运算量可约减少到1/5,可以保证更快的运算速度?
Darknet-19相比VGG-16计算量大幅减少,主要源于两个关键设计:
a) 用全局平均池化(GAP)取代全连接层(FC)—— 这是最大的贡献
这是减少计算量的头号功臣。我们以ImageNet分类的经典输入 224x224
为例,假设最后一个卷积层的输出是 7x7x512
的特征图。
- VGG-16的做法:将其展平为一个
7*7*512 = 25088
长度的向量,然后连接几个巨大的全连接层(如FC1有4096个神经元)。- 仅FC1一层的计算量(参数数量):
25088 * 4096 ≈ 102.8 million
(1.028亿)次乘加运算!这仅仅是一层的参数。
- 仅FC1一层的计算量(参数数量):
- Darknet-19的做法:使用全局平均池化(GAP)。对
7x7x512
的特征图,在每个通道上求平均值,即把每个7x7
的平面压缩成一个数字。- 结果:得到一个
1x1x512
的特征向量。 - 计算量:GAP几乎不需要计算(就是求平均),并且将这个512维的向量送到分类器所需的计算量微乎其微(比如
512 * 1000
)。 - 对比:
512 * 1000
vs25088 * 4096
,计算量的差距是数量级的。GAP彻底移除了模型中最耗计算资源的全连接层。
- 结果:得到一个
b) 大量使用小卷积核和1x1的“瓶颈”结构
如上文第二点所详述,Darknet-19借鉴了这些高效的设计,使得在保持相近深度(19层 vs 16层)的情况下,每一层的计算效率都远高于VGG-16。
- VGG-16以使用大量通道数(512,甚至1024)的3x3卷积而闻名,虽然结构规整,但非常“笨重”。
- Darknet-19通过1x1卷积在通道数上进行压缩和扩张,灵活地控制每个阶段的通道数,避免了像VGG-16那样一直使用非常大的通道数,从而极大地减少了浮点运算量(FLOPS)。
结论:正是由于移除了全连接层和采用了更高效的卷积块设计这两大举措,Darknet-19才能用仅相当于VGG-16约1/5的计算量,完成同样出色的特征提取任务。计算量(FLOPS)的直接减少,意味着完成一次前向传播所需的算术运算次数更少,因此在相同的硬件上运行速度自然就更快。
6.2 三阶段训练
YOLOv2的训练主要包括3个阶段,前两个阶段是分类训练,最后一个阶段是检测训练,如图6-6-1所示。
分别是以下3个阶段:
- (1)在ImageNet分类数据集上预训练Darknet-19,此时输入为224×224的张量。
- (2)将网络输入调整为448×448的张量,继续在ImageNet上微调模型。
- (3)修改Darknet-19分类模型为检测模型:去掉最后一个卷积层全局平均和Softmax层;新增3个3×3×1024的卷积层,同时增加一个穿越层,最后使用1×1输出预测结果,输出通道数为
式中,numchannel表示通道数;numanchors表示锚框的数量;括号中的5表示4个坐标值和对应的置信度;num_classes对应的数量为20(VOC数据集)。
因此,输出通道数为5×25=125,如果分类在实际操作中,先将输出的张量重塑成形状(batch_size,13,13,5,25),如果以T表示一个张量,每个批次的边框中心点坐标和宽高为(tx,ty,tw,th),用Loc表示:数是1000,这里就是5×1005=5025。
在实际操作中,先将输出的张量重塑成形状(batch_size,13,13,5,25),如果以T表示一个张量,每个批次的边框中心点坐标和宽高为(tx,ty,tw,th),用Loc表示:
YOLOv2各层结构和输出如图6-6-2所示。
其中,22~24层为检测网络新增的3个3×3×1024卷积层。
25层route 16表示将第16层的输出拿过来;26层实现通道缩减,利用1×1卷积把26×26×512变为26×26×64;27层reorg表示宽、高数据移到通道维上,即space to depth(TensorFlow中函数space_to_depth实现这个变换)。
这个操作可以将26×26×64变换为13×13×256,共256个13×13;28层route 27 24表示将27层与24层的输出串接在一起,1024+256=1280,输出13×13×1280,正是前面说的细粒度特征。28层再经过29层3×3卷积和30层1×1卷积完成检测。
最后,对比一下YOLOv2与YOLO的输出:
- ①YOLO没有先验框,直接输出2个框;而YOLOv2预设5个先验框,并且通过K-means聚类得到框的尺寸,更加接近真实物体框。
- ②输出特征下采样倍数不同(YOLOv2是32倍下采样,而YOLO是64倍下采样),这使得YOLOv2比YOLO能检测更小的物体。
- ③YOLOv2输出13×13×5×25的张量,即每个单元格(网格)负责多个目标,这种输出可以检测两个挨在一起的目标,YOLO则不能。
6.3 YOLOv2的损失函数
官方论文没有像YOLOv1那样提供YOLOv2的损失函数,下面结合Darknet的源码来分析YOLOv2的损失函数。
对于真值框,中心落在哪个单元格,就由该单元格的5个锚框中IoU最大的框负责预测,即计算锚框与真值框IoU,选IoU值最大的那个。
这样,每个框至多预测一个目标。IoU最大的先验框负责计算坐标误差、置信度误差及分类误差,其他4个边界框只计算置信度误差。
对于(i,j),即第i个单元格的第j个锚框,Ci,j表示边框(i,j)的置信度,在YOLOv1讲过置信度,置信度得分反映了框包含对象的可能性及边界框的准确性,用P(Object)×IoU表示,也就是不光是有物体,还考虑IoU,即与真值框的重叠。因此,IoU最大的先验框,负责预测真值框,那么设置这个框的Ci,j=1,否则,Ci,j=0。
(1)第1项:位置损失负责预测目标的锚框的坐标损失,包括中心定位和边界定位。对其进行展开来观察细节,如式(6-10)所示,YOLOv1中的边界定位采用根号后的差值的平方。
这里当Ci,j=1时,
=1,其他情况等于0。
最后,我们来说一下这里的系数,其用于平衡数值。因为框位置、置信度、类别数量是不平衡的,所以,需要用一些系数加以平衡,怎么平衡呢?很简单,分别用λcoord、λobj、λnoobj、λclass除以相应的数量,
图6-6-5所示为YOLOv2与其他方法的速度对比,横坐标为GPU所耗时间(GPU Time),纵坐标为总体mAP(Overall mAP)。
从图中可以看出速度最快的是最左边方块,图上有注解,是SSD的检测器。最上面的是mAP最大的检测器,是Faster R-CNN。不同颜色表示不同Backbone的卷积神经网络。可以看出,Faster R-CNN虽然mAP高,但是检测速度很慢。
再来看看YOLOv2的对比,在图6-6-3中,紫红色五角星表示YOLOv2表现,很明显,YOLOv2的速度是很快的,红色虚线为实时检测时间线,也就是说YOLOv2达到实时检测的效果。
再看YOLOv2的精度,很明显YOLOv2的总体mAP也在平均水平上,是各类检测器中能够很好地平衡速度和精度的一种检测器,在同等准确率下速度是很棒的。
准确率及速度对比如表6-6-3所示:
可以看出YOLOv2的top-1准确率是74%,top-5准确率是91.8%。所谓top-1准确率,是指排名第一的类别与实际结果相符的准确率,而top-5准确率是指排名前五的类别包含实际结果的准确率。单次运行次数为55.8亿次,运行速度是每秒200帧,准确率也比YOLOv1有所提高,虽然比ResNet-50稍微低些,但是速度是ResNet-50的2倍。YOLOv2很好地兼顾了准确率和速度。
一、YOLOv2 预测机制与损失函数计算流程图
该流程图清晰地展示了YOLOv2如何分配预测责任并计算损失。
二、损失函数组成部分详解表
下表对应流程图中“计算所有三项损失”的细节,解释了损失函数中每个部分的具体含义和目标。
损失组成部分 | 计算对象 | 功能描述 | 数学公式 | 关键说明 |
---|---|---|---|---|
位置损失 (中心点) | 负责预测的锚框 | 惩罚预测框中心点(x, y)与真实框的偏差。 | λ_coord * Σ [ (x_i - x_hat_i)² + (y_i - y_hat_i)² ] | 只对“责任人”框计算。 |
位置损失 (宽高) | 负责预测的锚框 | 惩罚预测框宽高(w, h)与真实框的偏差。为减小大框的绝对误差影响,对宽高取平方根。 | λ_coord * Σ [ (√w_i - √w_hat_i)² + (√h_i - √h_hat_i)² ] | 只对“责任人”框计算。取平方根使损失更均衡。 |
置信度损失 (正样本) | 负责预测的锚框 | 鼓励“责任人”框的预测置信度接近1(即最高置信度)。 | Σ (C_i - 1)² | 真实目标值 C_hat = 1 。 |
置信度损失 (负样本) | 不负责预测的锚框 | 惩罚其他框的错误自信,鼓励其预测置信度接近0。 | λ_noobj * Σ (C_i - 0)² | 真实目标值 C_hat = 0 。λ_noobj 用于降低大量简单负样本的权重。 |
分类损失 | 负责预测的锚框所在网格 | 惩罚预测的分类概率与真实类别标签的误差。 | Σ (p_i(c) - p_hat_i(c))² | 按类别计算平方和误差。 |
三、YOLOv2 与其他检测器性能对比表
文末关于YOLOv2在速度和精度上的表现,并与其他主流方法进行对比。
模型/检测器 | 骨干网络(Backbone) | mAP (准确率) | 速度 (FPS) | 核心优势 | 定位 |
---|---|---|---|---|---|
YOLOv2 | Darknet-19 | ~74% (Top-1) 91.8% (Top-5) | 200 | 速度和精度的最佳平衡,达到实时检测标准。 | 又快又准 |
Faster R-CNN | VGG-16 / ResNet | 高 (~73.2% VOC2007) | 慢 (~7 FPS) | 精度高,曾是业界标杆。 | 更准但慢 |
SSD | VGG-16 | 中等 | 极快 (最高) | 速度极快,单阶段检测器先锋。 | 最快但精度一般 |
YOLOv1 | Custom GoogleNet | 63.4% (VOC2007) | 45 | 开创性实时检测器,但精度和定位能力较差。 | 快但不够准 |
说明:
- mAP: 综合衡量检测准确度的指标,值越高越好。
- FPS (Frames Per Second): 每秒处理的图像帧数,衡量速度,值越高越快。
- 实时检测: 通常认为 ≥ 30 FPS 即可称为“实时”,YOLOv2远超这一标准。
- 结论: YOLOv2在保持高精度(优于SSD,接近Faster R-CNN)的同时,实现了极快的检测速度(远超Faster R-CNN),是其最大的成功之处。