YOLOv8训练实战:从数据集准备到模型训练全流程(附参数详解)
引言
环境搭建好了,CUDA也装上了,接下来最激动人心的时刻就是——用自己的数据训练YOLOv8模型!很多初学者拿到自己的图片后往往不知道从何下手:数据集要整理成什么格式?命令怎么敲?参数怎么调?训练过程中怎么看效果?
本文将从零开始,手把手带你完成一次完整的YOLOv8训练。我们会详细介绍数据集的组织结构、训练命令的每个参数含义、训练过程的监控方法,并用流程图梳理整个流程。无论你是要做目标检测、实例分割还是分类,YOLOv8的统一接口都能让你快速上手。
一、训练前的准备工作:数据集
YOLOv8支持多种任务,本文以最常用的目标检测为例。你需要准备一批已标注好的图片,标注格式推荐使用YOLO格式(即每个图片对应一个同名的txt文件,每行记录一个目标的类别和归一化坐标)。
1.1 数据集目录结构
创建一个数据集根目录,比如 datasets/Helmet(以安全帽检测为例),目录结构必须严格按照以下方式组织:
datasets/Helmet/
├── images/
│ ├── train/ # 训练图片
│ │ ├── img1.jpg
│ │ └── …
│ └── val/ # 验证图片
│ ├── img2.jpg
│ └── …
└── labels/
├── train/ # 训练标注
│ ├── img1.txt
│ └── …
└── val/ # 验证标注
├── img2.txt
└── …
💡 重要:
- 图片和标注文件的名称必须一一对应(不包括扩展名)。
- 验证集 val 必不可少,用于评估模型在未见过的数据上的表现。
- 如果你没有现成的验证集,可以从训练集中随机抽取20%左右单独存放。
1.2 标注文件格式(YOLO格式)
每个txt文件中,每一行代表一个目标,格式为:
class_id center_x center_y width height
- class_id:类别索引(从0开始)
- center_x, center_y:目标中心点坐标(归一化到0~1,即除以图片宽高)
- width, height:目标宽高(归一化到0~1)
例如,一张图片中有两个目标,其中一个类别是0(人),另一个是1(安全帽),txt文件内容可能如下:
0 0.514 0.361 0.182 0.291
1 0.782 0.512 0.103 0.148
1.3 创建 data.yaml 配置文件
在数据集根目录(或任意位置)创建一个YAML文件,例如 data.yaml,内容如下:
# 数据集根目录路径(可选,如果train/val是绝对路径则可以省略path)
path: /home/user/datasets/Helmet # 数据集的根目录
train: images/train # 训练图片相对路径
val: images/val # 验证图片相对路径
# test: images/test # 测试图片(可选)
nc: 2 # 类别数量(number of classes)
names: ['person', 'helmet'] # 类别名称列表
注意:
- path 可以是绝对路径,也可以是相对路径。如果train/val写的是相对路径,则相对于这个path。
- 如果不想设置path,也可以直接写train和val为绝对路径。
- nc 必须和你的标注文件中的class_id范围一致(0~nc-1)。
二、开始训练:命令与参数详解
在激活了虚拟环境(安装了 ultralytics)的情况下,使用 yolo 命令即可启动训练。最基本的训练命令如下:
yolo train model=yolov8n.pt data=data.yaml epochs=100 imgsz=640
2.1 命令拆解
| model | 预训练模型或配置文件 | yolov8n.pt | 可以是预训练权重(自动下载),也可以是yaml配置文件(从头训练) |
| data | 数据集配置文件的路径 | data.yaml | 上面创建的yaml文件 |
| epochs | 训练轮数 | 100 | 模型遍历整个训练集的次数 |
| imgsz | 输入图片尺寸 | 640 | 训练时会resize到这个大小(通常是正方形) |
2.2 更多常用参数
除了上述必填项,还有很多可以调整的超参数:
| batch | 16 | 批次大小,根据显存调整,越大训练越稳定 |
| device | None | 指定设备,如 device=0(单卡)、device=0,1(多卡)、device=cpu |
| workers | 8 | 数据加载的工作线程数 |
| lr0 | 0.01 | 初始学习率 |
| lrf | 0.01 | 最终学习率因子(最终学习率 = lr0 * lrf) |
| momentum | 0.937 | SGD动量/Adam的beta1 |
| weight_decay | 0.0005 | 权重衰减系数 |
| warmup_epochs | 3.0 | 学习率预热轮数 |
| box | 7.5 | 边界框损失权重 |
| cls | 0.5 | 分类损失权重 |
| dfl | 1.5 | 分布焦点损失权重(仅检测) |
| resume | False | 是否从上次训练断点继续 |
| project | runs/train | 结果保存的项目目录 |
| name | exp | 实验名称,结果保存在 project/name 下 |
| exist_ok | False | 是否覆盖已存在的实验文件夹 |
2.3 训练示例
假设你想训练一个安全帽检测模型,使用yolov8s.pt作为预训练权重,批次大小为32,训练200轮,并在双卡上训练:
yolo train model=yolov8s.pt data=./data.yaml epochs=200 batch=32 imgsz=640 device=0,1
训练开始后,你会看到类似下面的输出,显示每个epoch的损失、精度等指标:
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/200 3.72G 1.487 1.342 1.354 23 640: 100%|██████████| 50/50 [01:23<00:00, 1.66s/it]
Class Images Instances P R mAP50 mAP50-95: 100%|██████████| 10/10 [00:06<00:00, 1.55it/s]
all 50 123 0.951 0.926 0.965 0.789
三、训练流程可视化
3.1 训练流程图
下面用mermaid绘制YOLOv8训练的整体流程,帮助你理解数据流向:
#mermaid-svg-QXCyMl2TmVH4sYAi{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QXCyMl2TmVH4sYAi .error-icon{fill:#552222;}#mermaid-svg-QXCyMl2TmVH4sYAi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QXCyMl2TmVH4sYAi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QXCyMl2TmVH4sYAi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QXCyMl2TmVH4sYAi .marker.cross{stroke:#333333;}#mermaid-svg-QXCyMl2TmVH4sYAi svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QXCyMl2TmVH4sYAi p{margin:0;}#mermaid-svg-QXCyMl2TmVH4sYAi .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi .cluster-label text{fill:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi .cluster-label span{color:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi .cluster-label span p{background-color:transparent;}#mermaid-svg-QXCyMl2TmVH4sYAi .label text,#mermaid-svg-QXCyMl2TmVH4sYAi span{fill:#333;color:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi .node rect,#mermaid-svg-QXCyMl2TmVH4sYAi .node circle,#mermaid-svg-QXCyMl2TmVH4sYAi .node ellipse,#mermaid-svg-QXCyMl2TmVH4sYAi .node polygon,#mermaid-svg-QXCyMl2TmVH4sYAi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QXCyMl2TmVH4sYAi .rough-node .label text,#mermaid-svg-QXCyMl2TmVH4sYAi .node .label text,#mermaid-svg-QXCyMl2TmVH4sYAi .image-shape .label,#mermaid-svg-QXCyMl2TmVH4sYAi .icon-shape .label{text-anchor:middle;}#mermaid-svg-QXCyMl2TmVH4sYAi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QXCyMl2TmVH4sYAi .rough-node .label,#mermaid-svg-QXCyMl2TmVH4sYAi .node .label,#mermaid-svg-QXCyMl2TmVH4sYAi .image-shape .label,#mermaid-svg-QXCyMl2TmVH4sYAi .icon-shape .label{text-align:center;}#mermaid-svg-QXCyMl2TmVH4sYAi .node.clickable{cursor:pointer;}#mermaid-svg-QXCyMl2TmVH4sYAi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QXCyMl2TmVH4sYAi .arrowheadPath{fill:#333333;}#mermaid-svg-QXCyMl2TmVH4sYAi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QXCyMl2TmVH4sYAi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QXCyMl2TmVH4sYAi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QXCyMl2TmVH4sYAi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QXCyMl2TmVH4sYAi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QXCyMl2TmVH4sYAi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QXCyMl2TmVH4sYAi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QXCyMl2TmVH4sYAi .cluster text{fill:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi .cluster span{color:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QXCyMl2TmVH4sYAi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QXCyMl2TmVH4sYAi rect.text{fill:none;stroke-width:0;}#mermaid-svg-QXCyMl2TmVH4sYAi .icon-shape,#mermaid-svg-QXCyMl2TmVH4sYAi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QXCyMl2TmVH4sYAi .icon-shape p,#mermaid-svg-QXCyMl2TmVH4sYAi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QXCyMl2TmVH4sYAi .icon-shape rect,#mermaid-svg-QXCyMl2TmVH4sYAi .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QXCyMl2TmVH4sYAi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QXCyMl2TmVH4sYAi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QXCyMl2TmVH4sYAi :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
已有权重
从头训练
否
是
数据集准备
编写data.yaml
选择预训练模型
yolov8n.pt
yolov8n.yaml
执行训练命令
加载数据加载器
迭代每个epoch
前向传播
计算损失 box+cls+dfl
反向传播/优化
验证集评估
是否达到epochs?
保存最佳模型
训练完成
3.2 实时监控训练
YOLOv8默认会在终端打印每个epoch的训练损失和验证指标。如果你想更直观地观察曲线,可以开启以下工具:
-
TensorBoard:YOLOv8训练时会自动在 runs/train/exp*/ 下生成TensorBoard日志文件。在命令行中运行:
tensorboard –logdir runs/train
然后在浏览器打开 http://localhost:6006,即可查看损失曲线、mAP曲线等。
-
Comet ML / Weights & Biases (wandb):如果你有账号,可以在训练命令中添加参数 project=my_project,YOLOv8会自动集成wandb,将指标同步到云端。
训练完成后,结果会保存在 runs/train/exp/ 目录下,包括:
- weights/best.pt:验证集上表现最好的模型权重
- weights/last.pt:最后一个epoch的权重
- results.png:训练过程中的损失和指标曲线图
- confusion_matrix.png:混淆矩阵
- results.csv:所有指标的详细记录
四、常见问题与调优建议
4.1 训练时报错 “CUDA out of memory”
- 原因:显存不足,batch_size太大或imgsz太大。
- 解决:减小 batch(例如从16降到8),或减小 imgsz(例如从640降到512),或者使用显存更小的模型(yolov8n < yolov8s < yolov8m < yolov8l < yolov8x)。
4.2 模型不收敛(损失不下降)
- 可能原因:学习率不合适、数据集标注错误、类别不平衡。
- 解决:
- 尝试调整学习率 lr0(默认0.01,可以尝试0.001或0.1)。
- 检查标注文件是否和图片对应,类别索引是否超出 nc。
- 如果某类样本太少,可以考虑数据增强或类别加权。
4.3 验证时mAP很低
- 可能原因:过拟合、验证集分布与训练集差异大、模型容量不够。
- 解决:
- 增加数据增强(YOLOv8默认已经较强,可以尝试关闭一些增强看效果)。
- 确保验证集的标注正确且具有代表性。
- 换用更大的模型(如从yolov8n换成yolov8m)。
4.4 训练速度慢
- 可能原因:CPU加载数据瓶颈、GPU利用率低。
- 解决:
- 增加 workers(数据加载线程数),但不要超过CPU核心数。
- 确保 batch 足够大,充分利用GPU。
- 如果使用多卡训练,确保 device 设置正确。
五、使用训练好的模型进行预测
训练完成后,可以用最佳模型进行预测:
yolo predict model=runs/train/exp/weights/best.pt source=./test_images/ save=True
或者用Python:
from ultralytics import YOLO
model = YOLO('runs/train/exp/weights/best.pt')
results = model('test.jpg')
for result in results:
result.show() # 显示图片
result.save(filename='result.jpg') # 保存
总结
至此,你已经完成了从零开始训练YOLOv8模型的全部流程。回顾一下关键步骤:
YOLOv8的强大之处不仅在于它的性能,更在于其简洁统一的API。一旦你掌握了目标检测的训练流程,同样的方法稍作修改就可以用于实例分割、姿态估计和分类任务。


