4. YOLOv8模型训练实战:配置训练参数、启动训练、观察Loss曲线、模型评估与导出
好,到了真正动手的环节了。前面我们聊了数据集怎么准备、环境怎么搭,现在终于可以跑训练了。说实话,我第一次在树莓派上跑YOLOv8训练时,心里也没底——怕显存不够、怕训练到一半崩了、怕Loss曲线像心电图一样乱跳。但别担心,这一章我会把每一步拆开讲清楚,你跟着走就行。
4.1 训练参数配置:别让默认值坑了你
YOLOv8的训练参数很多,但真正需要你动手调的,其实就那么几个。我个人习惯是先跑一个“探路”版本,参数保守一点,看看数据有没有问题,再回头精调。
下面这个配置,是我在树莓派4B上验证过的。显存只有4GB,所以batch size不能大。
from ultralytics import YOLO
# 加载预训练模型(轻量版)
model = YOLO('yolov8n.pt') # n = nano,最适合树莓派
# 训练参数配置
results = model.train(
data='dataset/data.yaml', # 数据集配置文件
epochs=100, # 训练轮数
batch=8, # 批次大小(树莓派建议4-8)
imgsz=320, # 输入图片尺寸(原版640,我们降一半)
workers=2, # 数据加载线程数
device='cpu', # 强制使用CPU训练
lr0=0.001, # 初始学习率
patience=20, # 早停耐心值
save_period=10, # 每10轮保存一次模型
project='runs/train', # 输出目录
name='yolov8n_custom', # 实验名称
exist_ok=True, # 覆盖已有结果
amp=False # 关闭混合精度(CPU下反而慢)
)
关键参数说明:
- imgsz=320:这是最关键的改动。原版640x640在树莓派上训练太慢,320x320能快3-4倍,精度损失在可接受范围内(约2-3% mAP)。
- batch=8:树莓派4B的4GB内存,batch=8是上限。如果你用树莓派5(8GB版),可以试试batch=16。
- patience=20:如果连续20轮验证集精度没提升,训练自动停止。省电又省时间。
注意:千万不要在树莓派上用GPU训练!虽然YOLOv8支持CUDA,但树莓派的GPU不是NVIDIA的,强行用device='cuda'会报错。老老实实用CPU,虽然慢,但稳定。
4.2 启动训练:一杯咖啡的时间
配置好参数后,直接运行上面的代码就行。训练过程中,你会看到类似这样的输出:
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/100 0.00G 1.234 2.345 1.123 12 320
2/100 0.00G 1.198 2.201 1.089 15 320
3/100 0.00G 1.156 2.134 1.056 10 320
...
嗯,这里要注意:GPU_mem显示0.00G是正常的,因为我们用的是CPU。别被这个吓到,继续跑就行。
我第一次跑的时候,看到Loss值半天不降,差点想中断重来。后来发现,YOLOv8的初始Loss本来就偏高,前10轮主要是在“热身”——让模型先适应你的数据集分布。所以,耐心点,至少等20轮再下结论。
4.3 观察Loss曲线:读懂模型的“心电图”
训练过程中,YOLOv8会自动生成Loss曲线图,保存在runs/train/yolov8n_custom/results.png。这张图很重要,它能告诉你模型学得怎么样。
我一般看三个关键指标:
| 指标 | 正常表现 | 异常表现 | 怎么办 |
|---|---|---|---|
| box_loss | 平稳下降,最后趋于平缓 | 震荡剧烈或突然上升 | 降低学习率,或检查数据标注 |
| cls_loss | 快速下降后稳定在0.5以下 | 一直很高(>2.0) | 检查类别数量是否匹配 |
| dfl_loss | 缓慢下降,波动不大 | 突然跳变 | 可能是batch size太小 |
我的经验:如果Loss曲线在30轮后还在剧烈震荡,别犹豫,直接停掉。调低学习率(比如从0.001降到0.0005)再重新跑。我曾经有一次忘了调学习率,跑了60轮才发现Loss根本没收敛,白白浪费了一下午。
4.4 模型评估:别只看mAP
训练完成后,YOLOv8会自动在验证集上评估。你会看到类似这样的结果:
Model summary: 225 layers, 3,157,200 parameters, 3,157,200 gradients
Class Images Instances Box(P R mAP50 mAP50-95)
all 100 500 0.892 0.856 0.912 0.678
person 100 150 0.934 0.912 0.956 0.734
car 100 200 0.901 0.867 0.923 0.689
bike 100 150 0.842 0.789 0.857 0.612
这里我建议你重点关注两个指标:
- mAP50:IoU阈值0.5时的平均精度。对于部署到树莓派这种边缘设备,mAP50达到0.85以上就算不错了。
- 推理速度:YOLOv8不会直接告诉你FPS,但你可以用下面的代码测一下:
import time
import torch
# 加载训练好的模型
model = YOLO('runs/train/yolov8n_custom/weights/best.pt')
# 模拟树莓派上的推理
dummy_input = torch.randn(1, 3, 320, 320)
start = time.time()
for _ in range(100):
_ = model(dummy_input)
end = time.time()
print(f"平均推理时间: {(end - start)/100*1000:.2f} ms")
print(f"预估FPS: {100/(end - start):.1f}")
树莓派上的目标:
- 推理时间 < 100ms(即FPS > 10)
- mAP50 > 0.80
- 模型大小 < 10MB
如果达不到,别灰心。后面几章我们会讲量化、剪枝、蒸馏,这些技术能把模型再压缩2-4倍。
4.5 模型导出:为部署做准备
训练完成后,我们需要把PyTorch模型导出成适合树莓派部署的格式。YOLOv8支持多种导出格式,我推荐你用ONNX或TensorFlow Lite:
# 导出为ONNX格式(推荐)
model.export(format='onnx', imgsz=320)
# 导出为TensorFlow Lite格式(树莓派上运行更快)
model.export(format='tflite', imgsz=320)
导出后,你会得到两个文件:
best.pt:原始PyTorch模型(约6MB)best.onnx或best.tflite:导出的部署模型(约5.5MB)
我曾经踩过的坑:导出ONNX时,如果遇到算子不支持的错误,多半是因为你用了自定义的模块。YOLOv8原版模型一般没问题,但如果你改了网络结构,导出前记得检查一下。另外,导出TFLite时,树莓派上需要安装tflite-runtime,别装错了包。
4.6 本章知识结构图
下面这张图,把整个训练流程串起来了。你可以把它当作一个检查清单,每一步做完就打个勾。
4.7 常见问题与避坑指南
最后,分享几个我实际踩过的坑,希望能帮你省点时间:
- 训练到一半内存爆了:把batch size降到4,或者把imgsz降到256。树莓派的4GB内存真的很紧张。
- Loss一直不降:检查一下数据集的标注文件,我遇到过标注框坐标超出图片范围的情况,YOLOv8不会报错,但Loss就是降不下去。
- 导出ONNX失败:升级ultralytics到最新版,老版本对ONNX导出的支持不够好。
- 模型在树莓派上跑得慢:别急着优化代码,先看看是不是用了原版640x640的输入尺寸。降到320x320,速度能翻倍。
好了,这一章的内容就到这里。你按照上面的步骤走一遍,应该能顺利跑通YOLOv8的训练流程。记住,第一次训练别追求完美,先跑通再说。后面我们有的是时间优化。