2026/10/26 13:45:06

YOLO自建数据集目标检测:数据标注、训练推理与排错全流程

YOLO自建数据集目标检测:数据标注、训练推理与排错全流程 上周有位做工业质检的朋友抱着一台笔记本找我说他照着网上教程把自己的数据集喂给 YOLO 目标检测模型训练日志里的损失确实在往下掉可一跑预测检测框要么飘在背景上要么整张图一个目标都框不出来折腾了三天没找到原因。我看了他的数据目录和标签文件问题其实很朴素标签里存的是像素坐标而不是归一化坐标验证集还和训练集来自同一段视频的相邻帧。这两个问题凑在一起指标看着漂亮模型实际上什么也没学会。这类事情我见过太多次了所以想把自己用 YOLO 在自己的数据集上做目标检测的完整流程摊开写一遍——从数据采集、标注规范、配置文件的写法到训练参数怎么定、预测阈值怎么调、指标怎么读、出了问题怎么排查。这篇内容面向的是手上已经有一批自己拍的或者业务里攒下来的图片、想把它们变成能用的检测模型的人。你不需要精通深度学习但最好跑过一次公开数据集的 demo知道训练和推理大概是什么节奏。我会把每一步背后的“为什么”说清楚参数取值尽量给出计算依据也会把那些文档里不会写、只有真跑过一遍才会知道的小坑单独拎出来讲。读完你应该能独立完成一次从原始图片到可用权重的完整闭环并且在效果不理想时知道该往哪个方向调。1. 先想清楚用自己的数据跑 YOLO 到底难在哪1.1 公开数据集能跑通不代表你的数据能跑通很多人第一次接触目标检测是在公开数据集上跑官方示例几条命令下去就能在验证集上看到不错的精度于是形成一种错觉这套流程换个数据集照样能用。实际上公开数据集之所以“好训”是因为它经过大量人工筛选和清洗类别均衡、标注规范、图像质量稳定甚至连光照分布都相对集中。而你自己采集的数据往往是几十段视频里截出来的帧重复度极高前景背景比例严重失调个别类别可能只有二三十个样本标注还出自不同人之手标准不统一。我一般的判断是在一个全新的自建数据集上数据准备的工作量占比能到六成以上训练和调参加起来不到三成剩下的是推理验证和部署适配。这个比例听起来夸张但只要你在标注上偷过懒就一定会同意。举个具体例子同样是“螺丝”这个类别有人把整个螺丝头框进去有人只框螺帽还有人把旁边带阴影的部分也圈进来。模型学到的是框的尺寸分布标注尺寸方差这么大它只能学出一个折中的、谁都不准的框。所以第一件要建立的心理预期是这不是一个“调参问题”而是一个“工程问题”。模型结构和超参数在很大程度上已经被开源实现调好了你真正能拉开差距的地方是数据质量、类别设计、划分策略以及对训练曲线的判读能力。1.2 版本选型不同代际的 YOLO 该怎么挑YOLO 这条线迭代了很多代从早期的 anchor-based 到后来的 anchor-free从纯卷积到引入注意力模块每一代都有自己的性格。选型的时候我不太看论文里的精度榜单而是看三件事你的硬件能承载多大的输入分辨率、你需不需要导出到特定推理后端、你手上有没有靠谱的预训练权重。近几代的主流实现工程完备度都比较高配置文件、训练脚本、导出脚本、验证脚本是一整套的命令行接口也统一用起来省心。老一些的版本比如 v5 那一代优势是生态成熟、社区里能搜到的现成答案多改网络结构的人也多缺点是有些设计在新硬件上不是最优。新版本v8 之后默认 anchor-free配置更简洁导出链路更顺对小目标的默认处理也更好一些。我自己的取舍逻辑是这样的如果只是想做一次验证性的实验看看自己的数据能不能训出东西来用最新一代的主流实现默认配置直接跑省掉大量摸索时间。如果最终要落到边缘设备上且算力非常紧张可以先在新版本上训出效果再考虑用更小的模型尺寸n/s 级别重训或者做量化。如果团队里已经有一套基于老版本 v5 的流水线在跑别急着换迁移成本往往比收益高除非你确实卡在某个老版本解决不了的问题上。还有一个容易被忽略的点模型尺寸的选择比版本选择更影响最终体验。n 到 x 这几档参数量差了一到两个数量级在同样的数据上大模型精度高但推理慢、显存吃紧、小数据集上还容易过拟合。我的经验是自建数据集样本量在两三千张以内时用 s 或者 m 就够了上 l/x 大概率是浪费算力还会因为过拟合导致验证指标反而更差。1.3 硬件与时间预算的现实估算训练目标检测模型对显存的要求本质上是输入分辨率、批大小和模型规模的乘积关系。以 640 输入、s 尺寸模型为例批大小 16 在 8GB 显存的卡上基本能跑起来如果开混合精度AMP还能再往上加一点换成 l 尺寸同样的批大小大概要 16GB 起步。这个数量级关系心里要有个数不然一上来就把 batch 设成 64第一轮就 OOM白等半小时。时间预算方面一个 2000 张图、10 个类别的数据集在单张消费级显卡上s 模型训 100 轮到 150 轮大概需要几个小时。这个时间不算长所以我的建议是先小规模试跑抽 200 张图训 30 轮把整条链路数据读取、标签解析、损失下降、验证指标输出、权重保存、推理出图全部走通一遍。这一步能提前暴露 80% 的配置错误比训到第 90 轮才发现标签路径写错要划算得多。提示试跑阶段一定要真的去看推理出来的图不要只看指标。指标正常但预测框诡异的情况非常常见肉眼过一遍图能省下大量排查时间。2. 数据准备决定模型上限的一步2.1 采集与清洗把“能拍到的”变成“能训的”采集环节最常见的错误是“越多越好”的思维。有人拍了两万张图结果全是在同一个工位、同一个光照、同一个角度下拍的模型在这批数据上精度极高换个场景立刻崩。目标检测模型学到的是纹理和形状的统计规律如果你的数据里背景几乎是常量模型很容易退化成“靠背景认类别”。我的做法是刻意制造多样性同一类目标至少覆盖三种以上的光照条件顺光、逆光、室内灯光、三种以上的拍摄距离、三种以上的角度以及遮挡程度不同的样本。数量上不必追求极致一个类别有 300 到 500 个有效实例通常就能训出可用的效果低于 100 个实例模型对这个类别的召回会很不稳定。清洗比采集更费神。视频抽帧得到的数据相邻帧之间差异极小直接全量入训会导致严重的冗余。我一般按场景分段每段视频按固定间隔抽帧比如每 15 帧取一帧保证同一条流水线上不会出现几十张几乎一样的图。另外要主动剔除模糊、过曝、欠曝、严重遮挡到看不出类别的图——这些图留着不但没用还会污染损失。还有一个技巧值得说负样本只含背景、不含任何目标的图要保留一部分大概占总量的 5% 到 10%。负样本能显著降低模型在空场景上的误检率。很多人只截有目标的图结果模型在纯背景图上也要框出点什么置信度还挺高这就是缺少负样本训练的直接后果。2.2 标注规范与类别设计标注是整条链路里最容易出问题、也最难返工的环节。先说格式YOLO 系列用的是 txt 标签文件每行一个目标格式是“类别编号 中心点 x 中心点 y 宽 高”后四个值必须是相对图像宽高归一化到 0 到 1 之间的小数。我那位朋友的坑就在这里——他用的工具导出的是像素坐标直接喂进去模型看到的框位置全在图外自然什么都学不到。类别设计上有几条硬经验。第一类别编号必须从 0 开始、连续、不跳号并且和配置文件里 names 列表的顺序严格对应。中间空一个号或者顺序写反模型会把 A 类学成 B 类而且指标看起来还挺正常极难发现。第二能合并的类别尽量合并比如“大螺丝”和“小螺丝”如果你的业务只要检出螺丝就不要拆成两类拆分只会让每类的样本变少、混淆矩阵变难堪。第三对于边界模糊的类别提前定好判定规则并写进标注文档比如“遮挡超过 50% 不标”“目标宽度小于 8 像素不标”规则定得越具体多人标注的一致性越高。标注完成后务必做一次可视化抽查。写个小脚本把标签画回原图上随机抽二三十张看重点看三件事框是否贴合目标、有没有漏标、类别有没有标错。这一步花二十分钟能避免后面几小时的无效训练。我见过最离谱的一次是某批数据的标签和图片序号整体错位了一位画出来框全在错误的位置上肉眼一看就发现了但如果不看训出来的模型会表现出一种“知道有东西但位置永远偏一点”的诡异状态。2.3 数据集目录结构与配置文件目录结构这块主流实现基本统一一个 images 目录放原图一个 labels 目录放同名 txt各自再分 train 和 val 子目录。注意图片和标签必须同名只是扩展名不同并且目录层级镜像对应。一个可直接抄的结构如下dataset/ ├── images/ │ ├── train/ │ │ ├── 0001.jpg │ │ └── 0002.jpg │ └── val/ │ ├── 0101.jpg │ └── 0102.jpg └── labels/ ├── train/ │ ├── 0001.txt │ └── 0002.txt └── val/ ├── 0101.txt └── 0102.txt配置文件是一个 yaml几个主流版本写法略有差异但核心字段一致path: /data/dataset # 数据集根目录建议写绝对路径 train: images/train val: images/val nc: 3 # 类别数量 names: 0: screw 1: washer 2: defect这里有几个细节值得强调。path 建议写绝对路径相对路径在不同工作目录下跑行为不一致很容易出现“跑得起来但读不到图”的情况。路径里尽量不要有中文和空格这块在某些系统的文件读取上会出玄学问题虽然新版实现好了很多但没必要去赌。另外 nc 和 names 的长度必须一致多写一个少写一个训练一开始就会报错或者直接静默出错。标签文件里如果某张图没有任何目标负样本对应的 txt 文件应该是空文件而不是不存在。有些实现的容错处理不一样空文件是最稳的做法。2.4 数据划分与增强策略划分训练集和验证集最忌讳的是“随机划分”这四个字不加思考地用。如果你的数据来自视频抽帧随机划分会让同一段视频的相邻帧同时出现在训练集和验证集里验证指标会虚高十几个点你以为模型泛化很好实际上一换场景就废。正确做法是按场景、按批次、按拍摄日期做划分保证验证集的分布和训练集有真实的差异。比例上八成训练两成验证是常见起点。数据量少的时候比如总量低于 1000 张可以考虑五折交叉验证来更充分地评估但工程上为了省事我一般还是固定一份验证集只要保证它的分布足够有代表性就行。验证集一旦定下来就不要再动否则你没法横向比较不同实验的效果。数据增强这块训练阶段默认会开马赛克增强把四张图拼成一张、随机缩放、色彩抖动、水平翻转。这些默认配置在多数场景下是有效的但有两个例外要手动处理。一是垂直方向有明确语义的场景比如俯拍的零件翻转后不符合物理常识要关掉垂直翻转。二是小目标密集的场景马赛克增强会把目标缩得更小反而不利于收敛这时候可以在训练的最后十几轮关掉马赛克多数实现提供了 close_mosaic 参数让模型在接近真实分布的图像上做收尾微调指标通常会有明显提升。3. 训练配置参数背后的取舍逻辑3.1 从预训练权重出发的迁移学习自建数据集几乎不应该从零开始训。预训练权重里包含的是通用的边缘、纹理、形状特征这些特征在绝大多数视觉任务里都是通用的拿它做初始化能让模型在几百张图上就收敛出可用效果从随机初始化开始同样的数据量大概率训不出东西。这个差距在小数据集上是数量级的不是百分比。加载预训练权重时要注意两点。一是类别数不一致是正常的加载时框架会自动跳过检测头的分类分支只加载主干和颈部日志里通常会打印“跳过某些层的权重”之类的信息这不是错误。二是如果改了输入通道数比如把三通道 RGB 改成单通道灰度或者加上红外通道主干第一层也对不上这时候要么改配置让它重新初始化那一层要么在数据加载阶段把图转成三通道我一般选后者改动最小。还有一种情况是“增量训练”你之前已经用自己的数据训过一个版本现在新增了一批数据想接着训。这时候用自己训出来的权重做初始化学习率要调小大概是原来峰值的十分之一到五分之一否则新数据会把旧知识冲掉出现“学了新的忘了旧的”。这在工业场景里非常常见值得提前规划好数据版本和权重版本的对应关系。3.2 关键参数逐个拆解参数不用背但要理解每个参数在控制什么。我把最常调的几个列出来配合取值依据参数作用常用取值取值依据imgsz输入分辨率640 / 512 / 416必须是 32 的整数倍小目标多就往上加batch批大小8 至 32显存能承载的最大值往下留一档余量epochs训练轮数100 至 300数据量越小需要的轮数越多但要防过拟合lr0初始学习率0.01SGD/ 0.001Adam批大小翻倍学习率大致可翻倍patience早停耐心值30 至 50验证指标连续这么多轮不涨就停workers数据加载进程数4 至 8不超过 CPU 核心数Windows 下建议 0 至 2imgsz 这个参数最值得展开说。它必须是 32 的整数倍因为网络在下采样过程中累计缩放了 32 倍输入尺寸不是 32 的倍数会在特征图对齐时出问题。选多大的依据是你的目标在图中占多少像素如果一个小目标在原图上只有 20 像素宽你缩到 640 输入它可能只剩 10 像素特征图上几乎没有响应了。这种情况下要么提高输入分辨率要么在采集阶段就靠近拍。粗暴的判断标准是缩放到输入尺寸后最小目标不应小于 8 到 10 像素。batch 的取值有个隐性约束太小会让批归一化的统计量不稳定训练曲线抖动明显。老一些的实现在 batch 小于 8 时会给出警告新版靠梯度累积之类的机制缓解了但我的经验还是尽量保证在 8 以上实在显存不够就降低 imgsz 而不是降 batch。学习率这块很多教程上来就写 0.01但那是针对较大批大小和 SGD 优化器的。如果你用 Adam 系优化器0.001 起步更稳。判断学习率是否合适看训练前 10 轮的损失曲线掉得太慢说明小了前期剧烈震荡甚至出现 nan 说明大了。一个可直接用的训练命令示例命令行写法各版本大同小异yolo detect train \ data/data/dataset/mydata.yaml \ modelyolov8s.pt \ imgsz640 \ batch16 \ epochs150 \ patience40 \ workers8 \ device0 \ project/data/runs \ nameexp_screw_v1project 和 name 这两个参数建议每次都写清楚不然跑十几个实验之后你会在一堆自动命名的目录里彻底迷失。我的习惯是 name 里带上数据集代号、模型尺寸和版本号比如 exp_screw_s_v1一眼能看出跑的是什么。3.3 训练过程监控与中断恢复训练启动之后第一件要看的是数据加载是否正常。日志里会打印训练集和验证集的图片数量、类别分布如果这个数字和你预期的不一致立刻停下来检查路径和标签。我遇到过标签文件里有一行格式错误少了一个字段整个文件被静默跳过的情况结果某个类别在统计里凭空消失了。接下来看损失曲线的形状。正常情况是前几轮快速下降然后进入缓慢下降的长尾阶段中间会有小幅波动。如果损失在第 20 轮之后还在剧烈震荡多半是学习率偏大或者数据里有大量脏标注。如果损失降得极慢检查一下是不是冻结了主干而忘了解冻。训练过程中最有价值的监控项其实是验证集上的 mAP 曲线而不是训练损失。训练损失一直降但验证 mAP 持平甚至下降就是典型的过拟合信号这时候早停机制会帮你停下来你也可以手动把最佳权重取出来用。中断恢复是长训练必须要考虑的。多数实现会在每轮结束后把状态存到 last.pt 里加上 resumeTrue 就能接着训。但这里有个坑resume 依赖的是完整的训练状态如果你中途改了配置文件或者换了数据resume 会出问题甚至静默用错配置。我的习惯是长训练之前先把配置文件复制一份到输出目录里存档出问题时能对照。3.4 训练日志里的异常信号怎么读有几个信号我总结成了“看到就查”的清单分类损失居高不下框回归损失正常通常是类别标签错乱或者类别极度不均衡某个类别样本太少。框回归损失震荡且不下降标签格式问题归一化 vs 像素坐标、标注框尺寸异常宽高为 0 或为负。验证 mAP 从第一轮开始就异常高比如 0.9 以上几乎可以确定是数据泄漏训练集和验证集有重复或高度相似样本。训练损失远低于验证损失且差距持续扩大过拟合减模型尺寸、加增强、减轮数。某一类别的 AP 恒为 0该类别的标签编号写错或者配置文件里 names 顺序错位。这些判断没法靠工具自动给出但你每跑一次实验把这几条过一遍几次之后就能形成直觉。4. 推理预测从权重到能看的图4.1 单图、批量、视频与摄像头的调用方式训练完成后权重文件通常是 best.pt就可以直接拿来做推理。最简单的单图预测from ultralytics import YOLO model YOLO(/data/runs/exp_screw_s_v1/weights/best.pt) results model.predict( source/data/test/0001.jpg, imgsz640, conf0.25, iou0.45, saveTrue, project/data/pred, namesingle )批量预测只需要把 source 指向一个目录框架会自动遍历。视频预测把 source 指向视频文件逐帧推理后合成输出视频这一点在做实际验证时特别有用因为单帧看不出误检的时间连续性而视频里误检往往是闪烁的一眼就能识别。摄像头实时推理就是把 source 设成摄像头索引这时候要关注的不只是精度还有帧率。我一般的做法是先在视频文件上跑确认效果稳定之后再做实时因为实时调试的反馈链路太短来不及看清细节。注意推理时的 imgsz 要和训练时保持一致或者至少保持同样的缩放逻辑。训练用 640、推理用 1280虽然能跑但特征尺度发生变化精度通常会有可见的下降。4.2 置信度与 NMS 阈值怎么调conf 和 iou 这两个阈值是推理阶段最能影响观感的参数。conf 是置信度阈值低于它的框直接丢弃iou 是 NMS 的重叠阈值两个框的交并比超过它就只保留分数高的那个。调参的方向取决于你的业务更怕哪种错误。怕漏检比如安全相关的场景conf 往下调0.15 到 0.2 都可以试代价是误检变多要靠后续规则过滤。怕误报比如自动计数conf 往上调到 0.4 到 0.5宁可漏几个也别数错。iou 的调整场景窄一些主要针对密集目标目标挨得很近时iou 设太大比如 0.7会把两个真实目标合并成一个设太小0.3又会对同一个目标产生多个框。密集场景我一般用 0.4 到 0.5。还有一个不太常用但很好使的参数是类别无关 NMSagnostic NMS。当两个类别在视觉上高度相似、模型经常对同一个目标同时输出两个不同类别的框时打开它能让这两个框互相抑制只留分数高的那个。这在“合格品/次品”这类外观差异极小的二分类任务里效果明显。4.3 指标怎么读别只看一个 mAP验证输出的指标里最常被引用的是 mAP50 和 mAP50-95。前者的意思是 IoU 阈值取 0.5 时的平均精度后者是在 0.5 到 0.95 之间每隔 0.05 取一个阈值再平均后者严格得多。两个数一起看才有意义mAP50 高而 mAP50-95 低说明模型能大概找到目标但框的位置不够准这种情况下如果你的应用只需要知道“有没有”那够用如果需要精确测量尺寸那还差得远。除了 mAP我更关注三样东西。PR 曲线能看出在某个置信度下精确率和召回率的平衡点据此定 conf 阈值比拍脑袋靠谱。混淆矩阵能暴露类别之间的系统性混淆比如“划痕”被大量判成“污渍”这就是特征区分度不够要么合并类别要么补充区分性样本。每类的 AP 分布能看出短板整体 mAP 0.8 但某一类只有 0.4那这一类就是下一步优化的重点。还有一个小技巧把验证集的预测结果全部画出来存成图人工扫一遍。指标是统计量会掩盖个案的荒谬错误。我曾在一次任务里发现 mAP 挺漂亮但画出来一看模型把所有反光点都框成了缺陷——这类问题只有看图才能发现。4.4 导出与部署侧的速度优化训练用的 PyTorch 权重在部署时往往不是最优选择。导成 ONNX 或者针对特定硬件做转换推理速度通常能有显著提升。常见的路径是先导出 ONNX再根据目标平台转成对应的推理格式。from ultralytics import YOLO model YOLO(/data/runs/exp_screw_s_v1/weights/best.pt) model.export(formatonnx, imgsz640, simplifyTrue, opset12)导出时有几个细节要注意。imgsz 在导出时就要定死导出的模型输入尺寸是静态的后面推理必须用同样的尺寸否则会报错或输出错乱。simplify 建议打开能消掉一些冗余算子速度提升明显。opset 版本要和目标推理引擎兼容不是越高越好。如果要进一步做 INT8 量化需要准备一批校准图一两百张代表性的图即可量化后精度通常会掉一两个点速度能提升一倍左右是否划算取决于你的场景对延迟的敏感程度。我的经验是在边缘设备上量化带来的收益通常值得那一两个点的精度损失在服务器端用 FP16 就够了。5. 常见问题与排查实录5.1 训练不收敛、指标不涨的排查顺序这是我被问得最多的一类问题。排查应该从最底层往上层走而不是一上来就调学习率。第一步确认标签能被正确读到把数据集配置文件里的路径打印出来手动确认文件存在再看训练日志里统计的实例数量和你标注的数量是否一致。第二步把标签画回图上看确认坐标归一化正确、类别编号正确。第三步用 20 张图做过拟合测试——只训这 20 张看能不能把损失压到接近 0。如果连过拟合都做不到说明问题在数据链路或者模型配置上不是泛化能力问题。过拟合测试是我最推荐的一个诊断手段因为它把问题域切得很干净能过拟合说明链路是通的问题在数据量和泛化不能过拟合说明链路本身有错继续调超参数是浪费时间。5.2 显存不足与训练速度异常的排查显存不够最直接的解法是降 imgsz 或者降 batch但顺序有讲究优先降 batchimgsz 尽量保持因为输入分辨率直接影响小目标的检出能力而降 batch 只是影响训练稳定性。如果 batch 已经降到 4 还是不够再考虑降 imgsz每次降 64降到 512、448、416。如果开了 AMP 还 OOM可以检查一下是不是验证阶段爆的显存——验证时也会前向传播而且有时批大小设得比训练还大。另外某些版本在做马赛克增强时会临时拼接大图峰值显存比常规训练高可以试着调小马赛克的概率。训练速度慢则要分清是 GPU 利用率低还是数据加载慢。看 GPU 利用率如果长期在 30% 以下波动基本可以确定是数据加载成了瓶颈解法是增加 workers、把数据集放到更快的磁盘上、或者开启图像缓存把解码后的图缓存在内存里代价是吃内存。提示workers 在 Windows 上设太大容易出进程卡死的问题表现为训练启动后长时间无输出。遇到这种情况先把 workers 设成 0 或 2 试一下这是平台差异导致的不是配置写错。5.3 推理结果异常的典型原因框位置整体偏移、大小不对八成是训练和推理的预处理不一致。检查两边的 imgsz 是否一致、是否都做了同样的 letterbox 填充。有些自写的推理脚本忘了保持长宽比直接拉伸导致框位置系统性偏移。同一目标出现多个重叠框说明 NMS 没生效或者 iou 设得过大。检查推理代码里是否正确传入了 iou 参数以及是否在自定义后处理里重复做了 NMS。某个类别从来检不出来先看验证指标里这个类别的 AP 是不是接近 0如果是回到训练侧查标签编号和 names 顺序如果训练侧 AP 正常那问题在推理的类别映射表上可能是导出模型时的类别名和推理脚本里读的不一致。全部图都检不出东西先看 conf 是不是设得太高再确认输入图像的通道和归一化方式是否和训练一致。有些自定义推理代码忘了做 0 到 1 的归一化模型输入全是很亮的像素输出全是乱的。5.4 一份排查速查表现象最可能的原因优先验证方式损失降但一个框都不出标签坐标未归一化把标签画回原图看位置验证 mAP 异常高训练/验证集数据泄漏检查是否同源视频抽帧某类 AP 恒为 0类别编号与配置错位打印数据集类别统计对比框位置系统性偏移推理预处理与训练不一致核对 imgsz 和 letterbox 逻辑密集目标被合并NMS 的 iou 阈值偏大降到 0.4 至 0.45 重测背景图大量误检缺少负样本补 5% 至 10% 纯背景图训练一轮就 OOMbatch 或 imgsz 过大先降 batch再降 imgszGPU 利用率长期偏低数据加载瓶颈加 workers、开启缓存6. 几个我踩过之后才记住的细节第一个是验证集要“冻结”。我在早期项目里犯过一次错看到验证集上某一类表现太差就把那几张图挪回训练集重新训指标立刻好看了但上线后完全不是那个表现。验证集一旦用来指导决策它就不再是客观的评估集了。后来的做法是留一份完全不动用的测试集只在最后验收时跑一次。第二个是权重版本管理。同一个数据集上跑十几次实验如果没有清晰的命名和记录你会彻底搞不清哪个权重对应哪次改动。我的做法是每次实验在输出目录里放一个说明文件记下数据版本、模型尺寸、关键参数改动和验证指标几行字的事省下的时间难以估量。第三个是小目标场景优先考虑切图推理。如果你的目标在原图上只有几十像素而整图分辨率又很高与其硬提输入分辨率显存吃不消不如把大图切成重叠的小块分别推理再合并结果。这个思路在遥感、工业检测里非常常见效果提升比调参明显得多。第四个是别迷信默认的 300 轮。很多配置默认给了很大的轮数配合早停机制其实没什么问题但如果你没有设 patience模型会在过拟合区间里白白训很久最后保存的 best 权重可能反而不如中间某一轮的。设上 patience 并定期看曲线比一口气训到底要靠得住。最后分享一个我在数据量偏少时常用的做法先把模型在一个相近的、样本更充足的数据集上训一轮把学到的权重作为自建数据集的初始化再训一遍。这个“两段式”的策略在样本只有几百张时特别有效收敛速度和最终精度都比直接用通用预训练权重更好代价只是多花一次训练时间。