YOLO 是怎么工作的:目标检测的原理与流程


分类只需回答”是什么”,检测还要回答”在哪里”,并且一张图里有几个目标、是什么,事先都不知道。YOLO 的全部设计,都是围绕这三个”不知道”展开的。

一、目标检测是个什么问题

把视觉任务排成一条谱线,从易到难是:图像分类、定位、目标检测、实例分割。分类只需要输出一个类别标签;定位在分类之外多输出一个框,但默认图里只有一个主目标;目标检测则要找出图中所有感兴趣的目标,每个目标给出一个框、一个类别和一个置信度——目标的数量在推理之前是未知的,这正是检测区别于定位的本质困难。
检测器的每条输出由四元组构成:边界框的位置与大小(三种常见表示:左上右下两个角点、中心点加宽高、以及中心点加到四条边的距离)、类别、置信度。评价两个框是否框住了同一个目标,用的是交并比:

$$\text{IoU}(A, B) = \frac{|A \cap B|}{|A \cup B|}$$

IoU 是一个介于 0 和 1 之间的数,两个完全重合的框为 1,完全不相交为 0。检测任务的几乎所有质量标准都建立在它上面:预测框与真实框的 IoU 超过某个阈值(常用 0.5),且类别一致,这条预测才算命中。

先把几种”框”说清

检测里的”框”按角色分三种,加上量它们的尺子,一共四个词,先把关系说清。

边界框(bounding box)是总称:把目标圈起来的矩形,由四个数确定,前面说的几种表示只是同一个矩形的不同写法。

真实框(ground truth)是人工标注的标准答案。训练集里每个目标都有一个标注员给出的框和类别,模型的全部学习目标就是逼近它。真实框是人标的、本身带噪声——框松了、紧了、漏了——所以常说标注质量封死模型上限。

预测框(prediction)是模型输出的框。评估的全部内容,就是拿预测框和真实框算重合度。

锚框(anchor box)既不是答案也不是输出,而是预设的参考框。让网络直接回归绝对坐标,框的宽可以是十几也可以是几百,数值跨度大、不好学;改成”相对一个预设框预测偏移量”,问题温和得多。锚框的形状来自对训练集真实框的聚类,一组锚框覆盖几种典型长宽比。v6 之后的去锚框设计去掉了它,让特征图上每个位置直接预测到四条边的距离——参照物从预设框换成了位置本身。三者的关系一句话:真实框是答案,锚框是参考线,预测框是答卷。

IoU 的手算值得走一遍:两个框的交集,宽是右边界取小减左边界取大,高是下边界取小减上边界取大,任一为负即不相交。预测框 (200, 300, 450, 420) 与真实框 (198, 298, 452, 418) 几乎重合,IoU 接近 0.97;预测框整体偏出去一百像素,交集只剩一条边,IoU 跌到 0.3 上下——“命中”与”没命中”之间的距离就是这么具体。

还有一个词会反复出现:NMS(非极大值抑制)。同一个目标周围,相邻的多个位置都会各自输出一个高置信度的框,直接输出就是一叠重复框。NMS 做的事:按置信度从高到低排序,保留最高的,删掉与它 IoU 超过阈值的其余框,对剩下的重复这一步,直到没有冗余。完整算法、它的缺陷与变体在第九节展开。

有了命中的定义,就能定义精度与召回,进而定义 AP(平均精度,precision-recall 曲线下的面积)与 mAP(对各类别取平均)。行业基准 COCO 用的是 mAP@[.5:.95]:把 IoU 阈值从 0.5 到 0.95 每隔 0.05 取一档,共十档,分别算 mAP 再平均。这个指标比”IoU 大于 0.5 就算对”严格得多——后者只要求框得大概齐,前者要求框得越来越准。另外 COCO 还按目标面积分成小、中、大三档分别报告,因为小目标检测的难度和大目标完全不是一个量级,一个总 mAP 会把它们糊在一起。

训练检测器比训练分类器多两类困难。一是类别极不平衡:一张图里真正的目标只占极少数位置,绝大多数位置是背景,损失函数如果平等对待所有位置,模型会学会永远预测”没有目标”。二是框的表示空间不友好:位置和大小是连续量,直接用分类损失去回归会收敛得很差。后文会看到,YOLO 十年间的多数改进,都是围绕这两点展开的。

二、两条路线:两阶段与单阶段

2014 年 R-CNN 给出的两阶段范式统治了早期检测:先用候选区域方法( selective search)在图里挖出约两千个”可能有东西的框”,再对每个框做分类与框微调。这条路线的精度好,但两千次前向传播注定快不起来。后续的 Fast R-CNN 把共享卷积提出来,Faster R-CNN(NeurIPS 2015)用区域建议网络(RPN)替换了 selective search,让候选框也由网络生成,两阶段就此定型:快了很多,但结构上是两个网络的串联。

YOLO 的立场写在标题里:You Only Look Once。把检测直接当成一个回归问题——一次前向传播,从整幅图直接输出所有框和类别,没有候选阶段。2016 年这篇论文(CVPR 2016)给出的理由是,人类看图一眼就能感知到有什么东西在哪,检测也应该是同一个量级的计算。

单阶段的代价在早期是明显的:定位精度不如两阶段,小目标和密集目标容易漏。但它的上限是两阶段结构上达不到的——推理成本一次前向封顶。于是单阶段内部发生了三场关键的技术演进,撑起了精度缺口:锚框机制(v2)、多尺度预测(v3)、训练技巧的系统化(v4)。同期的 SSD(ECCV 2016)和 RetinaNet(ICCV 2017,Focal Loss)从另外的角度验证了单阶段的潜力——Focal Loss 用一个调制因子解决类别不平衡,让单阶段第一次在精度上超过两阶段。

三、YOLO v1:把检测变成回归

v1 的设计非常直接:把输入图切成 S×S 的网格(论文里 S=7),每个网格单元负责预测中心落在它里面的目标。每个单元预测固定数量的框(B=2)和每框的置信度,再加一组类别条件概率(C=20,对应 PASCAL VOC 的二十类)。

置信度的定义值得写下来,它把”有没有目标”和”框得准不准”合成一个数:

$$\text{confidence} = P(\text{object}) \times \text{IoU}_{\text{pred}}^{\text{truth}}$$

前半部分是这个单元里有目标的概率,后半部分是预测框与真实框的 IoU。

网络结构:24 个卷积加 2 个全连接

输入 448×448×3,整个网络由 24 个卷积层和 2 个全连接层组成。骨架模仿的是 GoogLeNet 而非 VGG——在 3×3 卷积之间大量插入 1×1 卷积做通道压缩,同样的感受野下层数更少、速度更快。空间分辨率靠六次 2×2、步长 2 的最大池化从 448 一路压到 7:

输入 448×448×3
  卷积 7×7、64 通道、步长 2   → 224×224×64    池化 → 112
  卷积 3×3、192               → 112×112×192   池化 → 56
  1×1 与 3×3 交替堆叠,通道 128→256→512       池化 → 28×28×512
  1×1 与 3×3 交替堆叠                         池化 → 14×14×512
  1×1 与 3×3 交替堆叠,通道升至 1024          池化 → 7×7×1024
  连续数层 1024 通道的 3×3 卷积
  展平 → 全连接 4096(Dropout 0.5)→ 全连接 1470
  重排为 7×7×30

两个容易忽略的选择。激活全部用 LeakyReLU(负半轴斜率 0.1):标准 ReLU 把负输入的梯度置零,而 v1 的输出全是回归量,保留一点负半轴的梯度更稳。v1 没有使用批归一化——BN 刚刚提出,论文的消融显示给卷积层加上它能带来约两个点的 mAP,但主线版本没有纳入,这也解释了它对训练技巧的敏感。

最后那层 1470 维的全连接是设计的点睛之处:整张图的所有检测结果,被压成一个长度固定的向量,由一次矩阵乘法直接给出。

30 个数怎么解读

1470 = 7×7×30,每个网格单元 30 个数:

30 = (x, y, w, h, confidence) × 2 个框 + 20 个类别条件概率

怎么读:x、y 是框中心相对所在网格单元的偏移,归一化到 0 到 1;w、h 是相对整张图的宽高;confidence 就是前面定义的”有目标概率乘 IoU”。20 个类别概率每个格子一份、由该格的两个框共享——这就是后面要讲的”一格一类”限制的根源。7×7 个格子合计 98 个候选框。

测试时,把类别条件概率与框置信度相乘,得到每个框在每个类别上的分数;过置信度阈值、做 NMS,就是最终输出。

损失函数的四个细节

损失是全部输出上的平方和误差,但有四个精心设计的地方。

责任框。一个目标只由中心落在的格子负责;格子的两个框里,又只让当前与真实框 IoU 最高的那个承担坐标损失,另一个不学坐标、只学置信度。训练中两个框会逐渐分化出不同的长宽比偏好(一个偏宽一个偏高),变相扩大了单格的表达范围。

坐标加权 λ_coord = 5。30 个输出里坐标只占 10 个,平等对待的话定位会被类别与置信度项淹没,所以坐标项权重放大五倍。

无目标格子的置信度降权到 0.5。49 个格子里绝大多数没有目标,置信度目标是 0;不降权的话,这些容易学对的项会占满梯度,模型会偏向永远预测”没有目标”。

宽高取平方根。平方误差下,同样 10 像素的偏差在大框上无关紧要、在小框上是灾难。对 w、h 取根号再算平方差,同样的绝对偏差在小框上损失更大,等于给小框加权。

成绩与遗留问题

训练流程也值得一记:先在 ImageNet 上以 224×224 的分类任务预训练前 20 个卷积层,再随机初始化其余 4 个卷积层和 2 个全连接层,把输入切到 448×448,在 PASCAL VOC 上训练约 135 个 epoch(batch 64,学习率先升后分三段衰减)。

结果是把检测做到了实时:VOC 2007 上 63.4 mAP、45 FPS;砍掉一半层数的 Fast YOLO 以 52.7 mAP 换 155 FPS。同期 Fast R-CNN 精度 66.9,但一帧约 0.3 秒。更有意思的一个结论是组合:用 YOLO 先扫一遍”背景里可能的漏网目标”再喂给 Fast R-CNN,mAP 涨到 70.7,超过任何一个单模型——YOLO 的漏检模式与两阶段模型不同,恰好构成互补。

短板也很清楚:每个网格单元只预测固定数量的框,一个单元里有多个小目标时必然漏检(一群鸟挤进一格只出两个框);类别概率每格一份,一格只能出一个类别;网格 7×7 粒度太粗,定位精度有限;对长宽比悬殊的目标泛化差。这四条短板,恰好对应了后面几代人的修补方向。

四、v2 与 v3:锚框、多尺度与主干定型

v2(YOLO9000,CVPR 2017)补了 v1 的三个洞。

对长宽比泛化差,答案是锚框:不再直接回归框的绝对位置,而是预设一组先验框,网络只预测相对先验框的偏移和缩放。锚框的形状不是拍脑袋定的——用 k 均值在训练集的真实框上聚类,聚出几个”数据里最常见的形状”作为先验,距离度量用 1 减 IoU(而不是欧氏距离,因为 IoU 才和最终评价标准一致)。这个”用聚类决定锚框”的做法成了 v2 到 v5 的标准流程。

小目标漏检,答案是更高的输入分辨率(448 训练、544 推理)配合更强的主干 Darknet-19,加上批归一化——v1 没有用 BN,加了之后训练稳定性和精度都有明显提升。定位粗,答案是直接位置预测:偏移量过 sigmoid 压到 0 到 1 之间,保证每个框的中心落在自己的网格单元内,收敛比无约束回归稳定得多。

v2 还有一个有名的大动作:用 WordTree 把检测数据集和分类数据集组织成同一个层级,用 COCO 学检测、用 ImageNet 的四千多个分类学类别概念,得到能识别九千多类的 YOLO9000。这条”检测与分类联合”的路线后来没有成为主流,但它是多任务与层级标签的早期认真尝试。

v3(2018,作者以技术报告形式发布,未投会议)做了两件影响深远的事。

一是多尺度预测。借鉴特征金字塔网络(FPN,CVPR 2017)的思想,在主干的三个不同深度各接一个检测头,分别负责大、中、小目标——深层特征语义强、分辨率低,适合大目标;浅层特征细节多,适合小目标。每个尺度配三个锚框,共九个,锚框同样来自对训练集的聚类。小目标漏检这个 v1 遗留问题,从 v3 起才算真正缓解。

二是主干换代。Darknet-53 用残差连接把网络加深到 53 层卷积,论文里的对比显示它的精度与更深的 ResNet 相当而速度更快——原因是没有残差块里那些额外的池化和全连接开销。

还有一个容易被忽略的细节:v3 把类别预测从 softmax 换成了每个类别独立的二元逻辑回归。softmax 隐含”各类别互斥”的假设,而现实里一个目标可以同时是”女人”和”人”,多标签化之后这个假设被去掉了。这个改动很小,方向性很强。

五、v4 与 v5:训练技巧的系统化

到 2020 年,检测社区积累了一大堆零散的训练技巧,散落在各个论文和开源实现里。YOLOv4(2020,预印本)的贡献是把它们整理成体系,并分了类:免费提升(bag of freebies,只改训练、不改推理成本)和微小代价提升(bag of specials,推理成本小幅增加、精度明显上涨)。

免费提升里最出名的是 Mosaic 数据增强:把四张图拼成一张再训练,模型在同一张图里见到更多尺度的目标组合,对”目标扎堆”的鲁棒性明显提高。其余包括 MixUp、HSV 色域扰动、余弦学习率退火、标签平滑等。损失函数上,框回归从 IoU 损失升级到 CIoU 损失(AAAI 2020 的 Distance-IoU 工作)——普通 IoU 损失在两个框不相交时梯度为零,CIoU 把重叠面积、中心点距离、长宽比三项都纳入惩罚,解决了”不相交就没有梯度”的问题。

结构上的变化是主干换成 CSPDarknet53(CSP 结构把特征图分两半、只对一半做卷积再拼接,减少重复梯度信息),颈部用 SPP 空间金字塔池化和 PANet(CVPR 2018)的自底向上再加自顶向下的特征融合。这版把”主干—颈部—头部”的三段式结构定型,之后所有 YOLO 都长这个样子。

v5(Ultralytics,2020,开源项目、无论文)做的事不在算法而在工程:把框架从 Darknet 迁到 PyTorch,提供 n/s/m/l/x 五档模型规模(同一套结构,按宽度和深度缩放),配置全 YAML 化,训练推理一条命令,导出 ONNX/TensorRT 顺畅,锚框自动聚类。它没有论文,却是把 YOLO 从”研究者能训”变成”工程师能用”的一代,生态优势延续至今。

六、YOLOX 到 v8:去锚框与解耦头

2021 年之后,YOLO 系列发生了两个结构性变化,此后成为默认设计。

第一个是去锚框。锚框带来一批超参(数量、形状、每尺度分配),也带来正负样本匹配的复杂度。YOLOX(2021,预印本)取消锚框,每个位置的头部直接预测框的中心和到四边的距离;同时把分类和回归拆成两条并行分支(解耦头)——此前分类和回归共享特征,但这两个任务关注的特征并不相同,解耦后两边都更干净。正样本分配换成 SimOTA:按预测与真实的代价矩阵动态决定每个真实框由哪些位置负责学习,取代固定的 IoU 阈值规则。

第二个是损失函数的离散化。框的回归从直接预测一个连续数,改成预测”到四条边的距离”在若干离散档位上的分布,再用分布的期望作为最终距离(Generalized Focal Loss,NeurIPS 2020 的 Distribution Focal Loss)。直觉是:数据集里框的标注本身有模糊性(边界到底在哪一像素),预测一个分布比预测一个点更贴近真实。

这两项在 v8(Ultralytics,2023,开源项目)里合流并成为默认:anchor-free 的解耦头、DFL 框回归、CIoU 损失、任务对齐分配器(Task-Aligned Assigner,按分类得分与 IoU 的加权挑正样本)。v8 同时把框架扩展成多任务:检测、实例分割、姿态、旋转框(OBB)、分类共用一套结构。它的发布没有论文,但凭借与 v5 同级的易用性,成为目前工业界使用最广的一代。

七、v9 之后:效率优化与免 NMS

2024 年之后,几个方向值得关注,各代表一种思路。

v9(2024,预印本)提出可编程梯度信息(PGI):深层网络训练时梯度经过多层传播会丢失定位所需的信息,PGI 用一个辅助可逆分支保证梯度能带回浅层;配合新的骨干 GELAN,在更少的参数量和计算量下拿到当时的最高精度(论文报告参数量与计算量分别下降约四成,而 AP 反而更高)。

v10(2024,预印本)攻击的是 NMS:推理流程里唯一不是网络的部分就是后处理,而 NMS 的阈值要调、在密集场景下会误删重叠的真目标。v10 用”一致双分配”的训练策略让网络本身学会抑制冗余预测,实现免 NMS 的端到端检测,论文报告在精度持平的情况下端到端延迟明显下降。对部署在边缘设备、后处理逻辑越简单越好的场景,这个方向的价值会越来越大。

v11 与 v12。v11(Ultralytics,2024)换上更高效的特征模块与空间注意力,延续多任务框架;v12(2025,预印本)把主干改成以注意力为中心的设计,把视觉 transformer 里验证过的注意力机制做成了实时可行的版本。它们代表同一种张力:注意力机制的容量更大,但要塞进”实时”的预算里,必须做大量结构裁剪。

还有两条不是 YOLO 编号、但绕不开的线。一是 RT-DETR(CVPR 2024):transformer 检测器(DETR 家族)一直以”免 NMS、端到端集合预测”为卖点,RT-DETR 把它做到了实时,官方标题就是”DETR 在实时检测上超过了 YOLO”。二是 YOLO-World(CVPR 2024):把开放词表检测做到实时——不再限于训练时见过的固定类别,而是文本编码类别名、按嵌入相似度匹配,类别可以运行时更换。这两条线共同指向一个问题:固定类别、闭合集合的检测范式,正在被更强的范式在特定场景下替代。

八、训练流程:从数据到损失

训练一个检测模型的完整流程,比分类多出好几个环节,逐个说。

标注。目标检测需要的是框级标注。COCO 用 JSON 存多边形与框,Pascal VOC 用 XML 每图一文件,YOLO 格式是每图一个同名 txt,每行一个目标:

    
0 0.512 0.343 0.281 0.412

坐标全部按图片宽高归一化到 0 到 1,用的是”中心点加宽高”的表示。标注成本是检测任务最真实的门槛:分类贴标签点一下就行,检测要框;框的质量直接封顶模型上限——框得松,IoU 阈值高的指标永远上不去。

数据增强。检测的增强比分类复杂,因为所有几何变换必须同步作用于框的坐标。翻转、缩放、仿射、HSV 扰动是基础;Mosaic 四图拼接是 YOLO 系的招牌;MixUp 按透明度混合两张图。一个重要的实践细节:Mosaic 在训练的最后若干轮要关闭(close_mosaic),让模型最后阶段见到的是真实分布的数据,否则增强带来的分布偏移会留在最终权重里。

标签分配。这是检测训练里最”玄”也最关键的环节:一个真实框,该由特征图上哪些位置来负责学习它?早期规则是固定的——中心落在哪个网格、与哪个锚框 IoU 最高就算哪个。后来发展成动态分配:按”当前预测的质量”(分类得分乘 IoU)给候选打分,动态挑出每个真实框的最优负责者(SimOTA、TAL 这一族)。直觉是:同一个真实框,让此刻已经学得最像它的位置来学,收敛更快也更稳。

损失。现代 YOLO 的损失由三部分加权求和:框回归损失(CIoU 加 DFL)、分类损失(二元交叉熵)、以及 v5 系独有的目标置信度损失。三者的权重比本身是需要调的超参。

训练节奏。优化器从 SGD 走向 AdamW;学习率经过若干轮 warmup 再衰减;EMA(指数滑动平均)保留一份更平滑的权重用于评估与导出;混合精度训练是标配。批次大小受显存限制,显存不够时用梯度累积凑。

整个流程串起来是:准备图像与标注 → 按上述增强生成训练样本 → 前向得到所有位置的预测 → 分配器决定每个真实框由哪些预测负责 → 按三部分损失回传 → 循环,直到验证集的 mAP 不再上涨。

九、推理流程:从预处理到 NMS

推理是一条固定的流水线,逐站说清楚。

预处理。输入图的宽高比和模型要求的不一致,直接缩放会拉伸目标。标准做法是 letterbox:等比缩放到目标尺寸内,空出的部分填灰。这一步的坐标换算必须在输出端原样还原,任何一处忘了除回缩放系数,框就会整体偏移。

前向。一次前向传播输出所有检测头在所有位置的原始预测:类别分数、框的回归分布。v8 一类 anchor-free 结构,每个位置直接输出四个距离值。

解码与过滤。把回归分布的期望乘回锚框(或加上位置偏移)得到框坐标;置信度低于阈值的预测直接丢弃。阈值是精度与召回的直接旋钮:调高,误检少但漏检多;调低反之。这个阈值应该按业务对两类错误的代价来定,而不是套用默认值。

NMS。同一目标周围的相邻位置会各自输出一个高置信度的框,NMS 负责去掉冗余:按置信度从高到低排序,取最高的框保留,删掉与它 IoU 超过阈值(常用 0.45 到 0.65)的其余框,再在剩下的框里重复这个过程。NMS 的类别处理有两种模式:各类别独立做(默认),或跨类别一起做(同一位置”既是人又是车”时需要)。NMS 的已知缺陷在密集场景:两个真目标高度重叠时,低置信度的那个会被误删。补救办法有 Soft-NMS(ICCV 2019,把”删除”改成按 IoU 衰减置信度,一行代码的改动)和 DIoU-NMS(相邻且中心距离远的两个框更可能是不同目标)。v10 一类免 NMS 设计则直接从训练层面消除这一步。

部署。训练框架和部署框架是两回事。常见路径是导出 ONNX,再转 TensorRT(NVIDIA)、CoreML 或 OpenVINO,中间通常伴随量化(fp16 或 int8)。这里有一个反复被验证的经验:FLOPs 低不等于延迟低。访存量、算子融合程度、硬件对特定结构的支持,都会让参数量相近的两个模型在同一块卡上差出几倍。选型要看部署目标硬件上的实测延迟,不要看论文里的计算量。

十、评估与调优

检测的全部评估指标都从 IoU 生长出来,先一一说清,再说训练工具输出的那些图怎么读,最后回到聚合数的拆读与错误归因。

指标一一说明

IoU(交并比)。预测框与真实框的交集面积除以并集面积,是”命中”的定义基础。它不看类别,只衡量两个框的重合程度。

TP、FP、FN,以及为什么没有 TN。以 IoU 阈值(常用 0.5)加类别一致为命中条件:预测框命中某个真实框、且这个真实框此前没被匹配过,是 TP——一个真实框只能被吃掉一次,第二个预测它的框算 FP;没命中任何真实框的预测是 FP,包括 IoU 不够的、类别错的、以及重复框;没被任何预测命中的真实框是 FN。真负例在检测里不存在:背景”正确地什么都没预测”不产生任何输出,所以检测的评估体系里没有 TN,也没有分类任务那种整体 accuracy。这是检测评估与分类评估在骨架上的差别。

Precision 与 Recall:

$$P = \frac{TP}{TP + FP}, \qquad R = \frac{TP}{TP + FN}$$

前者回答”报出来的框有多少是对的”,后者回答”该找的目标找到了多少”。关键在于它们都是某个置信度阈值下的数:阈值从 0.9 降到 0.1,两个数会从”很少但很准”滑向”很多但很脏”。单点的 P 和 R 意义有限,完整的刻画是把阈值从高到低扫一遍。

P-R 曲线与 AP。把每个阈值下的一对 (R, P) 画成曲线就是 P-R 曲线,曲线下面积是该类别的 AP。COCO 用 101 点插值:在召回轴上取 101 个等距点,每点取其右侧的最大精度再平均,避免曲线锯齿干扰面积。曲线形状本身就是诊断:右上角饱满说明高分段干净;高召回区精度塌得早,说明置信度中段全是误检。

mAP 与两个口径。各类别 AP 的平均是 mAP。mAP@0.5 把 IoU 阈值固定在 0.5(PASCAL VOC 口径),框个大概就算对;mAP@[.5:.95] 从 0.5 到 0.95 每隔 0.05 一档取十档平均(COCO 口径),要求框越来越准。两个数的差值本身是诊断信息:差得越大,说明”能框到但框不准”,短板在定位而不在找。

按目标尺寸拆分。COCO 把目标按面积分成小(小于 32 平方像素)、中、大三档,分别报告 AP_small、AP_medium、AP_large。小目标的 AP 常常只有大目标的一半甚至更低,糊在一个总分里会掩盖这个事实。

AR(平均召回)。限定每张图最多检测 N 个目标(AR@1、AR@10、AR@100)时的平均召回,不惩罚误检。做”候选预筛”类业务(后面还有模型接力)时,AR 比 mAP 更贴近真实需求。

速度三件套:FPS、单帧延迟、吞吐。要分清论文口径和业务口径——论文的 FPS 通常不含前后处理、在旗舰卡上测得;业务该量的是目标硬件上端到端延迟的分布(p50 与 p99)和并发下的吞吐。

F1 与 F1 曲线:

$$F_1 = \frac{2PR}{P + R}$$

精度与召回的调和平均。对每个置信度阈值算一对 (P, R) 与对应的 F1,得到 F1-阈值曲线;峰值对应的阈值就是”使 F1 最大的置信度阈值”,通常直接用作部署默认值。所以 F1 曲线的用途不是给模型排名(那是 mAP 的事),而是给已选定的模型挑部署阈值:业务更怕漏检(安防),阈值往召回高的方向移;更怕误报(自动拦截),阈值往精度高的方向移。

训练输出的图怎么读

主流框架跑完训练和验证会输出一组图,逐张说读法。

results.png(训练曲线)。框回归损失、分类损失、DFL 损失与各项指标随轮数的变化。三个看点:验证损失是否已经平台化(平台了就该早停);验证损失是否掉头向上(过拟合信号);训练损失还在降而验证指标不动,是典型的过拟合或增强过度。

PR_curve.png。每个类别一条 P-R 曲线加汇总的 mAP@0.5。看两处:哪条曲线塌得早(那类在高召回区误检多)、哪条整体贴着右上角(那类基本没问题)。

F1_curve.png。如上,峰值横坐标就是推荐的部署阈值。

confusion_matrix.png 与归一化版。检测版混淆矩阵:把命中(IoU 过阈值且类别一致)的预测按”真实类别 × 预测类别”计数,另加一行一列 background——预测了框但没匹配上任何真实框的进 background 列,真实框没被任何预测命中的进 background 行。读法:对角线是各类命中比例;对角线以外最亮的格子是两类互混的直接证据(比如卡车被认成公交车);background 列亮说明该类误检多,background 行亮说明该类漏检多。归一化版按行除以总数,类别样本量悬殊时只看归一化版。注意它对定位质量是盲的——IoU 过阈值就算对,定位问题要靠 mAP 两个口径的差值暴露。

labels.jpg 与 labels_correlogram.jpg。数据集体检图:各类别的框数(是否平衡)、框中心的位置热图(目标惯常出现在画面哪里)、框宽高的直方图,以及四个量的联合相关图。用途是在训练前发现标注的系统性问题:框总贴着图像边缘(标注习惯或裁切问题)、宽高集中在某几个值(复制粘贴式标注)、某些类样本数只有别类的零头(先补数据再谈调参)。

train_batch 与 val_batch 可视化。前者是增强后的训练样本,肉眼确认增强没有把目标破坏掉;后者是验证集上的预测叠加,快速感受模型”看起来”对不对,再决定是否进入细致的错误分析。

聚合数要拆开读

mAP@[.5:.95] 是主要指标,但它是一个聚合数,会掩盖具体问题。有效的做法是拆开看三组数:按类别拆(哪些类的 AP 低,是标注少了还是类间易混)、按目标尺寸拆(小目标的 AP 通常低一大截,对应增强和分辨率的问题)、按置信度阈值拆(precision-recall 曲线上哪一段塌了)。

错误分析的分类也是固定的三种:漏检(有目标没框出来)、误检(框了不存在的东西)、定位不准(类别对、框的 IoU 不够高)。三种问题对应完全不同的修法:漏检先查标注覆盖和增强强度,误检先查负样本和置信度阈值,定位不准先查小目标占比和输入分辨率。见到 mAP 不涨就盲调超参,不如先花一小时把验证集上的一百条错误人工过一遍——每条错误归进这三类之一,哪类多修哪类。

换到自己的数据上时,预训练模型的迁移是起点:目标类别与 COCO 重合的部分几乎不用教,业务特有的类别(工业件、医学影像里的病灶)需要几百到几千张标注量级才够,且类别间样本数要尽量平衡。类别不平衡时,不是调损失权重就能解决的,采样和增强层面的补足更有效。

十一、做一个目标检测任务的完整步骤

把前文的原理和指标串成一个可执行的项目流程。每一步的关键不是”做什么”,而是”这一步做错会拖垮什么”。

1. 定义任务。写下三件事:类别清单(闭集固定类别,还是会长出新类别);业务上的”命中”标准(IoU 阈值取 0.5 还是更严);漏检与误报哪个代价更高。这三条决定后面所有的阈值与取舍,写下来,不要让它们停留在感觉里。

2. 收集数据。覆盖业务会遇到的全部场景差异:光照、时段、角度、天气、设备、密度。数量级的经验值:每类几百张能到”能用”,几千张能到”好用”,而跨场景泛化的瓶颈往往是场景覆盖不是总张数。另外留 5% 到 10% 的纯负样本(图里没有目标的图),对压误检有直接帮助。

3. 标注。工具用 labelimg、labelme 或 CVAT;格式选 YOLO txt 或 COCO JSON,前者配 YOLO 系训练最省事。比工具更重要的是标注规范:遮挡目标框到可见部分还是整体轮廓、截断目标怎么处理、框要贴多紧——写成文档。多人标注时,规范的一致性比个人手艺重要。标注完抽查一批,框的质量封死模型的上限。

4. 划分数据集。train、val、test 三份,比例常见 8:1:1 或 7:2:1。关键原则是按场景划分而不是按图片划分:同一场景的连拍如果一部分进训练集、一部分进验证集,验证指标会虚高得毫无意义。test 只在整个迭代结束、要出最终数字时才碰。

5. 搭环境与准备配置。安装训练框架(Ultralytics 一条命令装好),把数据整理成目录加 data.yaml(路径、类别数、类别名)。模型规模按部署硬件倒推:边缘设备从 n 档起步,服务器可以 s 或 m。

6. 训练。加载预训练权重,迁移几乎总是划算;先小规模跑通流程再放量。核心参数是轮数、批次、输入尺寸与增强开关,其中输入尺寸对小目标的影响立竿见影。训练时盯 results.png,验证指标平台化即可早停。

7. 评估。看四张图:PR 曲线(哪类弱)、混淆矩阵(谁和谁混、误检漏检的分布)、F1 曲线(部署阈值)、按类别拆的 AP 表。加上 mAP 两个口径的差值,判断定位是不是短板。

8. 错误分析迭代。把验证集上的错误人工过一遍,每条归进三类:漏检、误检、定位不准。修法各不相同:漏检先查场景覆盖与标注,误检先查负样本与阈值,定位不准先查小目标占比与输入尺寸。一次只改一件事,改完用同一份验证集重评,否则无法归因。

9. 测试集终评。迭代收敛后,在从未参与任何决策的 test 上出最终数字,这份报告才是上线依据。

10. 部署。导出 ONNX,转目标硬件的推理格式(TensorRT、CoreML、OpenVINO),按需量化——fp16 的精度损失几乎可忽略,int8 要重新验证。实测部署硬件上的延迟分布;置信度阈值按第 1 步定义的错误代价来定,而不是沿用验证时使 F1 最大的值。

11. 上线与回流。数据分布会漂移:新设备、新季节、新场景都会让线上效果悄悄下滑。建立回流机制,把线上低置信度和人工纠错的样本收集回来,定期重复第 2 到第 8 步。检测模型不是训完就结束的项目,是持续喂养的系统。

十二、怎么选、什么时候不用它

在 YOLO 系内部选型,可以按这几条走:

  • 没有历史包袱的新项目:v8 或 v11 起步。生态最全(训练、评估、导出、多任务一套 API),文档完整,社区答案多
  • 边缘设备、极致延迟:优先考虑 v10 的免 NMS 设计,后处理少一环;模型规模选 nano 档再配合 int8 量化
  • 密集重叠目标(人群、车流):NMS 是主要矛盾,v10 一类免 NMS 方案或 Soft-NMS 变体值得优先验证
  • 需要旋转框(遥感、文档):用支持 OBB 任务的版本,不要自己拿水平框硬拟合
  • 部署环境受限:v5 一代反而是经验上最”皮实”的选择,导出链路最成熟

什么时候不用 YOLO 系:类别不固定(开放词表场景)用 YOLO-World 一类视觉语言检测器;需要目标之间的关系推理(场景理解而非单纯检测)时,transformer 检测器的集合预测更自然;需要像素级轮廓时检测本身不够,要接实例分割。

十三、常见误解

“YOLO 只能检测大目标。” v3 的多尺度预测专门为此设计,小目标检测从那时起就是标配能力。真正的短板在极小目标(几十像素以下),这受限于输入分辨率,任何检测器都一样——把输入开大比换模型有效。

“mAP 高就是检测得好。” mAP@[.5:.95] 与 mAP@0.5 可能差出二十个点,前者要求的框精确得多。业务上”框个大概就行”的场景看 mAP@0.5 即可,但拿 mAP@0.5 的模型去做需要精确边界的任务(测量、抠图)会失望。

“FLOPs 低就一定快。” 计算量是理论值,延迟由访存、算子、硬件共同决定。同一代模型在不同硬件上的速度排序可能完全不同,部署目标上的实测才是唯一可信的数字。

“anchor-free 就没有先验了。” 去掉的是显式的锚框超参,但框的表示方式(到四边的距离)、正样本分配的规则,都是另一种形式的先验。结构变简单是真的,”没有假设”是假的。

“NMS 阈值随便设。” 它直接决定密集场景下的误删率。人群、交通这类目标重叠频繁的业务,NMS 阈值和变体是必须单独验证的项。

“训练集标注越满越好。” 框的质量比数量重要——边界框松散的数据集,训练出的模型在 IoU 阈值严格的指标上永远上不去。宁可选一批框得准的数据,也不要一批框得糙的数据。

参考

  • 1506.02640 — You Only Look Once: Unified, Real-Time Object Detection — CVPR 2016(CCF-A)
  • 1612.08242 — YOLO9000: Better, Faster, Stronger — CVPR 2017(CCF-A)
  • 1804.02767 — YOLOv3: An Incremental Improvement — 预印本 2018
  • 2004.10934 — YOLOv4: Optimal Speed and Accuracy of Object Detection — 预印本 2020
  • Ultralytics YOLOv5 — 开源项目,无论文
  • 2107.08430 — YOLOX: Exceeding YOLO Series in 2021 — 预印本 2021
  • 2209.02976 — YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications — 预印本 2022
  • 2207.02696 — YOLOv7: Trainable Bag-of-Freebies Sets New State-of-the-Art for Real-Time Object Detectors — CVPR 2023(CCF-A)
  • Ultralytics YOLOv8 与 YOLO11 — 开源项目,无论文
  • 2402.13616 — YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information — 预印本 2024
  • 2405.14458 — YOLOv10: Real-Time End-to-End Object Detection — 预印本 2024
  • 2502.12524 — YOLOv12: Attention-Centric Real-Time Object Detectors — 预印本 2025
  • 1506.01497 — Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks — NeurIPS 2015(CCF-A)
  • 1708.02002 — Focal Loss for Dense Object Detection(RetinaNet)— ICCV 2017(CCF-A)
  • 1512.02325 — SSD: Single Shot MultiBox Detector — ECCV 2016
  • 1612.03144 — Feature Pyramid Networks for Object Detection — CVPR 2017(CCF-A)
  • 1911.11929 — CSPNet: A New Backbone that can Enhance Learning Capability of CNN — CVPR Workshops 2020
  • 1803.01534 — Path Aggregation Network for Instance Segmentation — CVPR 2018(CCF-A)
  • 1406.4729 — Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition — ECCV 2014
  • 1902.09630 — Generalized Intersection over Union: A Metric and a Loss — CVPR 2019(CCF-A)
  • 1911.08287 — Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression(DIoU 与 CIoU)— AAAI 2020(CCF-A)
  • 2006.04388 — Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Prediction — NeurIPS 2020(CCF-A)
  • 1405.0312 — Microsoft COCO: Common Objects in Context — ECCV 2014
  • 1704.04503 — Soft-NMS — Improving Object Detection with One Line of Code — ICCV 2019(CCF-A)
  • 2401.17270 — YOLO-World: Real-Time Open-Vocabulary Object Detection — CVPR 2024(CCF-A)
  • 2304.08069 — DETRs Beat YOLOs on Real-time Object Detection(RT-DETR)— CVPR 2024(CCF-A)

文章作者: Halensea
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Halensea !
 上一篇
YOLOv8 实战:环境、数据、训练与部署 YOLOv8 实战:环境、数据、训练与部署
从一个空环境开始:装依赖、跑通第一次推理、标注自己的数据、训练、读懂训练产物、导出部署——每一步给命令、预期输出和踩坑提示,全程不需要先懂检测原理
2026-10-24
下一篇 
向量存储 向量存储
向量存储不只是"存向量"——它要在一个不能同时满足召回、延迟、内存的三角里做取舍,还要把标量过滤、增删改、权限和一致性一并解决。索引结构决定了前一半,工程能力决定了后一半
2026-10-20
  目录