【YOLO 入门到精通 07】验证与性能评估:读懂 mAP、Precision、Recall
标签:mAP 模型评估 混淆矩阵 Precision Recall 过拟合 难度:⭐⭐⭐ | 阅读时长:约 55 分钟 | 系列:第 07/12 集 前置:06 训练 | 下一集:08 推理指南

写在前面
训练完不等于能用。一个 mAP 0.3 的模型上线后可能误报满天飞。验证就是给模型「体检」——用数据说话,决定能不能部署。
本集教你读懂每一个指标,并学会从混淆矩阵定位问题类别。
本集学习目标
- 理解 IoU、Precision、Recall、mAP
- 使用 val 模式评估模型
- 分析混淆矩阵和 PR 曲线
- 判断过拟合并选择最佳 conf 阈值
文章目录
- 【YOLO 入门到精通 07】验证与性能评估:读懂 mAP、Precision、Recall
-
- 写在前面
- 本集学习目标
- 7.1 为什么需要验证
-
- 过拟合识别
- 7.2 核心指标详解
-
- IoU(交并比)
- Precision & Recall
- 混淆矩阵
- 7.3 mAP 详解
- 7.4 执行验证
-
- 输出解读
- 7.5 可视化分析
-
- 选最佳 conf
- 7.6 模型对比
- 7.7 错误分析
-
- 逐类 AP 分析
- 7.8 踩坑指南
- 7.9 常见问题 FAQ
- 7.10 本集小结
7.1 为什么需要验证
| Train | 训练集 | 学习 |
| Val | 验证集 | 调参、选 best.pt |
| Test | 测试集 | 最终报告 |
过拟合识别
Loss
│ 训练损失 ────────────
│ ╲
│ 验证损失 ╲____╱ ← 过拟合:验证损失回升
└──────────────────────→ Epoch
7.2 核心指标详解
IoU(交并比)
IoU = 交集面积 / 并集面积
IoU=1.0 完全重合 | IoU=0.5 一半重叠(常用阈值)| IoU=0 不重叠
def iou(box1, box2): # [x1,y1,x2,y2]
x1,y1 = max(box1[0],box2[0]), max(box1[1],box2[1])
x2,y2 = min(box1[2],box2[2]), min(box1[3],box2[3])
inter = max(0,x2–x1) * max(0,y2–y1)
a1 = (box1[2]–box1[0])*(box1[3]–box1[1])
a2 = (box2[2]–box2[0])*(box2[3]–box2[1])
return inter / (a1 + a2 – inter + 1e-6)
Precision & Recall
| Precision | TP/(TP+FP) | 预测对的占多少 | 提高 conf |
| Recall | TP/(TP+FN) | 找到了多少真目标 | 降低 conf |
| F1 | 2PR/(P+R) | 综合平衡 | 找最佳 conf |
混淆矩阵
| 实际正 | TP | FN(漏检) |
| 实际负 | FP(误检) | TN |
7.3 mAP 详解
| mAP@0.5 | IoU≥0.5 即算对 | 宽松 |
| mAP@0.5:0.95 | IoU 0.5~0.95 步长0.05 平均 | COCO 标准 |
| mAP@0.75 | IoU≥0.75 | 严格 |
| <0.3 | 较差 |
| 0.3~0.5 | 一般 |
| 0.5~0.7 | 良好 |
| 0.7~0.9 | 优秀 |
| >0.9 | 非常优秀 |
7.4 执行验证
yolo detect val model=runs/detect/train/weights/best.pt data=my_dataset.yaml
from ultralytics import YOLO
model = YOLO("runs/detect/train/weights/best.pt")
metrics = model.val(data="my_dataset.yaml", imgsz=640, conf=0.001, plots=True)
print(f"mAP50: {metrics.box.map50:.4f}")
print(f"mAP50-95: {metrics.box.map:.4f}")
print(f"Precision: {metrics.box.mp:.4f}")
print(f"Recall: {metrics.box.mr:.4f}")
输出解读
Class Images Instances Box(P R mAP50 mAP50-95)
all 50 150 0.85 0.78 0.82 0.65
cat 50 80 0.90 0.85 0.88 0.72
dog 50 70 0.80 0.71 0.76 0.58
7.5 可视化分析
训练后在 runs/detect/val/ 查看:
| confusion_matrix.png | 类别混淆 |
| PR_curve.png | 精确率-召回率 |
| F1_curve.png | 最佳 conf 参考 |
| val_batch0_pred.jpg | 预测 vs 真实对比 |
选最佳 conf
for conf in [0.1, 0.25, 0.5, 0.7]:
m = model.val(data="data.yaml", conf=conf, verbose=False)
p, r = m.box.mp, m.box.mr
f1 = 2*p*r/(p+r+1e-6)
print(f"conf={conf}: P={p:.3f} R={r:.3f} F1={f1:.3f}")
7.6 模型对比
models = {"n": "runs/n/weights/best.pt", "s": "runs/s/weights/best.pt"}
for name, path in models.items():
m = YOLO(path).val(data="data.yaml", verbose=False)
print(f"yolo26{name}: mAP={m.box.map:.4f}, P={m.box.mp:.4f}, R={m.box.mr:.4f}")
| n | 较低 | 最快 | 实时 |
| m | 中等 | 中等 | 通用 |
| x | 最高 | 最慢 | 离线高精度 |
7.7 错误分析
| 定位差 | 框偏移 | 看 box_loss |
| 分类错 | 张冠李戴 | 看混淆矩阵 |
| 漏检 | Recall 低 | 降 conf / 增数据 |
| 误检 | Precision 低 | 升 conf |
| 重复框 | 同目标多个框 | 调 iou |
逐类 AP 分析
metrics = model.val(data="data.yaml")
for i, ap in enumerate(metrics.box.ap50):
print(f"{model.names[i]}: AP50={ap:.4f}")
# 找最差类别 → 针对性增数据
worst = sorted(zip(model.names.values(), metrics.box.ap50), key=lambda x: x[1])[:3]
print("需改进:", worst)
7.8 踩坑指南
| 只看 mAP50 | 生产看 mAP50-95 |
| val 用训练集 | 必须独立 val 集 |
| conf=0.25 验证 | 验证用 conf=0.001 得完整 PR 曲线 |
| 指标好但实战差 | 检查 val 分布是否代表真实场景 |
7.9 常见问题 FAQ
Q1:mAP 多少能上线? A:视业务而定。安防误报代价高→重 Precision;漏检代价高→重 Recall。一般 mAP50-95 > 0.5 可尝试部署。
Q2:训练和验证 mAP 差很多? A:过拟合。增数据、早停、减 epochs。
7.10 本集小结
| IoU | 定位准不准 |
| Precision | 误报多不多 |
| Recall | 漏检多不多 |
| mAP50-95 | 综合性能 |
网硕互联帮助中心







评论前必须登录!
注册