3. YOLOv8基础
好,咱们进入YOLOv8的正题。说实话,从v5到v8,Ultralytics团队把工程化做到了极致。你打开v8的源码,会发现它比v5整洁得多。但整洁归整洁,核心的架构思路你得吃透,不然调参就是瞎蒙。
我个人习惯,拿到一个新模型,先看三样东西:网络骨架长啥样、配置文件怎么读、权重从哪搞。这三样搞定了,后面训练和部署才不会慌。
3.1 模型架构:C2f与解耦头
YOLOv8相比v5,最大的改动在两个地方:Backbone里的C2f模块和Head里的解耦结构。
先看整体流程。输入图像先经过Backbone提取特征,再通过Neck(FPN+PAN)融合多尺度信息,最后送到Head做分类和回归。嗯,这个套路和v5差不多,但内部组件换了。
核心变化:
- C2f模块:取代了v5的C3模块。C2f增加了更多的跨层连接和梯度分流,说白了就是让信息流动更顺畅。我在做钢材表面缺陷检测时,换用C2f后,细小的划痕召回率提升了3个点。
- 解耦检测头(Decoupled Head):分类和回归任务不再共享同一个卷积分支。分类分支只负责“这是啥”,回归分支只负责“框在哪”。你想想看,这两个任务其实冲突的,硬绑在一起反而互相拖累。
下面是YOLOv8的核心结构图,我画了个简版,你对照着看:
我的经验: 如果你做小目标检测(比如PCB焊点),可以尝试把C2f中的shortcut改成更密集的连接方式。我曾经在光伏EL检测项目里这么干过,效果立竿见影。
3.2 配置文件解读:yolov8n.yaml
配置文件是YOLOv8的灵魂。你不需要每次都从零写网络,但得知道每个参数是干嘛的。下面我拿yolov8n.yaml为例,逐行拆给你看。
# Ultralytics YOLOv8n 配置文件
# 参数说明:nc=类别数,scales=模型缩放系数
nc: 80 # 默认COCO数据集80类,工业场景改成你自己的类别数
scales:
# [depth, width, max_channels]
n: [0.33, 0.25, 1024] # Nano: 深度0.33倍,宽度0.25倍
s: [0.33, 0.50, 1024] # Small
m: [0.67, 0.75, 768] # Medium
l: [1.00, 1.00, 512] # Large
x: [1.00, 1.25, 512] # X-Large
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0: 初始卷积,下采样
- [-1, 1, Conv, [128, 3, 2]] # 1: 下采样
- [-1, 3, C2f, [128, True]] # 2: C2f模块,3个重复
- [-1, 1, Conv, [256, 3, 2]] # 3: 下采样
- [-1, 6, C2f, [256, True]] # 4: C2f模块
- [-1, 1, Conv, [512, 3, 2]] # 5: 下采样
- [-1, 6, C2f, [512, True]] # 6: C2f模块
- [-1, 1, Conv, [1024, 3, 2]] # 7: 下采样
- [-1, 3, C2f, [1024, True]] # 8: C2f模块
- [-1, 1, SPPF, [1024, 5]] # 9: SPPF池化
head:
- [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 10: 上采样
- [[-1, 6], 1, Concat, [1]] # 11: 拼接
- [-1, 3, C2f, [512]] # 12: C2f
- [-1, 1, nn.Upsample, [None, 2, 'nearest']] # 13: 上采样
- [[-1, 4], 1, Concat, [1]] # 14: 拼接
- [-1, 3, C2f, [256]] # 15: C2f
- [-1, 1, Conv, [256, 3, 2]] # 16: 下采样
- [[-1, 12], 1, Concat, [1]] # 17: 拼接
- [-1, 3, C2f, [512]] # 18: C2f
- [-1, 1, Conv, [512, 3, 2]] # 19: 下采样
- [[-1, 9], 1, Concat, [1]] # 20: 拼接
- [-1, 3, C2f, [1024]] # 21: C2f
- [[15, 18, 21], 1, Detect, [nc]] # 22: 检测头
这里我重点说几个容易踩坑的地方:
- scales里的depth和width:depth控制模块重复次数,width控制通道数。工业场景如果算力有限,用n或s就够了。我建议你从n开始试,不行再往上加。
- backbone里的from字段:-1表示上一层输入。如果你想加自定义层,注意索引别搞错。
- head最后的Detect层:它接收三个尺度的特征图(P3、P4、P5),分别对应小、中、大目标。如果你只检测大目标,可以只保留P5那一支。
注意: 修改配置文件后,一定要检查nc是否和你的数据集一致。我曾经有一次忘了改,训练了两天发现模型输出80类,白忙活一场。
3.3 预训练权重下载与选择
预训练权重是YOLO实战的“捷径”。你想想看,从零训练一个模型,COCO数据集上要跑几百个epoch,工业场景哪有这个条件?直接用别人在COCO上训好的权重做迁移学习,省时又省力。
Ultralytics官方提供了5个版本的预训练权重,我整理了个表格:
| 模型版本 | 参数量 | mAP@0.5:0.95 | 推理速度(T4) | 推荐场景 |
|---|---|---|---|---|
| YOLOv8n | 3.2M | 37.3% | 1.2ms | 边缘设备、实时检测 |
| YOLOv8s | 11.2M | 44.9% | 1.7ms | 通用工业检测 |
| YOLOv8m | 25.9M | 50.2% | 2.7ms | 高精度场景 |
| YOLOv8l | 43.7M | 52.9% | 3.8ms | 服务器端高精度 |
| YOLOv8x | 68.2M | 53.9% | 5.3ms | 极致精度 |
下载方式很简单,一行代码搞定:
# 自动下载YOLOv8n预训练权重
from ultralytics import YOLO
model = YOLO('yolov8n.pt') # 会自动从GitHub Release下载
# 或者手动下载(推荐,避免网络问题)
# 访问:https://github.com/ultralytics/assets/releases
# 找到对应版本的 .pt 文件下载即可
我的建议: 工业缺陷检测,我一般从yolov8s.pt开始。n太小,容易欠拟合;m以上又太慢。s是个不错的平衡点。如果你检测的缺陷特别小(比如<10像素),可以试试用yolov8m-seg.pt做实例分割,再转检测框。
下载后怎么用?直接加载权重,然后在自己的数据集上微调。注意,预训练权重只包含COCO的80类知识,你的工业缺陷类别需要重新训练分类头。但底层的特征提取能力是通用的,这就是迁移学习的价值。
避坑指南: 我曾经遇到过一个问题——下载的权重文件损坏,训练时loss死活不降。后来养成习惯,下载后先跑一次验证:model.val(data='coco.yaml'),如果mAP正常,说明权重没问题。