YOLOv8 基础实战:模型结构解析、权重下载与推理
YOLOv8 是 Ultralytics 团队在 2023 年初推出的目标检测框架。说实话,从 v5 到 v8 的跨度挺大的——不光是模型结构改了,连训练和推理的 API 都重新设计了。我个人习惯把 v8 看作一个「工程化更彻底」的版本,它把数据增强、模型导出、部署转换都集成到了一个库里。
这一章我们先把 YOLOv8 的模型结构拆开看看,然后下载官方权重,最后用预训练模型跑几个推理 demo。嗯,动手之前先把原理理清楚。
YOLOv8 模型结构总览
YOLOv8 延续了「Backbone + Neck + Head」的三段式设计。但和 v5 相比,每个模块都有调整。我画了一张结构图,方便你对照着看。
核心模块详解
1. Backbone:CSPDarknet 的进化
YOLOv8 的 Backbone 还是基于 CSPDarknet 的架构,但把原来的 C3 模块换成了 C2f。C2f 的全称是「Cross Stage Partial with 2 convolutions and feature fusion」——说白了就是让梯度在跨层连接时流得更顺畅。
我在项目中对比过 C3 和 C2f 的参数量:同样深度下,C2f 的 FLOPs 略高一点,但 mAP 能提升 0.5~1 个点。对于追求精度的场景,这个 trade-off 是值得的。
| 模块 | 输入通道 | 输出通道 | 层数 | 说明 |
|---|---|---|---|---|
| Conv + BN + SiLU | 3 | 64 | 1 | 初始下采样,步长 2 |
| C2f ×3 | 64 | 128 | 3 | 特征提取,步长 2 |
| C2f ×6 | 128 | 256 | 6 | 深层特征,步长 2 |
| C2f ×6 | 256 | 512 | 6 | 最深层,步长 2 |
| SPPF | 512 | 512 | 1 | 空间金字塔池化 |
2. Neck:FPN + PAN 的经典组合
Neck 部分负责把 Backbone 输出的多尺度特征融合起来。YOLOv8 沿用了 FPN(自顶向下)和 PAN(自底向上)的双向融合结构。这样做的好处是:小目标能从高层语义中受益,大目标也能保留底层细节。
具体来说,Neck 会输出三个尺度的特征图:
- P3(80×80):负责小目标检测
- P4(40×40):负责中目标检测
- P5(20×20):负责大目标检测
3. Head:解耦检测头
这是 YOLOv8 和 v5 最大的区别。v5 的 Head 是耦合的——分类和回归共享同一组卷积。v8 把这两个任务拆开了:
- 分类分支:输出每个 anchor 的类别概率
- 回归分支:输出边界框的坐标偏移
为什么要解耦?我在做行人检测时遇到过一个问题:分类和回归对特征的需求其实不一样。分类更关注「是什么」,回归更关注「在哪里」。共享特征会导致两者互相干扰。解耦之后,每个分支可以专注自己的任务,收敛更快。
官方权重下载
YOLOv8 提供了 5 个不同规模的预训练模型,从轻量到高精度都有。我个人习惯在项目初期先用 nano 版本跑通流程,确认数据没问题后再换大模型。
| 模型 | 参数量 | FLOPs | mAP@0.5:0.95 | 推理速度(T4) | 适用场景 |
|---|---|---|---|---|---|
| YOLOv8n | 3.2M | 8.7G | 37.3 | 1.2ms | 移动端、边缘设备 |
| YOLOv8s | 11.2M | 28.6G | 44.9 | 1.4ms | 轻量级服务器 |
| YOLOv8m | 25.9M | 78.9G | 50.2 | 2.0ms | 通用场景 |
| YOLOv8l | 43.7M | 165.2G | 52.9 | 2.7ms | 高精度场景 |
| YOLOv8x | 68.2M | 257.8G | 53.9 | 3.5ms | 极致精度 |
下载权重很简单,一行代码搞定:
# 自动下载 YOLOv8n 权重(首次运行会自动下载)
from ultralytics import YOLO
model = YOLO('yolov8n.pt') # 会自动从 GitHub Release 下载
权重文件会保存在当前目录下。如果你想手动下载,也可以去 Ultralytics 的 GitHub Release 页面找。嗯,不过我建议直接用代码自动下载,省事。
使用预训练模型进行推理
推理是 YOLOv8 最爽的部分——API 设计得非常简洁。我们分三种场景来看:图片、视频、摄像头。
图片推理
from ultralytics import YOLO
# 加载模型
model = YOLO('yolov8n.pt')
# 单张图片推理
results = model('bus.jpg')
# 批量图片推理
results = model(['img1.jpg', 'img2.jpg', 'img3.jpg'])
# 查看结果
for result in results:
boxes = result.boxes # 边界框
print(f"检测到 {len(boxes)} 个目标")
for box in boxes:
x1, y1, x2, y2 = box.xyxy[0].tolist()
conf = box.conf[0].item()
cls = box.cls[0].item()
print(f"类别: {int(cls)}, 置信度: {conf:.2f}, 坐标: ({x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f})")
视频推理
视频推理其实就是逐帧处理。YOLOv8 封装好了,你只需要传入视频路径:
model = YOLO('yolov8n.pt')
# 视频推理,自动保存结果
results = model('test_video.mp4', save=True)
# 如果想实时显示,可以用 stream=True
results = model('test_video.mp4', stream=True)
for result in results:
# 处理每一帧
pass
我在项目中处理过一段 10 分钟的 4K 视频,用 YOLOv8m 跑,T4 显卡上大概花了 3 分钟。如果换成 YOLOv8n,能压缩到 1 分钟以内。所以视频推理时,我建议先评估一下精度要求,再选模型。
摄像头实时推理
摄像头推理和视频推理几乎一样,只是输入源变成了摄像头 ID:
model = YOLO('yolov8n.pt')
# 使用摄像头 0(默认摄像头)
results = model(source=0, show=True, conf=0.5)
# 或者用更底层的写法
import cv2
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
results = model(frame)
annotated_frame = results[0].plot()
cv2.imshow('YOLOv8 Detection', annotated_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
推理参数调优
YOLOv8 的推理函数支持很多参数,我列几个常用的:
| 参数 | 默认值 | 说明 |
|---|---|---|
| conf | 0.25 | 置信度阈值,低于此值的检测框会被过滤 |
| iou | 0.7 | NMS 的 IoU 阈值,值越小重复框越少 |
| imgsz | 640 | 输入图片尺寸,越大精度越高但速度越慢 |
| max_det | 300 | 每张图片最大检测目标数 |
| device | None | 指定设备,如 'cpu'、'cuda:0' |
举个例子,如果你想要高精度检测:
results = model('bus.jpg', conf=0.5, iou=0.5, imgsz=1280)
如果你想要快速推理:
results = model('bus.jpg', conf=0.3, iou=0.7, imgsz=320)
本章小结
这一章我们做了三件事:
- 拆解了 YOLOv8 的 Backbone、Neck、Head 结构,重点讲了 C2f 和解耦检测头
- 下载了官方预训练权重,了解了 5 个模型的性能差异
- 用预训练模型跑了图片、视频、摄像头三种推理场景
说实话,YOLOv8 的 API 设计得确实好——几行代码就能跑通一个完整的检测流程。但别急着高兴,真正的工作量在后面:数据标注、模型训练、调参、部署……这些才是硬骨头。