YOLOv8 自定义目标检测:从数据标注到边缘部署全流程
·
YOLOv8 自定义目标检测:从数据标注到边缘部署全流程
1. 引言
YOLOv8 是 Ultralytics 在 2023 年推出的单阶段目标检测模型,在精度和速度上均超越了前代 YOLOv5/v7。本文将带你完成一个完整的工业级目标检测项目:从数据采集、标注、训练、评估到 TensorRT 边缘部署。
你将学到:
- 使用 Roboflow 进行数据标注与增强
- YOLOv8 检测/分割/分类三种任务的训练
- 超参数调优与 mAP 分析
- 导出 ONNX → TensorRT 并在 Jetson 上实时推理
2. 环境搭建
# 创建虚拟环境
conda create -n yolo python=3.10 -y
conda activate yolo
# 安装 Ultralytics
pip install ultralytics==8.2.0
# 验证安装
yolo checks
期望输出:
Ultralytics 8.2.0 🚀
OS Windows-10
Python 3.10.14
CUDA 12.1 (RTX 3090)
torch 2.1.0+cu121
3. 数据标注与准备
3.1 使用 Roboflow 标注
- 注册 Roboflow 账号
- 创建项目(Object Detection)
- 上传图片 → 使用 Smart Polygon 标注
- 导出为 YOLOv8 格式
3.2 数据集目录结构
dataset/
├── train/
│ ├── images/
│ │ ├── img001.jpg
│ │ └── img002.jpg
│ └── labels/
│ ├── img001.txt # class_id cx cy w h (归一化)
│ └── img002.txt
├── valid/
│ ├── images/
│ └── labels/
├── test/
│ ├── images/
│ └── labels/
└── data.yaml
3.3 data.yaml 配置
# data.yaml
path: /data/custom_dataset
train: train/images
val: valid/images
test: test/images
nc: 3
names: ['scratch', 'dent', 'crack']
标注规范: 标注框应紧贴目标边缘,不留过多空白;遮挡目标仍需标注;困难样本(模糊、小目标)不可忽略。
4. 模型训练
4.1 基础训练
from ultralytics import YOLO
# 加载预训练权重
model = YOLO('yolov8m.pt') # medium 模型,平衡精度与速度
# 训练
results = model.train(
data='data.yaml',
epochs=100,
imgsz=640,
batch=16,
device=0,
project='runs/detect',
name='custom_defect',
patience=20, # 早停轮数
save=True,
save_period=10,
verbose=True,
)
4.2 超参数调优
| 参数 | 推荐值 | 说明 |
|---|---|---|
lr0 | 0.01 | 初始学习率 |
lrf | 0.01 | 最终学习率 = lr0 × lrf |
momentum | 0.937 | SGD 动量 |
weight_decay | 0.0005 | 权重衰减 |
warmup_epochs | 3.0 | 预热轮数 |
box | 7.5 | 边界框损失权重 |
cls | 0.5 | 分类损失权重 |
hsv_h | 0.015 | 色调增强范围 |
mosaic | 1.0 | Mosaic 增强概率 |
小目标优化:
results = model.train(
data='data.yaml',
imgsz=1280, # 更大输入分辨率
batch=8,
anchors=3, # 自动锚框
overlap_mask=True, # 分割任务时重叠掩码
)
4.3 训练监控
# 查看训练曲线
import pandas as pd
df = pd.read_csv('runs/detect/custom_defect/results.csv')
# 关键指标
# - train/box_loss: 边界框回归损失
# - train/cls_loss: 分类损失
# - metrics/mAP50: IoU=0.5 时的 mAP
# - metrics/mAP50-95: IoU=0.5:0.95 的平均 mAP
5. 模型评估
# 在测试集上评估
model = YOLO('runs/detect/custom_defect/weights/best.pt')
metrics = model.val(data='data.yaml', split='test')
print(f"mAP50: {metrics.box.map50:.4f}")
print(f"mAP50-95: {metrics.box.map:.4f}")
print(f"Precision: {metrics.box.mp:.4f}")
print(f"Recall: {metrics.box.mr:.4f}")
混淆矩阵分析:
from ultralytics.utils.metrics import ConfusionMatrix
# 自动生成 confusion_matrix_normalized.png
6. 推理与部署
6.1 Python 推理
from ultralytics import YOLO
import cv2
model = YOLO('runs/detect/custom_defect/weights/best.pt')
# 单张推理
results = model('test_image.jpg', conf=0.5, iou=0.45)
for r in results:
boxes = r.boxes
for box in boxes:
cls_id = int(box.cls[0])
conf = float(box.conf[0])
x1, y1, x2, y2 = box.xyxy[0].tolist()
print(f"Class: {r.names[cls_id]}, Conf: {conf:.2f}, "
f"Box: [{x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f}]")
# 可视化
annotated = r.plot()
cv2.imwrite('result.jpg', annotated)
6.2 导出 ONNX
model = YOLO('runs/detect/custom_defect/weights/best.pt')
model.export(format='onnx', imgsz=640, simplify=True, opset=13)
6.3 TensorRT 部署(Jetson)
# 在 Jetson 设备上
yolo export model=best.pt format=engine imgsz=640 device=0 half=True
# TensorRT 推理
model = YOLO('best.engine')
results = model('test.jpg', device=0)
性能对比(RTX 3090):
| 格式 | 推理时间 | 模型大小 | mAP50 |
|---|---|---|---|
| PyTorch FP32 | 8.2ms | 52MB | 0.892 |
| ONNX FP32 | 5.1ms | 52MB | 0.892 |
| TensorRT FP16 | 2.3ms | 28MB | 0.891 |
| TensorRT INT8 | 1.6ms | 15MB | 0.885 |
7. 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| mAP 低 | 数据量不足 / 标注不一致 | 增加数据量 + 数据增强 |
| 过拟合 | 模型过大 / 数据少 | 用 yolov8n.pt + early stopping |
| 小目标漏检 | 分辨率低 | 增大 imgsz 到 1280 |
| 类别不平衡 | 某类样本过少 | 使用 class_weights 或过采样 |
8. 总结
本文完成了 YOLOv8 从数据准备到 TensorRT 部署的完整流程。关键要点:
- 数据质量 > 模型复杂度:标注规范和数据增强比选大模型更重要
- 先跑 baseline,再调优:先用 yolov8s 快速验证,再升级到 yolov8m/l
- 部署用 TensorRT:FP16 量化几乎无损,速度提升 3-4 倍
更多推荐



所有评论(0)