4. 基准模型:加载预训练的YOLOv11模型,评估原始精度与推理速度

剪枝之前,咱们得先干一件事——把原始模型的状态摸清楚。说白了,你得知道手里的牌面到底怎么样,后面剪完才知道是赚了还是亏了。

我个人习惯,每次做模型优化前都会先跑一遍完整的基准测试。这就像体检,先量个血压、测个心率,后面做手术才有参照。你想想看,如果连原始精度都不知道,剪完枝说“掉点了”,掉多少?能不能接受?全凭感觉可不行。

4.1 加载预训练模型

YOLOv11官方提供了在COCO数据集上预训练好的权重。我们直接用Ultralytics的API加载就行,非常方便。

from ultralytics import YOLO

# 加载YOLOv11n预训练模型(nano版本,轻量级)
model = YOLO('yolo11n.pt')

# 你也可以加载其他版本
# model = YOLO('yolo11s.pt')  # small
# model = YOLO('yolo11m.pt')  # medium
# model = YOLO('yolo11l.pt')  # large
# model = YOLO('yolo11x.pt')  # xlarge

这里有个小细节。我第一次用的时候,直接下载了yolo11x.pt,结果发现显存爆了。嗯,后来学乖了,先看自己的硬件条件再选模型大小。你如果用的是消费级显卡,建议从nano或small版本开始。

💡 我的建议: 剪枝课程里,我们统一用yolo11n.pt作为基准。因为小模型剪枝后效果更明显,也更容易观察精度变化。大模型剪枝空间大,但训练成本也高,不适合教学场景。

4.2 评估原始精度

加载完模型,下一步就是跑验证集。YOLOv11的验证接口封装得很好,一行代码就能搞定。

# 在COCO验证集上评估
results = model.val(data='coco8.yaml', batch=16, imgsz=640)

# 打印关键指标
print(f"mAP50: {results.box.map50:.4f}")
print(f"mAP50-95: {results.box.map:.4f}")
print(f"Precision: {results.box.p:.4f}")
print(f"Recall: {results.box.r:.4f}")

跑完之后,你会看到类似这样的输出:

指标 yolo11n yolo11s yolo11m
mAP50 0.521 0.614 0.678
mAP50-95 0.375 0.452 0.513
参数量 2.6M 9.4M 25.1M

这些数据就是你的“原始基线”。我建议你把它记下来,或者直接写到一个配置文件里。后面每次剪枝、微调,都要拿这个基线来对比。

⚠️ 注意: 评估时一定要用和训练时相同的数据集和预处理参数。我曾经犯过一个低级错误——用不同的图片尺寸去验证,结果精度差了3个点,排查了半天才发现是imgsz没对齐。这种坑,踩一次就够了。

4.3 测量推理速度

精度有了,还得看速度。剪枝的核心目标之一就是加速,所以原始模型的推理速度必须测准。

我个人习惯用两种方式测速:

  • 单张图片延迟:测一次推理的时间,适合看极端情况
  • 批量吞吐量:测每秒处理的图片数,更适合实际部署场景
import time
import torch

# 准备测试数据
dummy_input = torch.randn(1, 3, 640, 640).cuda()

# 预热(前几次推理不稳定,先跑几轮)
for _ in range(10):
    _ = model(dummy_input)

# 正式测速
num_iter = 100
start = time.time()
for _ in range(num_iter):
    _ = model(dummy_input)
end = time.time()

avg_latency = (end - start) / num_iter
fps = 1.0 / avg_latency

print(f"平均延迟: {avg_latency*1000:.2f} ms")
print(f"FPS: {fps:.2f}")

这里有个关键点——预热。GPU在第一次推理时会做很多初始化操作,比如CUDA kernel编译、显存分配。如果不预热,测出来的延迟会偏大很多。我第一次测速时没预热,结果延迟比实际高了3倍,差点以为自己模型有问题。

测试条件 yolo11n (FP16) yolo11n (FP32)
平均延迟 (ms) 2.1 3.8
FPS 476 263
显存占用 (MB) 412 724
📊 关键结论: FP16推理比FP32快约45%,显存节省约43%。如果你的硬件支持,建议全程用FP16做基准测试。剪枝后的模型也建议用FP16部署,效果更好。

4.4 保存基准结果

测完精度和速度,别忘了保存结果。我一般会建一个基准日志文件,记录所有关键信息。

import json

baseline = {
    "model": "yolo11n",
    "precision": "fp16",
    "mAP50": 0.521,
    "mAP50-95": 0.375,
    "latency_ms": 2.1,
    "fps": 476,
    "params_M": 2.6,
    "gpu_mem_MB": 412
}

with open("baseline_results.json", "w") as f:
    json.dump(baseline, f, indent=2)

print("基准结果已保存到 baseline_results.json")

这样做的好处是,后面每次剪枝、微调,你都可以自动对比结果。我之前的项目里,团队有5个人同时做不同的剪枝方案,最后全靠这个基准日志来统一对比,省了很多扯皮的时间。

4.5 知识结构总览

这一章的内容其实就三件事:加载模型、测精度、测速度。但别小看这三步,它们是整个剪枝流程的基石。我画了一张图,帮你理清思路。

基准模型评估流程 加载预训练模型 yolo11n.pt 精度评估 mAP50 / mAP50-95 速度评估 延迟 / FPS 保存基准结果 baseline_results.json 📌 关键要点 • 精度和速度必须同时记录,缺一不可 • 测速前一定要预热GPU,否则数据不准 • 建议使用FP16推理,速度更快、显存更省

这张图把整个流程串起来了。你照着这个顺序走一遍,就能拿到完整的基准数据。后面剪枝、微调、再评估,每一步都跟这个基线对比,心里就有底了。

🔑 核心原则: 基准测试不是一次性工作。每次你修改了模型结构、训练策略或者部署环境,都应该重新跑一遍基准。我见过太多人只测一次,后面改了什么都不知道,最后精度掉了都找不到原因。保持基准更新,是模型优化的基本素养。