1. 从 v5 到 v11:每个版本到底改了什么
这几年的目标检测项目里,YOLO 几乎成了默认选项。我从 v5 开始接触,一路用到 v11,中间还踩过 v6、v7、v8、v9、v10 的不少坑,今天这篇就把这条演进路线完整盘一遍,说清楚每个版本的核心改动、适用场景,以及到了 2026 年的今天,新项目到底该选哪一版。
先说一个很多人问过的问题:YOLO 目前到几了?官方主线版本号已经走到 v11,社区里偶尔流传的 v26、v27 编号,基本是第三方分支或者网友起的外号,不是 Ultralytics 官方发布的版本,选型的时候不用被这些数字带偏。真正需要关注的,是 v5 到 v11 之间,每一代在骨干网络、标签分配、损失函数和推理效率上做了什么实质性的调整。
v5 是绝大多数人入门的起点。它的贡献不在于某个颠覆性算法,而是把训练、验证、导出、部署这条路彻底做顺了。CSPDarknet53 骨干加上 PANet 特征融合,配合自动学习 Anchor 的机制,让用户在自定义数据集上几乎不用手动调 Anchor 就能跑出还不错的结果。v3 到 v5 之间,业界对 Anchor 大小、宽高比极其敏感,换数据集就得重新聚类,v5 解决了这个痛点,这也是它在工业界迅速铺开的核心原因。
v6 是美团开源的版本,定位非常明确:面向工业落地。它做了两个大的调整,一个是把检测头从耦合改成解耦,另一个是全面转向 Anchor-Free。解耦头的思路是让分类和回归分支各自学习自己的特征,不再共享同一个卷积输出,收敛速度明显比 v5 快,训练时间可以缩短 30% 左右。但 v6 在生态工具链上相对封闭,后续更新也不积极,所以它更像是给 v8 铺路的试验场。
v7 延续了 v5 的框架路线,但把结构做了进一步打磨。E-ELAN 模块让网络在加深加宽的同时控制住梯度消失问题,辅助训练头的设计也很有想法——训练时多一条监督分支,推理时只保留主分支,参数量不变但精度提升。如果你手头有一套成熟 v5 的部署代码,迁移到 v7 的成本最低,因为它本质上就是 v5 的增强版。
v8 是 Ultralytics 团队推出的版本,也是目前生态最繁荣的一代。骨干网络从 C3 换成了 C2f,梯度流更丰富;检测头沿用解耦设计,配合 Anchor-Free 和 TaskAlignedAssigner 标签分配策略,在 COCO 上的 mAP 全面超过 v5。更重要的是,v8 的代码架构极其工整,训练、验证、导出、推理全部收敛到一个框架里,还支持检测、分割、姿态估计、旋转框、分类五种任务,API 风格统一。这版我已经在三个正式项目里落地,稳定性和可维护性都比前代强很多。
v9 在主线上不算大红大紫,但它的可编程梯度信息(PGI)思路值得单独拎出来讲。这套机制解决的是深层网络中信息在前向传播和反向传播过程中的丢失问题,配合 GELAN 轻量架构,收敛速度和最终精度都有明显提升。我自己的测试里,v9 在同等算力下比 v8 高 0.5 到 1 个点的 mAP,只是社区生态还没完全跟上,部分第三方改进模块只适配到 v8。
v10 最激进的改动是去掉了 NMS。传统检测器推理时必须靠 NMS 去除重复框,v10 通过双标签分配机制——一个分支用一对多分配学习全面特征,另一个分支用一对一分配模拟推理时的无 NMS 状态——在训练阶段就解决了重复预测的问题。推理链路少了 NMS 这一步,延迟确实更低,但代价是精度略微牺牲,而且在某些边缘设备上 NMS 的开销本来就不大,所以这版更适合对极端低延迟有硬指标的场景。
v11 是当前最新主线,与其说它是全新架构,不如说是过去所有经验的集大成者。C3k2 模块在 v8 的 C2f 基础上做了进一步优化,SPPF 升级成了 C2PSA,同时把 Attention 机制以一种更轻量的方式融入骨干网络。性能上,v11 在同等规模下比 v8 大约提升 0.5 到 1 个点 mAP,训练显存占用更低,推理速度基本持平。最让我满意的是它继承了 v8 的全部任务支持,可以直接无缝切换使用,这也意味着 v8 时代的部署方案不用推倒重来。
| 版本 | 核心结构变化 | 标签分配 | 最大优势 | 主要短板 |
|---|---|---|---|---|
| v5 | CSPDarknet53 + PANet | 基于 Anchor 的自动学习 | 生态成熟、部署方案多 | 结构相对落后 |
| v6 | 解耦头 + Anchor-Free | SimOTA | 训练速度快 | 工具链封闭 |
| v7 | E-ELAN + 辅助训练头 | Anchor 体系 | 精度均衡、迁移成本低 | 功能相对单一 |
| v8 | C2f + TaskAlignedAssigner | Anchor-Free | 生态最完整、API 统一 | 部分场景精度不如 v9/v11 |
| v9 | PGI + GELAN | TaskAlignedAssigner | 收敛快、精度高 | 社区模块少 |
| v10 | 无 NMS + 双标签分配 | 双分支分配 | 推理延迟低 | 精度略降 |
| v11 | C3k2 + C2PSA | TaskAlignedAssigner | 综合性能最佳 | 相对较新、踩坑记录少 |
2. 训练自己的数据集:从标注到调参的硬核笔记
版本差异聊完了,接下来是实操含量最高的部分:怎么把 YOLO 跑在自己的数据上。这part 是每个从“跑通 demo”走向“落地项目”的人都要迈过去的坎,也是问题最多的环节。
2.1 数据标注与格式转换
训练 YOLO 之前,数据标注是绕不开的第一步。LabelImg 是最经典的标注工具,VOC 格式的 XML 导出后,需要在脚本里转成 YOLO 的 txt 格式。转换规则很简单,YOLO 格式每行是一个目标的类别 ID 加上归一化后的中心点坐标和宽高,也就是 class_id、x_center、y_center、width、height,所有数值除以图片宽高,范围在 0 到 1 之间。
用 VSCode 的 YOLO 相关插件也能做标注,打开图片直接画框,实时预览标签,界面比 LabelImg 漂亮得多。我实测下来,对于几百张的小数据集,VSCode 插件足够用;如果是几千张的大项目,还是建议用 Roboflow 或 CVAT 这类支持团队协作和自动标注的工具,效率差距在数据量上去之后非常明显。
除了自己标,日常还会遇到数据集格式转换的需求。COCO 数据集要转成 YOLO 格式,这一步需要把 JSON 里的 annotations 解析出来,提取每个目标的 bbox 和 category_id,再做一次归一化。核心处理逻辑如下:
import json def convert_coco_to_yolo(coco_json, output_dir): with open(coco_json, 'r') as f: data = json.load(f) for img_info in data['images']: img_id = img_info['id'] img_w = img_info['width'] img_h = img_info['height'] txt_path = f"{output_dir}/{img_info['file_name'].split('.')[0]}.txt" with open(txt_path, 'w') as out_f: for ann in data['annotations']: if ann['image_id'] != img_id: continue cat_id = ann['category_id'] x, y, w, h = ann['bbox'] x_center = (x + w / 2) / img_w y_center = (y + h / 2) / img_h norm_w = w / img_w norm_h = h / img_h out_f.write(f"{cat_id} {x_center:.6f} {y_center:.6f} {norm_w:.6f} {norm_h:.6f}\n")MOT16 这类跟踪数据集转 YOLO 格式也是一个高频需求,原理差不多,只是每个目标在多帧中重复出现,需要循环写入不同帧对应的 txt 文件。这个过程里最常踩的坑是类别 ID 不连续,比如 COCO 数据集的 category_id 从 1 开始,但某些场景只挑其中几类训练,直接沿用原始 ID 会导致训练时类别索引错乱,建议写个脚本做一次 ID 映射。
2.2 训练配置与损失函数理解
数据处理完,进入训练环节。训练 YOLO 有一套标准的参数配方:img_size 通常用 640,batch_size 根据显存调整,epoch 数看数据集规模,一般小数据集 300 轮、大数据集 150-200 轮就能收敛。学习率用默认的 0.01 配合 warmup,前 3 个 epoch 线性预热,避免初始权重剧烈抖动。
很多人训练效果不好,问题往往出在超参数之外,而是没搞清楚 YOLO 的损失函数是怎么工作的。v5、v7 时代,损失分为三块:分类损失用 BCEWithLogitsLoss,目标置信度损失也是 BCE,边界框回归损失用 CIoU。CIoU 是在 IoU 基础上考虑了中心点距离和宽高比,训练时能更精准地回归框的位置和形状。
v8 之后引入了 DFL 损失,它的全称是 Distribution Focal Loss,作用是让模型对边界框的位置预测输出一个概率分布,而不是直接回归一个具体值。这个改动的直接好处是,对模糊边缘目标的定位精度明显提升。TaskAlignedAssigner 是 v8 之后的标签分配策略,训练时同时考虑分类得分和 IoU 得分,选出最合适的正样本,保证分类和回归两个任务在同一个目标上协同优化。
2.3 训练过程里的常见问题
训练过程中最容易遇到两个问题:loss 不下降和 mAP 波动。loss 不下降,先检查数据标签文件是否为空、类别 ID 是否越界,这时候跑一遍数据校验脚本是必要的,不能盲目调参。mAP 波动大,多半是验证集的样本量太小,或者数据集存在类别不平衡,这时候可以尝试调整验证集划分比例,或者用分层抽样的方式保持每个类别的样本比例。
数据增强也是影响训练效果的重要因素。YOLO 默认开启 Mosaic 增强,把四张图拼成一张训练,对小目标检测帮助很大。但 Mosaic 在训练后期可能会引入噪声,v11 里可以配置在最后 10 个 epoch 关闭 Mosaic 做精调,实测能稳定提升 0.3 到 0.5 个点的 mAP。
另外一个细节是类别不平衡问题。安全帽识别这种场景,戴帽子的样本可能占 90%,没戴帽子的只占 10%,直接训练会发现正样本分类很准但负样本几乎全漏。我的做法是先统计每类的样本数量,对少样本类别做数据增强,比如上下翻转、随机旋转 30 度内、HSV 色域扰动,数量提升到接近多数类的三分之一;如果方差太大,就在损失函数里按类别权重放大少样本类别的梯度。
3. 推理与部署的硬件适配要点
模型训练完不算结束,部署才是真正接近生产环境的部分。不同硬件平台适配 YOLO 的难度和性能差异非常大,这一节把常见平台的部署路径和避坑经验整理出来。
3.1 NVIDIA 与 AMD 的部署差异
NVIDIA 显卡部署 YOLO 有成熟的方案,PyTorch 模型导出为 ONNX,再转 TensorRT engine,利用 FP16 量化可以显著提速。转换代码通常长这样:
import torch from ultralytics import YOLO model = YOLO('yolo11n.pt') model.export(format='engine', half=True, dynamic=False)TensorRT 的优化点在于层融合、内存复用和 kernel 自动调优,同样一张 3070 显卡,TensorRT FP16 的推理速度能比 PyTorch 快 3 倍以上。但转 engine 时有几个坑值得注意:一是 batch size 必须固定,虽然支持动态 shape,但动态模式下性能会下降接近 20%;二是输入尺寸固定为训练时设置的 imgsz,推理新图片前需要做 letterbox 预处理,把短边缩放到目标尺寸、长边补灰边,这一步别直接用 cv2.resize,否则会破坏宽高比导致精度下降。
AMD 显卡跑 YOLO 这两年改善很大,主要依赖 ROCm 框架。如果显卡在 ROCm 支持列表中,可以把官方 PyTorch 镜像换成 ROCm 版本,用 hcc 作为编译器跑训练;推理导出 ONNX 后,可以用 ROCm 的 MIGraphX 引擎加速,实测性能在部分型号上已经追平同档位 N 卡的 80%。但兼容性还是需要提前评估的,比如 Windows 下 ROCm 的支持范围很窄,排版格式和工具链都建议先在 Linux 下测试确认,再决定是否切到 AMD 方案。
3.2 从 CPU 到边缘设备再到 FPGA 的部署
CPU 部署是很多部署方案兜底的选择,OpenVINO 是降低延迟最简单的方案。Intel 的 CPU 上,OpenVINO 把模型转成 IR 格式后推理速度能比原始 PyTorch 快 2 倍左右。值得留意的是,在 CPU 上跑 YOLO 时输入尺寸的选择非常敏感,用 320 代替 640 通常可以把延迟从 200ms 压到 60ms 左右,mAP 只降低 3 到 5 个点,对部分项目完全够用。
边缘设备方面,Jetson 系列是多数人的首选。Orin Nano 部署 YOLOv11n,TensorRT FP16 可以做到 30 到 50 FPS,功耗控制在 10 到 15W,适合移动巡检、无人机等场景。部署的时候要特别注意内存带宽的瓶颈,边缘设备对模型 FLOPs 的敏感度不如对内存访问的敏感度高,选型时优先考虑轻量版模型而不是一味缩减网络深度。
Atlas 系列部署 YOLO 用的是昇腾 CANN 工具链,模型先导出 ONNX,再用 ATC 工具转换成 .om 格式。转换过程中如果不做算子映射检查,很容易碰上 Din 算子不支持的情况。我的经验是先跑一遍 atc 前自带的精度对比工具,确认输入归一化方式和模型原训练配置保持一致,再部署上线,同时预留一个 CPU 的备用推理链路,方便压测调速和灰度验证。
FPGA 部署 YOLO 是一个相对硬核的方向。Xilinx 的 DPU 核可以运行经过量化的 YOLO 模型,流程是用 Vitis AI 的量化工具把模型权重量化成 INT8,再用编译器生成 xmodel。这块的难点在于网络层结构必须被 DPU 支持,v8 的 C2f 结构里有大量 concat 和残差连接,有些 FPGA 工具链对这类算子的支持并不完整,编译时报错很常见。如果你不是专门搞 FPGA 开发的,建议先跑通样例模型确认该工具链对 YOLO 的支持程度,再决定要不要投入。
3.3 一键部署脚本的价值
部署过程中,很多环境配置步骤非常重复,写一键部署脚本能省下大量时间。典型脚本的逻辑是:检查系统环境、安装对应版本的 CUDA 和 cuDNN、创建 conda 环境、安装 PyTorch 和 Ultralytics 依赖、下载预训练权重,最后跑一个测试图片验证环境正常。这个脚本我第一次写的时候花了半天,后面每个新项目复用,基本省掉了重新踩环境坑的时间。
要特别提醒的一点是,部署脚本里的版本号要严格锁定。PyTorch、CUDA、TensorRT 这三者的版本组合有很强的相互依赖关系,GPU 环境升级容易连锁翻车,建议写死版本参数并放到脚本头部,方便维护时一眼就能找到改哪里。
4. 网络改进与模块缝合的正确打开方式
很多人训练自己的数据集时,会遇到“加了改进模块反而掉点”的情况,这一节把模块改进的常见思路、踩坑点和方法论讲透。
4.1 改进的方向与做法
YOLO 的改进主要从三个维度入手:骨干网络、特征融合和检测头。骨干方向的改进思路是引入 SE、CBAM、CA、EMA 等注意力模块,目的是让网络更关注重要特征通道和区域;特征融合方向的改进关注多尺度特征的融合效果,AFPN、BiFPN 是常见操作;检测头方向的改进主要是把普通的卷积检测头换成更高效的结构,或者加入上下文信息增强模块。
以 v8 为例,在主干网络的第 6 层后接一个注意力模块,代码层面的插入方式通常是在模型配置文件里修改网络结构。Ultralytics 框架支持用 YAML 定义模型结构,你可以把注意力模块作为一个自定义 layer 写进 yaml 的 backbone 部分。这个方式比直接修改源码更好,既保留原始结构的可回溯性,又方便对比实验不同插入位置的效果。
4.2 模块缝合的边界与教训
模块缝合有一个很常见的误区,以为堆的模块越多效果越好。实际上我试过在一层网络里同时接 SE 和 CBAM,训练 loss 直接训不下去——梯度传播路径太长导致梯度消失。做模块改进一定要遵循“小步快跑”的原则:一次只加一个模块,同一批数据集、同一组超参数下做对比实验,确认确实涨点了再叠加下一个。
另外要注意 FLOPs 和显存的开销。有的注意力模块在论文里精度涨得不少,但实现时发现显存占用多出 20%,如果目标设备显存只有 8G,这类改动就得谨慎评估。选择模块时,建议综合考虑精度增益、计算量、显存开销三个指标,而不是单独看精度。
多尺度检测也是一个值得说的点。缺陷检测里的小目标占比高,YOLO 的 P3 特征层对 8x8 以下的小目标召回率还是偏弱。一个很实用的改进是在 neck 后面额外加一个 P2 输出头,把 160x160 的高分辨率特征图引入检测,小目标的 mAP 通常能提升 2 到 3 个点。代价是显存会增加大约 20% 到 30%,部署时需注意显存是否充裕,量化后是否有精度损失。
一套有效的改进流程大致是这样:先跑一个原始模型的 baseline,记录 mAP 和推理速度;然后针对数据特点选一个改进方向,插入模块后重新训练;如果训练好的模型 mAP 提升但推理速度下降可以接受,就保留;如果提升不明显,先调整插入位置再试,不要直接换更复杂的模块。
5. 2026 年 YOLO 选型决策参考
说了这么多,最后落到具体选型。每个新项目启动时,选对版本直接影响后面几个月的开发效率,这里给出 2026 年的决策建议,按场景分类。
5.1 按应用场景选版本
| 应用场景 | 推荐版本 | 选择理由 |
|---|---|---|
| 边缘设备实时检测 | v11n / v8n | 轻量化模型、TensorRT 优化成熟 |
| 高精度工业质检 | v9m / v11m | PGI 机制让深层网络不变差、边界回归精度高 |
| 特殊硬件部署 | v8s | ONNX 兼容性最好、第三方工具链适配最全 |
| 姿态估计 | v11m 姿态版 | 官方内置、协同训练方便 |
| 旋转框检测 | v11 旋转框版 | 官方支持最完整的旋转框方案 |
| 已有 v5 老项目升级 | v8s | 迁移成本低、部署代码免大改 |
边缘设备场景里,v11n 是当前综合体验最好的轻量模型。它比 v8n 在 COCO 上的 mAP 高约 0.8 个点,推理速度基本持平,转 TensorRT 后的延迟差异可以忽略。如果你的设备算力极其有限,比如树莓派 4B 这种级别,可以考虑 v5n 配 OpenVINO 的旧组合,毕竟这一套被验证过无数次,踩坑成本最低。
高精度工业质检是 v9 的主场。质检场景对 mAP 的要求往往在 0.95 以上,v9 的 PGI 机制在深层网络上表现更好,训练收敛后曲线更稳定。不过要注意,v9 的有些第三方辅助模块还未适配 RVC 工具链,如果你需要做切片后再检测的细粒度流程,建议用 v8 打底。
5.2 版本选择的现实考量
技术指标只是一部分因素,社区生态和工具链的成熟度往往更决定项目的顺畅程度。v11 在功能和性能上是当前最优解,但毕竟发布不到一年,第三方教程和源码解读相对少。v8 经历了两年多的社区沉淀,几乎所有的坑在网上都能搜到答案,很多开源项目的部署代码可以直接抄作业,如果你是第一次跑 YOLO,v8 仍然是风险最低的选择。
训练资源也是选型的重要变量。如果你的设备只有一张 4G 显存的消费级显卡,v9、v11 的中大型模型会非常吃力,建议选择 nano 或 small 版本;如果你有集群训练条件,mAP 指标优先,可以考虑 v11m 或 v11l。
最后一点,模型版本不是越新越好,真正重要的是适配你的数据和部署环境。v8 用了三年依然是很多工业项目的首选,恰恰说明稳定的生态比单点性能的提升更有价值。反过来说,如果你手里有一个精度要求极高但硬件算力充足的项目,v11 的收益也非常明显。
6. 垂直场景实例分析
很多实际项目不是单纯的通用目标检测,而是在某个垂直场景里做“应用”,这些场景里选型和部署的考虑也会很不一样。挑几个典型例子讲一下。
矿山上做泥石流、滑坡监测的项目,我接触过一些。这类场景的共性是数据极难获取,正样本稀少且环境背景复杂。选型上我们用的是 v8m,而不是追求最小延迟的 nano,因为精度是第一优先级,漏报会造成严重后果。数据处理上,滑坡样本往往需要做大量的旋转、亮度扰动和背景替换增强,否则模型只会记住“某类特定纹理的山体”,换一个矿区就失效。部署上,因为需要在边缘侧连续运行,我们用 TensorRT 做 FP16 量化,把整条推理链路稳定到 25 FPS 左右,并加上了一个“连续多帧检测结果置信度过滤”的逻辑,降低单帧误判。
烟火识别也是一个典型的垂直场景。这类项目通常部署在园区监控或林区边缘设备上。早期有人用 v5 做烟火检测,后来我们发现 v8n 配合专门的帧差预处理效果更好。烟火检测很依赖“时序信息”,单帧图片容易混淆光线变化和真正的烟雾。我们的做法是保留前 5 帧的检测结果做投票,超过 3 帧都判为烟火才触发告警。版本上选 v8n 而不是 v11n,原因很实际——现场设备已经有了一套配套 v8 的旧推理框架,留意见和稳定性更重要,没必要为了几个点的精度去换新版本。
安全帽和安全服检测应该是我被问得最多的项目类型。核心难点是夜间和环境背景复杂。夜间工地光线不足,检测精度明显下降。我的经验是除了模型改进,前处理阶段可以加一步自适应直方图均衡化,这个预处理在增强暗部细节方面很有效。版本选型上,这类项目用 v11s 的性价比最高,因为夜间小目标漏检率比 v8s 低接近 1.5 个点,部署到 Jetson Orin NX 上也能跑实时。另外提醒一句,打标签阶段别偷懒,安全帽和安全服这两个类别要分开标,很多人图省事只标安全帽,导致落地的模型根本无法回答“有人没穿安全服”这个实际问题。
综合这几个例子可以看到,选型逻辑从来不只看版本号,数据分布、现场环境、部署算力、误报漏报容忍度这些因素同样影响最终效果。
7. 2026 年避坑清单与实操总结
最后整理一份实战避坑清单,这些都是我在多个项目里踩过的真实教训,按重要程度排个序。
最严重的一个坑是训练集和测试集的来源不一致。有些项目拿了一部分网上公开的图片、一部分自己拍的图片,混合起来直接用,结果训练时 mAP 看着很高,一到现场测试完全拉跨。原因是采集的光照、相机型号、视角完全不同,模型学到了背景特征而不是目标特征。正确做法是尽量保持训练数据与真实场景同分布,如果做不到,至少把数据按来源分组,验证集用现场真实图片。
第二个常见坑是推理时的图像预处理和训练时不一致。训练时用了 Mosaic、MixUp 这些增强,推理时只需要做 letterbox,但很多人把增强逻辑盲目搬到推理端,导致输入分布漂移,精度下降。遇到这种问题,先检查输入图像的归一化参数、letterbox 填充值和模型期望的输入尺寸是否完全一致。
第三个坑是直接拿官方预训练权重在自己的数据上恢复训练后,选择性地不收敛。过拟合在小数据集上非常容易发生。这时候冻结骨干层是有效的:先冻结 backbone 训练头部 50 轮,再解冻全部网络微调,可以很好地在小样本场景下保持泛化能力。
第四个很隐蔽的问题是标签格式里出现 NaN。COCO 转 YOLO 时,如果 bbox 的宽或高为 0,归一化后就是 0,训练不会立刻崩溃,但 loss 会异常波动。这类问题排查很费时间,建议做校验脚本,扫描所有 txt,检查每个坐标,过滤掉非正值的异常标注再开训练。
关于损失函数的调参,如果训练时出现 loss 为 NaN 的情况,多半是学习率过大导致梯度爆炸,把学习率降到 0.001 以下再观察;如果 loss 正常下降但精度不涨,检查是否对数据做错了归一化,输入图片的像素范围应该在 0 到 255 之间,如果变成了 0 到 507 之类的范围,大概率是中转脚本里多乘了一次 255。
最后说一下模型量化。部署到边缘设备时经常需要 INT8 量化,量化后 mAP 可能掉 3 到 8 个点。关键是要用验证集图片做校准,校准集图片要覆盖所有类别的典型形态,数量不用太多,500 到 1000 张就够。量化后如果精度掉得厉害,可以尝试逐层混合精度量化,只对敏感层保持 FP16,其他层 INT8,这个策略在烟火、安全帽等小目标密集场景里能救回不少精度。
这篇文章写到这里,YOLO v5 到 v11 的演进脉络、训练细节、部署选型和各种避坑经验都过了一遍。如果你刚入门,建议从 v8 开始,跟着官方文档训练第一个模型,然后逐步摸索改进;如果你有明确的生产需求和硬件约束,可以对照选型表格直接做决策。最后再分享一个小经验:每次做新项目,我都会把训练数据分布、超参数配置、改进模块插入位置、最终 mAP 这些信息记录在一个固定的实验笔记里,这样过半年回来分析项目效果时,排查问题的速度快了非常多。