从“作废”到“登顶”:一次 YOLO 检测器选型实验的完整复盘
从“作废”到“登顶”:一次 YOLO 检测器选型实验的完整复盘
项目:无人机道路车辆流量统计系统(PRD v1.1) | 实验:检测器选型(FR-3 / O-4) 日期:2026-11-04 | 硬件:RTX 4060(8GB) | 环境:torch 2.0.1+cu118、CUDA 11.8、ultralytics 8.3.161 → 8.4.202 配套数据:eval_results_rerun/summary.csv · 技术报告:eval_results_rerun/eval_report_rerun.md
TL;DR
在 mini_test 7 个切片上用 COCO 预训练权重做零样本评测,第一轮(ultralytics 8.3.161)yolo26m 输出异常被作废、yolov10m 综合最优;升级到 8.4.202 重跑后剧情反转:yolo26m 恢复正常并在 6/7 切片登顶(7 切片均值 mAP50-95 = 0.149,比第二名高 30%),而 v10m 的“最优”结论被证明部分建立在旧版解码行为和小样本噪声上。最终候选收敛为 yolov8m(生态保底)+ yolo26m(精度冲刺)。
1. 背景:一次“选模型”的小实验
项目的检测模块(PRD FR-3)要求:主线选一个生态成熟、易导出的 YOLO 实现,另选一个版本做小规模对照,最终在第 2 周前定版(开放问题 O-4)。数据特点很鲜明:无人机航拍、俯视小目标占比高、峰值 ~100 辆/帧、巡飞相机运动是常态。
候选池定在四个同规模(m 档)模型:yolov8m、yolov10m、yolo11m、yolo26m——前三个是“老朋友”,yolo26m 是 2026 年初发布的新一代(NMS-free、无 DFL、专为小目标设计的 STAL 标签分配)。
实验设计很简单也很克制:
| 项 | 设置 |
|---|---|
| 测试集 | mini_test 7 子集:all/day/foggy/night/oblique/side/top_bottom,262 张图(子集间有重叠),5119 个 GT 框 |
| 类别口径 | 只评 car/truck/bus(COCO 映射 2/7/5);car 占 98.5%,是主信号 |
| 推理设置 | imgsz=1280、conf=0.001、NMS IoU=0.7、FP16、batch=1 |
| 指标 | 自研 COCO 风格:mAP50/75/50-95、AP small/medium/large、P/R/F1、混淆矩阵(PRD FR-3 要求 mAP50-95、Recall、APsmall) |
为什么用预训练权重直接测而不是先微调? 因为选型阶段要的是“零成本排除短板”:预训练零样本下的相对排名 + 问题诊断(哪个模型在本域彻底失灵、哪类目标检不出),足以把 4 选 1 收敛到 2 选 1,剩下的交给微调后复评。
2. 第一轮:yolo26m 的“灵异事件”
第一轮跑在 ultralytics 8.3.161 上,结果很诡异:
| 证据 | yolo26m | 其他三模型 |
|---|---|---|
| all 子集输出框数 | 1531 | 10825–14011 |
| day 子集输出 car 框 | 0 个 | 107–160 |
| night 子集输出框 | 3 个 | 780–1501 |
| maxF1 对应置信度 | 0.0010 | 0.011–0.028 |
| Recall@0.25 (all) | 0.0002 | 0.110–0.151 |
置信度被整体压缩到 0.001 量级、输出框少一个数量级、图像间剧烈波动(night 仅 2 个 car 框 + 1 个 TP 制造出 AP50=1.0 的假象)。结论是:8.3.161 能加载 yolo26m 权重,但后处理/置信度机制不兼容,其全部指标不可信,作废处理。
剩下三个正常模型里,yolov10m 看起来综合最优(7 切片均值 mAP50-95 = 0.158 vs v8m 0.101 / v11m 0.105),尤其在 day(0.254)和 top_bottom(0.285)切片上有 2–3 倍优势。当时的候选对建议是 v8m + v10m。
3. 假设与复跑:升级 ultralytics
“yolo26m 作废”这个结论一直让我不舒服——它论文里的 STAL(Small-Target-Aware Label Assignment)明明是为本项目这类“俯视小目标”场景设计的,不该烂成这样。最合理的假设是版本兼容性问题,而不是模型本身差。
于是做了最小改动复跑:只把 ultralytics 从 8.3.161 升到 8.4.202,其余设置完全不动。
4. 重跑结果:剧情反转
4.1 yolo26m 复活,而且全面登顶
升级后 yolo26m 输出恢复正常(输出框 1531 → 15057),然后直接统治了榜单——7 个切片里 6 个第一,唯一不是第一的 night 与 v8m 打平:
| 模型 | all | day | foggy | night | oblique | side | top_bottom | 均值 |
|---|---|---|---|---|---|---|---|---|
| yolo26m | 0.159 | 0.122 | 0.171 | 0.070 | 0.131 | 0.196 | 0.191 | 0.149 |
| yolov10m | 0.110 | 0.083 | 0.118 | 0.068 | 0.114 | 0.127 | 0.187 | 0.115 |
| yolo11m | 0.113 | 0.084 | 0.124 | 0.019 | 0.104 | 0.131 | 0.158 | 0.105 |
| yolov8m | 0.112 | 0.049 | 0.122 | 0.071 | 0.116 | 0.130 | 0.109 | 0.101 |
(表内为 mAP50-95)
更关键的是几个业务导向的指标:
| 指标(all 子集) | v8m | v10m | v11m | yolo26m |
|---|---|---|---|---|
| Recall@0.25 | 0.151 | 0.128 | 0.110 | 0.253 |
| maxF1(@conf) | 0.445(0.022) | 0.460(0.023) | 0.439(0.011) | 0.522(0.052) |
| AP_small | 0.091 | 0.092 | 0.088 | 0.116 |
| car AP50 | 0.516 | 0.536 | 0.526 | 0.593 |
| 推理耗时(1280/FP16) | 19.3ms | 20.3ms | 18.9ms | 18.9ms |
三点值得单独说:
- Recall 是计数业务的命门。PRD 的计数验收线是漏计率 ≤10%,检测 Recall 是它的上界。yolo26m 的 0.253 是第二名的 1.7 倍——同样是零样本预训练,它多找回了一倍的车辆。
- 小目标真的变好了。AP_small 0.116 vs 其余 ≤0.092,和 STAL 的设计意图对上了:极小目标在特征图上原本可能“无锚点可分配”,STAL 就是修这个的。理论宣称和实测方向一致,这是这次实验最舒服的部分。
- 精度领先没有付速度税。yolo26m 推理 18.9ms,与最快的 yolo11m 持平;四模型端到端单帧 21–25ms,离 NFR-1 的 p95 ≤ 150ms 差了近一个数量级,都达标。
代价也有:yolo26m 的 precision 略低(0.882 vs 其余 0.93+),会放出更多低置信误检——这对下游跟踪计数是干扰源,需要在跟踪侧消化,这是它上主线前的一道 gate。
4.2 v10m 的“最优”结论被推翻
重跑里最值得复盘的是 yolov10m:它的数字在两轮之间漂移了,而 v8m/v11m 几乎逐位不变:
| 切片 | v10m(8.3.161) | v10m(8.4.202) |
|---|---|---|
| all | 0.119 | 0.110 |
| day | 0.254 | 0.083 |
| top_bottom | 0.285 | 0.187 |
这说明上一轮 v10m 的领先(尤其 day/top_bottom 的 2–3 倍优势)很大程度来自旧版端到端解码行为 + 小样本(17/27 张图)的排序噪声,而不是模型本身的稳健优势。教训很直接:端到端(NMS-free)模型的解码对推理框架版本敏感,跨版本结论必须复跑验证。
4.3 稳定不变的发现
- v8m 和 v11m 跨版本几乎逐位一致(all:0.1123→0.1123 / 0.1131→0.1129),说明传统 NMS 链路很稳,跨轮可比。
- yolo11m 夜间连续两轮崩塌(night mAP50-95 = 0.019,TP = 0),升级救不了它。
- day 切片全员“名义失败”:17 张图 90 GT,四个模型都只有 1 个 TP(Recall≈0.011)——AP 的差异纯粹是置信度排序噪声,这个切片不能作为任何选型依据,需要 per-image 诊断。
- truck/bus 基本检不出:GT 太少(48/27),TP 接近 0,任何模型都救不了——是数据问题(类别不平衡)而非模型问题,建议合并为 vehicle 或补标注。
- night 是全局最短板:最好成绩也只有 0.071,微调后必须单独切片复评(对应 PRD DR-5 困难切片)。
5. 结论:选型如何收敛
- 候选对:yolov8m(生态保底)+ yolo26m(精度冲刺)。
- v8m:生态最成熟、导出链最稳、night 最稳之一、Recall 第二——扛 FR-3“主线选生态成熟易导出”这条底线;
- yolo26m:本域精度显著领先、NMS-free、速度零代价——微调后冲精度上限的首选。
- v10m 降级为 NMS-free 部署对照备选(它跨版本漂移的表现不够格当主线)。
- v11m 降为观察项:速度优势只有 ~8%,换不来夜间崩溃的容错。
- 最终定版仍按 PRD O-4:fine-tune 后复评(候选对 × 7 切片)。yolo26m 上主线前过两道 gate:
- ① ONNX / TensorRT 导出与 INT8 校准验证(FR-9 部署链);
- ② 与 BoT-SORT 跟踪/计数的联调(低置信 FP 是否影响计数精度)。
6. 踩坑清单(写给自己,也写给读者)
- 先怀疑工具链,再怀疑模型。yolo26m 第一轮那个“灾难级”表现,根因是推理框架版本,不是模型。遇到“某个模型烂得离谱”,先查它是不是被错误地加载/解码了。
- 小切片排名的含金量很低。day 只有 17 张图 90 个框,AP 排名完全被 1 个 TP 的置信度排序左右。结论要以大切片(all 5119 GT / foggy 4223)为准。
- 跨版本复跑是廉价保险。一次重跑推翻了一个“最优”结论——如果直接按第一轮结果定主线,后续微调、导出的时间都会花在错误的方向上。
- 锁定版本号写进报告。v10m 的漂移是版本敏感性的活教材,所以实验记录里明确写“后续统一锁定 ultralytics 8.4.202”,呼应 PRD 的可复现性要求(NFR-5)。
- 零样本置信度不能信默认值。预训练模型在本域数据上信心普遍偏低(maxF1 工作点 0.011–0.052):v8/v10/v11 直接用 conf=0.25 会漏掉约九成目标;临时做跟踪计数 demo 时要把 conf 降到 0.02–0.05 并按 maxF1 标定。
- Recall 优先于 mAP。对“数车”这类下游任务,漏计率 ≤10% 的验收线意味着检测阶段应该盯 Recall 而不是平均精度——选型排序也要按这个权重来。
7. 下一步
- 按 {yolov8m, yolo26m, yolov10m} × 自有数据 fine-tune × 7 切片跑复评矩阵;
- day 切片 per-image 诊断(四模型全 1 TP 太反常);night 专项评测;
- truck/bus 类别处理方案(合并 vehicle / 补标注);
- yolo26m 的 ONNX/TensorRT 导出与 INT8 小实验(FR-9 的第一块试金石)。
本文所有数据来自工作区内实验产物,原始文件:eval_results_rerun/、上一轮 eval_results/。实验口径与 PRD FR-3/DR-3、§9 对齐。

浙公网安备 33010602011771号