ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

目标检测模型训练全流程:数据准备、参数配置与调优实践

目标检测模型训练全流程:数据准备、参数配置与调优实践

搞目标检测模型训练这件事,说难不难,说简单也不简单。模型本身早就不是瓶颈了,真正决定你训练出来的东西能不能用的,是数据怎么准备、环境怎么搭、超参怎么设,还有训练过程中你能不能看懂那些日志和曲线。这篇博文我就围绕“训练目标检测模型”这件事,从数据准备讲到环境搭建,从模型选型讲到训练参数,再讲到怎么分析结果和排查问题,把一条完整的实操路线串起来。适合刚入门不久想做目标检测项目的人,也适合已经跑通但总觉得训练效果不稳定的朋友参考。

1. 关于数据准备与标注:目标检测的地基工程

1.1 数据采集与标注质量标准

很多人拿到目标检测任务,第一反应是去下载公开数据集。这当然是一条捷径,但真的做项目时你很快会发现,一套完整可用的数据集,往往需要自己动手采集和标注。这里想先强调一个观点:目标检测模型训练,数据质量的重要性排在模型结构前面。同样的模型,在干净的数据上能跑到 mAP 80,在脏乱差的数据上可能只有 50。

标准是要明确对象如何定义。比如你要检测“裂缝”,那么裂缝的最小长度是多少?宽度达到多少像素算裂缝?模糊到看不清的是不是也算?这些问题如果不在标注规范里写清楚,两个标注员会对同一张图给出完全不同的意见。常规做法是先做一个标注说明文档,里面放 10 到 20 个典型样例图片,把正样本、难样本、边界样本都框出来。标注员照着样例干活,效果会稳定很多。

数据集划分也值得讲究。我见过不少人直接把图片按 8:1:1 随机切分,结果验证集里出现的物体分布和训练集差异很大,最后模型评估结果忽高忽低。更稳妥的做法是按场景来划分,保证同一个场景的视频帧或连续采集的图片不要同时出现在训练集和验证集。不然连续帧的内容几乎一样,验证集等于变相“背题”,评估出来的分数虚高,上线就露馅。

1.2 选择合适的标注工具

标注工具选择上,常用的是图形化标注工具,支持矩形框、多边形、关键点等多种方式。实际项目中我会优先看两个指标:一是快捷键方便不方便,二是导出格式丰富不丰富。

如果只是做一次性的几百张图片标注,随便找一款轻量工具就行。如果要长期迭代、多人协作,那就值得用带管理后台的工具或者自己搭一套标注系统。团队标注需要关注的一个坑是漏标和错标。人工作业时间一长,注意力必定下降,局部小目标很容易被漏掉。检测模型对漏标的惩罚很大——漏标的那些框会变成“假背景”,模型会误以为这里不应该出现物体,训练时会主动抑制这个位置的预测,属于积累负面信号。有条件的话,每一批标注完成之后都要做一轮抽检,挑 10% 左右的图让另一个标注员重新标一遍,计算一致率。一致率低于 90% 就要返回重做。

1.3 数据格式规范化与“底图”检查

标注完成后的数据格式也值得多花一点时间统一。常见的目标检测数据格式有 COCO 的 JSON、Pascal VOC 的 XML,以及 YOLO 系的 TXT 格式。很多开源训练仓库只认其中一种,或者需要做格式转换。这个转换环节看似简单,但稍不小心就把类别 id 搞错。比如 VOC 的类别索引从 0 开始,COCO 的类别 id 有时有跳号,直接转换容易让模型学到混乱的标签。

这里分享一个我的习惯:不管原始标注是什么格式,我都会先转成 COCO JSON,因为 COCO 格式对类别、图片尺寸、标注信息的描述比较完整,后续转其他格式也方便。转完之后写一个数据校验脚本,自动检查每张图、每个框的基本情况:

  • 标注框超出图片边界(宽度或高度为负数的情况)
  • 框的面积太小(例如小于 2x2 像素)
  • 类别 id 超出类别列表范围
  • 图片文件缺失或格式损坏
  • 数据集中类别严重不平衡

这些检查可以提前筛掉很多训练时才暴露的问题。这些在训练过程里会造成很大的麻烦:面积过小的框会贡献噪声梯度,超出边界的框会得到负值坐标,直接影响损失计算。

2. 环境、硬件与模型选型:训练目标检测模型的预算与武器选择

2.1 显卡需求与训练速度估算

训练目标检测模型,硬件方面最关键的还是显卡。显存大小决定了你能用的 batch size 和输入分辨率,算力则决定了训练时间。很多人关心“显卡能不能跑”,先明确一点:所有显卡都能训练,只是快慢和上限问题。

以常见的检测模型为例,如果你用的是 YOLOv8s 这类轻量模型,输入尺寸 640,batch size 16,显存占用大约在 8 到 12 GB 之间。如果是 YOLOv8m 或者更大体量的模型,显存需求会涨到 16 GB 甚至更多。如果显存不够,有几种补救办法:降低输入分辨率、减小 batch size、开启梯度累积。梯度累积是把多个小 batch 的梯度攒起来一次性更新,效果近似于大 batch,但训练速度会慢一些。

还有一个经验值可以帮你预估训练时间。单张中高端显卡训练一张 640x640 的图片,包含 80 个类别的 COCO 预训练模型微调,大约每 10 万个样本需要 1 到 2 小时。如果你有 1 万张图,每张图上平均有 3 个目标,训练 100 个 epoch,大概就是 30 到 60 小时。这个估算不考虑验证和测试开销,实际只会更长。有 N 张卡并行,理想情况下时间能除以 N,但数据加载和通信同步会吃掉一部分加速比,多卡加速通常达不到线性。

2.2 模型架构选型逻辑

模型选型是很多人纠结的一步,其实只要想清楚两个问题:业务场景需要多快、精度要求有多高。

如果检测对象是视频流或实时摄像头画面,速度要求通常在 30 FPS 以上,轻量级实时检测系列是首选。这类模型把检测头设计得比较精简,骨干网络也偏小,单张中高端卡上可以跑到 100 FPS 以上。如果任务是扫描文档、分析卫星遥感图这种不要求实时的场景,那就可以牺牲一些速度换取精度,用两阶段检测器或者带注意力机制的高级检测器,它们在密集小目标场景下表现更好。

我自己的选型经验是:先跑一个中等体量的模型作为 baseline,等数据、训练流程都稳定了之后,再考虑换更轻量或者更重的模型。不要一上来就挑战超大模型,调试复杂度会翻倍。看看你的显存:如果显存低于 8 GB,尽量用轻量体量;如果显存在 16 GB 以上,中等体量或者更高精度模型都能跑;如果显存有 24 GB 甚至更多,那基本可以放开挑了。

2.3 预训练权重的取舍

训练目标检测模型时,用不用预训练权重对最终效果影响巨大。目标检测模型通常以图像分类任务上训练好的骨干网络作为起点,例如在 ImageNet 上预训练过的 ResNet 或 CSPDarkNet。采用预训练权重的意义在于,骨干网络已经学会了通用的边缘、纹理、形状特征,后面的检测头只需要在标注数据上学习“在哪、是什么”,收敛快且效果好。从零开始训练骨干网络,不仅耗时,而且在小数据集上很难收敛到理想精度。

实际使用中要注意预训练权重和模型结构的严格对应。你下载的权重文件里每个层的名称必须和当前模型定义完全对上。不同仓库的预训练权重归一化方式可能不一样,或者输入尺寸不同,直接加载容易报错或者精度崩塌。正确做法是下载官方发布的预训练权重,并且用一个很小的测试脚本先跑一次推理,确认输出是合理的结果,再正式开始训练。

3. 关键训练参数配置:写进配置文件之前要想清楚的那些事

3.1 epoch、batch size 与学习率的关系

目标检测训练中,epoch、batch size 和学习率是必须一起考虑的三个参数。很多人把 epoch 理解成“训练多少轮”,但实际上 epoch 决定了模型看到数据的次数。太少会欠拟合,太多会过拟合。常规经验是检测模型至少训练 100 到 300 个 epoch。如果你的数据量很小(几百张图),建议先做数据增强,再把 epoch 调高一些,同时配合早停机制,避免后期过拟合。

batch size 直接影响梯度估计的稳定性。batch 越大,梯度方向越稳定,训练越平滑,但显存占用也越大。这里有个经验公式:当 batch size 翻倍时,学习率也应该适当放大,否则梯度更新步长相对变小,收敛变慢。但学习率不能无限制放大,过大容易在损失曲面里来回震荡。我通常的做法是先在 batch size 16 的情况下设初始学习率 0.01,然后按 batch size 的比例折算。开启混合精度训练后,显存占用会明显下降,可以用更大的 batch,这也是目前训练的标配操作。

3.2 数据增强:目标检测训练的三餐与补剂

数据增强是目标检测训练里性价比最高的模块,尤其当标注数据有限的时候。增强的意义不是简单地把图片翻转一下,而是让模型对真实场景中的光照变化、遮挡、形变、尺度变化具备鲁棒性。

常用的检测增强手段包括水平翻转、随机裁剪、平移、缩放、色彩抖动、HSV 变换等。更强力的增强方式是拼接类方法,例如把 4 张训练图片拼接成一张大图,让模型学会在更复杂的背景下检测小目标,同时相当于扩大了 batch 的有效规模。还有混合增强,把两张图的像素和标签融合起来,让模型学习对遮挡和重叠目标的回归能力。

数据增强要不要全开?不是。增强过猛会让模型看不到原始数据的真实分布,训练集和验证集表现出现严重割裂。我见过一个项目,训练时用了很强的拼接和旋转增强,模型在训练上损失降得很漂亮,但验证集分数一路走低。原因就是验证集是未增强的自然图片,而训练集已经被增强到“面目全非”。比较好的做法是:初期用基础增强(翻转、色彩抖动),让模型快速稳定下来,训练中期再逐步叠加更激进的拼接、混合类增强,并且随时对比验证集的表现变化。

3.3 冻结训练与解冻:小数据集上的关键技巧

如果你只有少量标注数据,又打算用预训练权重微调,建议先冻结骨干网络,只训练检测头。骨干网络负责提取通用特征,这些特征在大规模数据集上已经学得很好了,在你的小数据集上强行微调反而会破坏这些通用表示。检测头则是随机初始化的,需要从你的数据里学习如何定位和分类,所以先让检测头快速收敛。

冻结训练一般跑 5 到 20 个 epoch,视数据集大小和你的耐心而定。等检测头的损失降下来了,再解冻骨干网络,用一个较小的学习率做全网络微调。因为此时检测头已经初步收敛,骨干网络只需要做小的调整来适配目标任务,学习率设置太大会把之前预训练学到的特征冲掉。这个“先冻结后微调”的策略,在小样本训练里能明显提升最终精度。

3.4 学习率调度、EMA 与混合精度

除了初始学习率,学习率调度策略对检测模型训练也有明显影响。最常用的方式是余弦退火:训练前半段学习率保持较高,后半段按余弦曲线慢慢降到接近 0,让模型在后期做精细的收敛。这种方式比固定学习率效果更好,也减少了手动调整学习率的次数。还有 warmup 阶段,尤其在大 batch 训练时,直接用很大的学习率起步会让模型早期产生震荡,所以前几个 epoch 学习率从很小的值线性升到目标值。

EMA(指数移动平均)是另一个容易被忽略的实用技巧。训练过程中维护一组模型参数的滑动平均版本,训练结束时用这个平均版本做推理,往往比直接用最后一轮权重更稳定,泛化性也更好。很多检测框架已经内置了 EMA 策略,但默认开启与否因版本而异,如果你发现训练后期验证分数不稳定,检查一下 EMA 有没有开启。

混合精度训练就是用半精度浮点数做前向和反向计算,用单精度保存参数和累积梯度。显存能省下近一半,训练速度也会提升不少。只要显存是限制条件,我基本都会开启混合精度。只是半精度下部分数值容易溢出,所以框架会自动做动态损失缩放,通常不需要你手动干预。

4. 训练流程实操:从命令行到损失曲线的完整复盘

4.1 配置一个可跑的训练任务

以目前社区最常用的目标检测训练仓库为例,一个标准的训练配置会包含以下内容:模型名称、数据集路径、类别数量、输入尺寸、batch size、初始学习率、训练轮数、增强策略、权重保存间隔、EMA 开关等。配置文件通常使用 YAML 格式,方便修改和复用。

实际执行训练时,核心命令长这样:

python train.py --data datasets/coco.yaml --model yolov8s.pt --epochs 200 --batch 16 --imgsz 640 --device 0

这里的参数含义也很直接:--data指向数据配置文件,里面写清楚了训练集、验证集路径、类别名称和映射关系;--model可以是预训练权重路径,也可以是模型结构定义文件;--imgsz是输入分辨率,越高对小目标越友好,但显存和速度代价也越大;--device指定用哪张卡,多卡时写0,1,2,3即可。

我一般会额外配置一个运行日志目录,把训练日志、TensorBoard 事件和权重备份都统一存放。训练开始之后先观察前 100 个 iteration 的损失有没有合理下降,如果损失纹丝不动甚至上升,那十有八九是数据路径写错、标签错位或者学习率过大,早点发现能省下大量等待时间。

4.2 理解训练日志和损失曲线的关键信息

训练过程会周期性打印一行日志,里面包含当前 epoch、iteration、各种损失分量、学习率、当前 batch 的 loss 值。很多人只盯着总 loss 看,我建议拆开看各个损失分量。检测模型的损失通常由分类损失、目标置信度损失、边界框回归损失三部分组成,分别对应“分类对不对”“有没有目标”“框得准不准”。如果某个分量一直不降,问题定位会更精确。

例如分类损失偏高但边界框损失已经达到稳定,可能说明特征提取阶段对某些易混淆类别的区分能力不足,可以考虑增加难负样本挖掘或者调整类别权重。如果边界框损失始终降不下来,检查一下标注质量——是不是很多框本身就画歪了,模型再怎么学也无法拟合错误的标注。看损失曲线还有一个基本准则:训练集损失和验证集损失要结合起来看。两者都在降,说明健康;训练损失降而验证损失不降或回升,就是过拟合信号,需要增强正则化或提前停止。

4.3 训练中途的常见策略调整

训练不是一条命令丢进去就等着收结果的,中途往往需要介入。最典型的情况是损失陷入平台期,比如训练 60 个 epoch 后训练损失和验证损失都停在某个水平不动了。这种时候可以尝试手动调整学习率,让它变成一个更小的值,通常会带来一轮明显的下降。很多训练仓库支持在配置文件里设置学习率调整策略,也支持从断点加载权重接着训练,所以中途调整不影响正常工作流。

训练中断也不可怕。因为正常的训练流程每个 epoch 都会保存权重,加载最近的一个 checkpoint 重新启动即可。唯一要注意的是,如果修改了配置参数,可能会和 checkpoint 里的记录不一致。稳妥做法是只修改你想调整的参数(例如学习率),其他保持和 checkpoint 训练时一致,否则会出现状态错乱。

有时间建议多看几个训练中间产物。训练到一半阶段,可以挑几张验证集图片跑一次推理,把检测结果可视化出来,看看框的位置、置信度、分类是否合理。这是最直接的反馈,比单看曲线更可靠。早期如果发现类别错乱严重,很可能是标签映射出了问题,这时候停下来修正比继续训练划算得多。

5. 评估模型效果:训练完成之后的工作才是真正的开始

5.1 指标怎么读:mAP、mAP@0.5 与 mAP@0.5:0.95

训练完成后,最关心的是模型到底准不准。目标检测领域最常用的指标是 mAP(mean Average Precision)。mAP 的计算逻辑可以这样理解:把模型对所有检测框的置信度从高到低排序,逐个统计召回率和精确率,画出 PR 曲线,曲线下的面积就是 AP,所有类别取平均就得到 mAP。

有一个容易让新手困惑的地方是,mAP 后面通常还跟着一个 IoU 阈值。mAP@0.5 表示当预测框和真实框的交并比达到 0.5 即算作命中,这是比较宽松的标准;mAP@0.5:0.95 则是在 0.5 到 0.95 之间每隔 0.05 取一个阈值再求平均,标准严格得多。同一个模型的两个值可能差很多,例如 mAP@0.5 到了 0.92,但 mAP@0.5:0.95 只有 0.65。后者对框的定位精度要求更高,如果你的业务场景对定位精度要求苛刻,那应该更关注 mAP@0.5:0.95,不能只看 mAP@0.5 这个“面子上好看”的指标。

5.2 混淆矩阵与小目标问题

评估阶段真正有价值的产出往往不是那个综合得分,而是逐类别的分析报告。混淆矩阵可以看到哪些类别经常被互相搞混,比如行人和路标之间、猫和狗之间。如果混淆集中出现在某些相似类别上,可以考虑补充更多这类易混淆样本,或者给容易混淆的类别增加类别权重。检测框的尺寸也会影响精度分布,大部分检测模型在中等和大目标上表现良好,但在小目标(例如小于 32x32 像素)上漏检率明显上升。这类问题的改善通常需要提高输入分辨率、增加浅层特征图或利用多尺度训练策略。

5.3 导出与部署的注意点

训练、验证都满意之后,模型还要导出成部署格式。常见的部署方式是把模型导出为标准化的轻量推理格式,部署到服务端或边缘设备。这个环节常见的坑是训练框架的增强和预处理逻辑与部署端不一致。训练时的预处理包括缩放、填充、归一化,如果部署端换个推理库,预处理不完全一致,同样的图片进到模型里就会得到不同的结果,精度直接掉一截。

所以导出后一定要做“端到端对比测试”:同一张图,训练框架推理一次,部署环境推理一次,对比输出框的坐标和置信度偏差。坐标偏差在可接受范围内,才算导出成功。另外一个部署阶段的常见问题是类别索引错位。训练时的类别顺序和部署端配置文件里的类别顺序如果不一致,模型检测出类别 0 时,客户端可能展示成完全不同的标签。这种错误非常隐蔽,因为整体流程都能跑通,只有仔细对比才会发现。

6. 训练过程中的典型问题与排查心得

6.1 常见故障速查表

我把训练目标检测模型过程中最常见的问题整理成一张表格,方便大家在遇到异常时快速对照。

问题现象可能原因解决建议
训练刚开始 loss 就很高且波动剧烈学习率过大、标签错位、数据路径错误调低学习率,检查标签映射和图像显示是否正常
loss 持续下降但验证 mAP 停滞增强过强导致训练分布和验证分布偏移减弱增强强度,核对验证集划分是否合理
训练集 loss 降了但验证集掉点过拟合增加数据量,加强增强,开启更强的正则化,或者用 EMA
小目标频繁漏检输入尺寸太小、特征图分辨率不足提高输入分辨率,使用高分辨率分支的检测头,增加小目标增强
显存不足batch 太大、输入尺寸太大调低 batch、减小尺寸、开启梯度累积或混合精度
某一类 AP 明显低于其他类该类样本过少或标注质量差补充该类样本或用类别重采样
模型推理速度达不到要求模型过大、硬件算力不足、预处理耗时切换轻量模型、量化部署、优化预处理流程

6.2 标注噪声:最隐蔽的性能杀手

训练完发现 mAP 不理想,先别急着换模型结构,优先怀疑训练数据。目标检测对标注噪声非常敏感,尤其是边界框框偏了半个目标、类别标错、漏标这些情况。框偏了会导致回归损失学到错误的信息,类别标错则会让分类分支产生矛盾梯度。我自己排查性能问题时,标准动作是随机挑 200 张训练图,把标注框可视化叠到图片上逐张看一遍。这个过程很枯燥,但常常能直接看出问题。比如某类别的框总是偏大或偏小,某些小目标漏标严重,或者某些图与任务根本无关。

还有一个验证标注质量的办法:用训练好的模型去对训练集本身做一次预测,把“模型预测不到”或者“模型预测置信度极低”的标注框挑出来看。模型对某个区域不响应,通常代表那个位置的视觉特征被同类负样本干扰过,提示对应标注可能有问题。

6.3 类别不平衡的应对策略

现实项目很少有完美的类别均衡。一个检测两类物体的模型,A 类可能有 5 万个框,B 类只有 800 个框,这种情况下 B 类的 AP 通常惨不忍睹。缓解办法有几类:最简单的是对每张图做类别重采样,保证每个 batch 里都能采到 B 类样本;更精细的是给少数类分配更高的分类损失权重;数据增强阶段专门针对少数类的框做裁剪拼接,提高少数类在训练样本中的出现频率。

但这些办法各有代价。重采样会让某些拥有大量标注的图片重复出现,增加过拟合风险;损失权重过大可能会让模型对少数类过度敏感,误检率上升。稳妥策略是先用基础训练跑一版 baseline,看看各类别 AP 差距有多大,再决定要不要上这些特殊手段。

一些最后想说的经验

练目标检测模型,模型结构只是最后的 10%,前面 90% 都是在跟数据和参数较劲。我把这个项目的经验浓缩成几条:第一,标注质量再怎么强调都不过分,花在数据校验上的时间永远值得;第二,训练时不要只看总损失,要拆成分量看,还要把验证集可视化结果纳入监控;第三,遇到效果不理想,优先排查数据和预处理,而不是急着换更复杂的模型;第四,训练流程要可复现,配置文件、代码版本、随机种子缺一不可。先把这几条做到位,你训练出来的模型大概率不会太差。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进