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 标注

  1. 注册 Roboflow 账号
  2. 创建项目(Object Detection)
  3. 上传图片 → 使用 Smart Polygon 标注
  4. 导出为 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 超参数调优

参数推荐值说明
lr00.01初始学习率
lrf0.01最终学习率 = lr0 × lrf
momentum0.937SGD 动量
weight_decay0.0005权重衰减
warmup_epochs3.0预热轮数
box7.5边界框损失权重
cls0.5分类损失权重
hsv_h0.015色调增强范围
mosaic1.0Mosaic 增强概率

小目标优化:

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 FP328.2ms52MB0.892
ONNX FP325.1ms52MB0.892
TensorRT FP162.3ms28MB0.891
TensorRT INT81.6ms15MB0.885

7. 常见问题

问题原因解决方案
mAP 低数据量不足 / 标注不一致增加数据量 + 数据增强
过拟合模型过大 / 数据少用 yolov8n.pt + early stopping
小目标漏检分辨率低增大 imgsz 到 1280
类别不平衡某类样本过少使用 class_weights 或过采样

8. 总结

本文完成了 YOLOv8 从数据准备到 TensorRT 部署的完整流程。关键要点:

  1. 数据质量 > 模型复杂度:标注规范和数据增强比选大模型更重要
  2. 先跑 baseline,再调优:先用 yolov8s 快速验证,再升级到 yolov8m/l
  3. 部署用 TensorRT:FP16 量化几乎无损,速度提升 3-4 倍
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐