YOLO(You Only Look Once)目标检测算法的单次检测原理与实现细节
YOLO(You Only Look Once)是一种开创性的单阶段目标检测算法。与传统的两阶段方法(如R-CNN系列)不同,YOLO将目标检测重构为一个单一的回归问题,直接从图像像素预测边界框(Bounding Box)和类别概率,实现了速度与精度的良好平衡。
题目描述
讲解YOLO目标检测算法的核心思想、关键设计细节、网络架构、损失函数以及训练与推理过程。核心在于理解YOLO如何将整个检测任务转化为一个端到端的回归问题,实现“只看一次”即可预测多个目标的类别与位置。
解题过程详解
第一步:核心思想——将检测视为网格化的回归问题
YOLO的核心创新在于其看待图像的方式。
-
网格划分:
- 输入图像首先被划分为一个 \(S \times S\) 的网格(例如,YOLOv1使用 \(7 \times 7\) 的网格)。
- 每个网格单元(Grid Cell)负责预测那些中心点落在该单元内的目标物体。
-
每个网格单元的预测任务:
- 对于 \(B\) 个边界框(Bounding Box),每个框预测5个值:中心坐标 \((x, y)\)、宽度 \(w\)、高度 \(h\),以及一个框的置信度得分(Confidence Score)。
- 同时,预测 \(C\) 个类别的条件概率 \(P(Class_i | Object)\),即假定网格中存在目标时,该目标属于每个类别的概率。
- 因此,每个网格单元的输出维度为:\(B \times 5 + C\)。对于YOLOv1,\(S=7, B=2, C=20\)(PASCAL VOC数据集),所以最终输出是一个 \(7 \times 7 \times (2*5+20) = 7 \times 7 \times 30\) 的张量。
-
置信度得分的定义:
- 置信度得分 = \(P(Object) \times IOU^{truth}_{pred}\)。
- \(P(Object)\):该预测框内包含目标物体的概率(0或1)。
- \(IOU^{truth}_{pred}\):预测框与真实框(Ground Truth)的交并比(Intersection over Union)。
- 这个得分同时反映了框内是否有目标以及框的位置准不准。
第二步:网络架构设计
YOLOv1采用了一个简化的自定义卷积神经网络。
-
骨干网络:
- 受到GoogLeNet的启发,由24个卷积层和2个全连接层构成。
- 卷积层主要用于特征提取,全连接层用于输出最终的 \(7 \times 7 \times 30\) 预测张量。
- 使用 \(1 \times 1\) 卷积来压缩特征图通道数,减少计算量。
-
端到端训练:
- 整个网络从输入图像到输出检测结果,是一个单一的、可微分的函数,因此可以使用反向传播进行端到端的训练。
第三步:关键技术与实现细节
-
边界框参数化:
- \((x, y)\) 坐标是相对于当前网格单元左上角的偏移量,并通过Sigmoid函数归一化到 \((0, 1)\) 之间,确保中心点落在该单元内。
- \((w, h)\) 是相对于整张图像宽度和高度的比值。原始预测值经过指数变换(\(e^{pred}\))后得到最终宽度和高度,允许预测框大于网格单元本身。
-
非极大值抑制(Non-Maximum Suppression, NMS):
- 推理时,同一个目标可能被多个网格单元预测出多个框。NMS用于过滤冗余框。
- 步骤:
a. 丢弃所有置信度低于设定阈值(如0.5)的预测框。
b. 在剩余的框中,选择置信度最高的框。
c. 计算该框与所有其他框的IoU。如果IoU大于另一个阈值(如0.45),则认为它们检测的是同一个目标,将置信度较低的框丢弃。
d. 重复步骤b和c,直到处理完所有框。
-
多尺度预测:
- YOLOv1的一个局限是每个网格单元只能预测固定数量(B=2)的框,且对密集小目标检测效果不佳。后续版本(YOLOv2/v3)引入了多尺度预测和锚框(Anchor Box) 机制来改进。
- 锚框:预先定义一组具有不同宽高比的候选框(例如,YOLOv2使用k-means聚类在训练集上得到5个锚框尺寸)。网络不再直接预测框的绝对尺寸,而是预测相对于这些锚框的偏移量和缩放因子,这使得模型更容易学习。
第四步:损失函数设计
YOLO的损失函数是一个多任务损失,需要同时优化坐标、置信度和分类。
总损失 = 坐标损失 + 置信度损失 + 分类损失
具体形式(以YOLOv1为例):
\[\begin{aligned} \mathcal{L} = & \lambda_{coord} \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{obj} \left[ (x_i - \hat{x}_i)^2 + (y_i - \hat{y}_i)^2 \right] \\ &+ \lambda_{coord} \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{obj} \left[ (\sqrt{w_i} - \sqrt{\hat{w}_i})^2 + (\sqrt{h_i} - \sqrt{\hat{h}_i})^2 \right] \\ &+ \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{obj} (C_i - \hat{C}_i)^2 \\ &+ \lambda_{noobj} \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{1}_{ij}^{noobj} (C_i - \hat{C}_i)^2 \\ &+ \sum_{i=0}^{S^2} \mathbb{1}_{i}^{obj} \sum_{c \in classes} (p_i(c) - \hat{p}_i(c))^2 \end{aligned} \]
关键点解释:
- \(\mathbb{1}_{ij}^{obj}\):指示符函数,如果网格 \(i\) 的第 \(j\) 个预测框负责某个真实目标(即与该目标的IoU最大),则为1,否则为0。
- \(\mathbb{1}_{ij}^{noobj}\):表示该预测框不负责任何目标。
- \(\lambda_{coord}\)(如5)和 \(\lambda_{noobj}\)(如0.5):是权重系数,用于平衡不同损失项的重要性。因为大多数网格不含目标,不包含目标的置信度损失需要被降权。
- 对宽度和高度取平方根:这是为了缓解大框和小框在宽高误差上敏感度不同的问题。对大框来说,小的宽高偏移可接受;但对小框,同样的偏移影响更大。取平方根后,小框的梯度会变大,使其得到更精确的回归。
第五步:训练与推理流程总结
-
训练:
- 输入:图像缩放到固定尺寸(如448x448)。
- 前向传播:经过CNN得到 \(S \times S \times (B*5+C)\) 的输出张量。
- 计算损失:将预测值与真实标签(需编码为与网络输出相同的格式)比较,计算上述复杂的多部分损失。
- 反向传播与优化:使用梯度下降算法(如SGD)更新网络权重。
-
推理:
- 输入图像经过网络,得到所有网格单元的预测。
- 根据预测的 \((x, y, w, h)\) 和置信度得分,解码出所有候选边界框在原始图像上的绝对坐标和得分。
- 对每个类别,应用置信度阈值过滤(去掉低分框)。
- 应用非极大值抑制(NMS),得到最终的不重叠的检测框及其类别标签。
总结
YOLO算法通过将目标检测问题重新定义为单一的回归问题,实现了前所未有的检测速度。其核心在于网格划分、每个网格的多任务预测、精心设计的损失函数以及推理时的NMS后处理。尽管YOLOv1在定位精度尤其是对小物体检测上存在不足,但其思想为后续的单阶段检测器(如SSD,以及YOLO的后续版本v2, v3, v4, v5, v7, v8等)奠定了基础。这些后续版本不断改进,通过引入锚框、多尺度特征金字塔、更强大的骨干网络等,在保持速度优势的同时,显著提升了检测精度。