第 6 篇|YOLOv8 实战:从零开始训练自己的数据集(详细步骤 + 避坑指南)
这篇是全网最完整的 YOLOv8 自定义数据集训练保姆级教程,从图片收集→标注→划分→格式转换→环境→训练→推理→部署→排错全覆盖。你只需要替换类别和图片,就能训练出自己的目标检测模型。
大家好,这里是 YOLO 理论与改进实战系列 第 6 篇。前 5 篇我们已经彻底讲透了 YOLO 的核心思想、进化史、网络结构、标签分配机制和损失函数 —— 从 “理论层面” 帮大家从 “会用 YOLO” 进阶到 “懂 YOLO”。今天,我们正式进入实战落地环节,也是大家最关心的内容:如何用 YOLOv8 从零开始训练自己的数据集,实现自定义目标检测(比如检测自己标注的猫、狗、车辆、工业缺陷等)。
这一篇,我会做到 **「极致详细、保姆级拆解」,全程手把手教学,每一个步骤都配具体操作、命令代码、参数说明、常见问题 **,甚至包含 “鼠标点击哪里、输入什么命令、遇到报错怎么解决”,无论你是新手还是有一定基础,都能跟着步骤完成训练。
重点覆盖:数据集准备(标注、划分、格式转换)、环境配置(从 0 搭建 PyTorch 环境)、训练全流程(配置文件修改、参数设置、训练监控)、常见坑排查(训练中断、损失不收敛、精度上不去、推理报错)、模型导出与部署(ONNX/TensorRT 快速推理),全程贴合 ultralytics YOLOv8 官方最新版本,避免出现 “命令失效、版本不兼容” 等问题。
同时,衔接上一篇的损失函数内容 —— 训练过程中会讲解如何结合损失函数调整权重,让模型精度达到最佳,做到 “理论 + 实战” 无缝衔接 。建议大家收藏本文,训练时直接对照操作,避开所有新手坑。
0. 前言:实战前必看(明确目标、准备工具)
在开始实战前,我们先明确 2 个核心前提,避免后续操作走弯路:
0.1 实战目标
本次实战将以 「自定义目标检测(猫、狗、汽车三类检测)」 为目标,从零完成:标注数据集 → 配置环境 → 训练模型 → 模型评估 → 推理测试 → 模型部署最终实现:输入一张图片,模型自动框选出猫 / 狗 / 汽车,输出坐标、类别和置信度。
0.2 准备工具与环境要求
提前备好,避免训练中途缺工具、报兼容错:
- 硬件:建议 NVIDIA 独显(显存≥6G),CPU 无强制要求,内存≥8G,硬盘≥10G;
- 标注工具:LabelImg(最简单,新手首选);
- 编程工具:PyCharm / VS Code;
- 系统终端:Windows 用 CMD/PowerShell,Linux/Mac 用终端;
- Python 版本:3.8~3.11(推荐 3.9,最稳定);
- 框架:PyTorch 1.13~2.1 + ultralytics 8.0+。
1. 第一步:数据集准备(核心!决定模型上限)
数据集是训练的根基,数据质量 = 模型上限。流程:收集图片 → 标注 → 划分训练 / 验证 / 测试集 → VOC 转 YOLO 格式
1.1 收集图片(数量 + 质量标准)
- 数量:每类目标至少 50 张,推荐 100~200 张 / 类,总数 300~600 张最佳;
- 质量:清晰、目标完整、姿态多样、背景多样;
- 格式:统一
.jpg/.png,不要用中文文件名; - 存放:新建文件夹
yolov8_custom_dataset→ 里面建images,所有图片放这里。
1.2 LabelImg 标注(零难度)
YOLOv8 用 YOLO 格式训练,LabelImg 默认输出 VOC(XML),后面我们代码一键转换。
- 安装(CMD 执行):
pip install labelImg -i https://pypi.tuna.tsinghua.edu.cn/simple
- 打开:CMD 输入
labelImg - 关键设置:
File → Open Dir:选你的images文件夹Change Save Dir:在yolov8_custom_dataset里新建labels,选它- 勾选
View → Auto Save
- 开始标注:
- 快捷键
W:画框 - 输入英文类别:
cat、dog、car D下一张,A上一张
- 快捷键
- 标注要求:
- 框要贴紧目标,不紧不松
- 类别绝对不能标错
- 不要漏标、多标
标注完:images 里是图片,labels 里是对应 XML 标注。
1.3 自动划分数据集(train:val:test = 7:2:1)
手动挪文件容易乱,直接用代码一键划分。
在 yolov8_custom_dataset 下新建 split_dataset.py:
import os
import shutil
import random
# 你的数据集根目录
dataset_root = "yolov8_custom_dataset"
train_ratio = 0.7
val_ratio = 0.2
test_ratio = 0.1
# 创建文件夹
folders = [
f"{dataset_root}/images/train",
f"{dataset_root}/images/val",
f"{dataset_root}/images/test",
f"{dataset_root}/labels/train",
f"{dataset_root}/labels/val",
f"{dataset_root}/labels/test"
]
for f in folders:
os.makedirs(f, exist_ok=True)
# 读取图片
img_files = [f for f in os.listdir(f"{dataset_root}/images") if f.endswith(('.jpg','.png'))]
random.seed(42)
random.shuffle(img_files)
# 划分数量
total = len(img_files)
train_num = int(total*train_ratio)
val_num = int(total*val_ratio)
test_num = total - train_num - val_num
train_files = img_files[:train_num]
val_files = img_files[train_num:train_num+val_num]
test_files = img_files[train_num+val_num:]
def move_files(files, split):
for f in files:
# 移动图片
shutil.copy(f"{dataset_root}/images/{f}", f"{dataset_root}/images/{split}/{f}")
# 移动标注
xml = f.replace(".jpg",".xml").replace(".png",".xml")
if os.path.exists(f"{dataset_root}/labels/{xml}"):
shutil.copy(f"{dataset_root}/labels/{xml}", f"{dataset_root}/labels/{split}/{xml}")
move_files(train_files, "train")
move_files(val_files, "val")
move_files(test_files, "test")
print(f"划分完成!总:{total} 训练:{train_num} 验证:{val_num} 测试:{test_num}")
运行后,自动生成 train/val/test 结构。
1.4 VOC (XML) → YOLO (TXT) 格式转换
YOLOv8 只认 TXT 格式(归一化坐标),XML 不能直接训练。
在 yolov8_custom_dataset 下新建 voc2yolo.py:
import os
import xml.etree.ElementTree as ET
# ===================== 只改这里 =====================
classes = ["cat", "dog", "car"] # 你的类别,顺序必须和标注一致
# ====================================================
dataset_root = "yolov8_custom_dataset"
splits = ["train","val","test"]
def convert(xml_path):
tree = ET.parse(xml_path)
root = tree.getroot()
size = root.find("size")
w = int(size.find("width").text)
h = int(size.find("height").text)
lines = []
for obj in root.findall("object"):
cls = obj.find("name").text
if cls not in classes: continue
cls_id = classes.index(cls)
xmlbox = obj.find("bndbox")
x1 = float(xmlbox.find("xmin").text)
y1 = float(xmlbox.find("ymin").text)
x2 = float(xmlbox.find("xmax").text)
y2 = float(xmlbox.find("ymax").text)
# YOLO 归一化
cx = (x1 + x2) / 2 / w
cy = (y1 + y2) / 2 / h
bw = (x2 - x1) / w
bh = (y2 - y1) / h
lines.append(f"{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}\n")
return lines
for split in splits:
xml_dir = f"{dataset_root}/labels/{split}"
for xml in os.listdir(xml_dir):
if not xml.endswith(".xml"): continue
lines = convert(f"{xml_dir}/{xml}")
with open(f"{xml_dir}/{xml.replace('.xml','.txt')}", "w") as f:
f.writelines(lines)
print("✅ VOC → YOLO 转换完成!")
运行后,labels/train/val/test 里全是 TXT 文件,数据集准备完成!
2. 第二步:环境配置(从 0 搭建,不报错版)
2.1 安装 Python 3.9
- 官网下载:Python 3.9.13
- 必须勾选 Add Python to PATH
- 验证:CMD 输入
python --version
2.2 安装 CUDA(GPU 必须)
- 查看支持版本:NVIDIA 控制面板 → 帮助 → 系统信息 → 组件
- 推荐安装 CUDA 11.8(最兼容)
- 验证:
nvcc -V
2.3 安装 PyTorch
GPU(CUDA 11.8):
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
CPU:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
验证:
import torch
print(torch.cuda.is_available()) # True=成功
2.4 安装 ultralytics(YOLOv8 官方库)
pip install ultralytics opencv-python pillow -i https://pypi.tuna.tsinghua.edu.cn/simple
验证:yolo version
3. 第三步:YOLOv8 训练(全程复制命令)
3.1 新建模型配置
在项目里新建 config 文件夹 → 新建 yolov8_custom.yaml:
yaml
nc: 3 # 类别数量
names: ["cat","dog","car"] # 类别名称
depth_multiple: 0.33
width_multiple: 0.25
anchors:
- [10,13, 16,30, 33,23]
- [30,61, 62,45, 59,119]
- [116,90, 156,198, 373,326]
3.2 新建数据集配置 data.yaml
在 yolov8_custom_dataset 里新建:
yaml
train: yolov8_custom_dataset/images/train
val: yolov8_custom_dataset/images/val
test: yolov8_custom_dataset/images/test
nc: 3
names: ["cat","dog","car"]
3.3 启动训练(复制即用)
yolo train model=config/yolov8_custom.yaml data=yolov8_custom_dataset/data.yaml epochs=100 batch=8 imgsz=640 device=0 pretrained=True
参数说明
epochs=100:训练轮数,小数据集 50~100 足够batch=8:显存小就改 4/2imgsz=640:输入尺寸device=0:用第一张 GPUpretrained=True:迁移学习,必须开,精度暴涨
3.4 训练正常标志
- 损失
loss持续下降 - mAP@0.5 逐步上升
- 模型保存在
runs/detect/train/weights/best.pt
4. 第四步:模型评估 + 推理测试
4.1 模型评估(看精度)
yolo val model=runs/detect/train/weights/best.pt data=yolov8_custom_dataset/data.yaml
看指标:
- mAP@0.5 ≥ 0.7 合格
- ≥ 0.8 优秀
4.2 推理测试(看实际效果)
测试文件夹:
yolo predict model=best.pt source=yolov8_custom_dataset/images/test save=True
测试单张图片:
yolo predict model=best.pt source=test.jpg save=True
结果保存在 runs/detect/predict。
5. 第五步:模型导出与部署(落地可用)
5.1 导出 ONNX(通用部署格式)
yolo export model=best.pt format=onnx imgsz=640
5.2 ONNX 推理代码(可直接部署)
import onnxruntime as ort
import cv2
import numpy as np
model_path = "best.onnx"
img_path = "test.jpg"
classes = ["cat","dog","car"]
imgsz = 640
conf_thres = 0.5
session = ort.InferenceSession(model_path)
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name
img = cv2.imread(img_path)
h, w = img.shape[:2]
scale = min(imgsz/w, imgsz/h)
new_w, new_h = int(w*scale), int(h*scale)
resized = cv2.resize(img, (new_w, new_h))
padded = np.zeros((imgsz, imgsz, 3), dtype=np.uint8)
padded[:new_h, :new_w] = resized
input = padded.transpose(2,0,1)/255.0
input = input[None].astype(np.float32)
pred = session.run([output_name], {input_name:input})[0]
for box in pred[0]:
conf = box[4]
if conf < conf_thres: continue
cx, cy, bw, bh = box[0], box[1], box[2], box[3]
x1 = int((cx - bw/2)*imgsz/scale)
y1 = int((cy - bh/2)*imgsz/scale)
x2 = int((cx + bw/2)*imgsz/scale)
y2 = int((cy + bh/2)*imgsz/scale)
cls = np.argmax(box[5:])
cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2)
cv2.putText(img, f"{classes[cls]} {conf:.2f}", (x1,y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
cv2.imwrite("result.jpg", img)
cv2.imshow("out", img)
cv2.waitKey(0)
6. 新手高频坑排查(完整版)
坑 1:找不到 data.yaml
- 原因:路径错 / 没创建
- 解决:用绝对路径,不要中文路径
坑 2:CUDA out of memory 显存爆炸
- 解决顺序:
batch=8 → 4 → 2imgsz=640 → 480 → 320- 换
yolov8n最轻量模型 - 关闭占用 GPU 的软件
坑 3:loss 不下降,模型不收敛
- 标注错误 / 图片太糊 / 类别写错
- 没开
pretrained=True - 解决:清洗数据集 + 开启预训练
坑 4:推理漏检、误检超多
- 数据集场景太单一 → 补充不同背景、角度、光照
- 目标太小 → 调高分辨率
imgsz=640 - 置信度太高 → 推理加
conf=0.25 - 数据量太少 → 每类至少补到 100 张
- 训练轮数不够 → epochs 改 100~150
- 标注不精准 → 重新检查框和类别
- 开启数据增强:训练命令加
augment=True
坑 5:类别全错
- 原因:
classes顺序和标注不一致 - 解决:
voc2yolo.py、yaml三处类别完全一致
坑 6:训练中断,如何继续训练
yolo train model=runs/detect/train/weights/last.pt data=data.yaml epochs=100 resume=True
坑 7:TXT 文件为空
- 图片里没目标,直接删除空 TXT 即可
坑 8:mAP 突然掉到 0
- 标注混乱 / 数据集路径变动
- 解决:重新检查划分与格式
坑 9:GPU 不调用,一直用 CPU
- PyTorch 没装 GPU 版本
- 重装对应 CUDA 版本的 torch
坑 10:预测框漂移、不准
- 标注框不贴合目标
- 图片分辨率太低
- 解决:精准标注 + 高分辨率训练
7. 训练精度提升最终方案(直接照做)
- 每类目标 ≥ 100 张
- 标注精准、无错标、无漏标
- 开启
pretrained=True - 训练轮数 100
- 开启增强
augment=True - 分辨率 640
- 清洗脏数据(模糊、重复、过小)
- 用
best.pt推理
按这套流程,自定义数据集 mAP@0.5 稳定 0.7~0.9。
总结
这篇是全网最完整的 YOLOv8 自定义数据集训练保姆级教程,从图片收集→标注→划分→格式转换→环境→训练→推理→部署→排错全覆盖。你只需要替换类别和图片,就能训练出自己的目标检测模型。
更多推荐



所有评论(0)