YOLOv8 深度学习目标检测实战指南

1. 引言

YOLOv8 作为 Ultralytics 公司推出的最新一代目标检测算法,在保持高效推理速度的同时显著提升了检测精度。本指南将带你完成从环境搭建到实际项目部署的全过程,帮助你掌握这一先进技术。

2. 环境搭建
2.1 系统要求

推荐使用 Ubuntu 20.04/22.04 LTS 或 Windows 10/11 操作系统,确保至少具备 16GB RAM 和 NVIDIA GPU(RTX 30 系列或更高性能)。对于大规模训练,建议使用专用工作站或云服务器(如 AWS EC2 P3/P4 系列)。

2.2 安装步骤

首先安装 Miniconda 以管理 Python 环境:

# Linux/macOS安装
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

# Windows安装:从官网下载安装包并运行

创建并激活专用环境:

conda create -n yolov8 python=3.9 -y
conda activate yolov8

安装 PyTorch(根据 CUDA 版本选择):

# CUDA 11.8
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# CPU版本
pip install torch torchvision torchaudio

安装 Ultralytics 库和依赖:

pip install ultralytics
pip install matplotlib pandas scipy tqdm seaborn

验证安装:

import ultralytics
ultralytics.checks()

输出应显示 PyTorch 版本、CUDA 可用性和 GPU 信息。

3. 数据准备
3.1 数据集结构

YOLOv8 使用特定的目录结构组织数据:

datasets/
└── custom_dataset/
    ├── images/
    │   ├── train/
    │   ├── val/
    │   └── test/
    └── labels/
        ├── train/
        ├── val/
        └── test/
3.2 标注格式转换

YOLO 格式要求每个图像对应一个.txt 标注文件,每行格式为:

    

其中坐标均为相对于图像宽高的归一化值。

以下是将 COCO 格式转换为 YOLO 格式的示例代码:

import json
import os
from PIL import Image

def coco_to_yolo(coco_file, img_dir, output_dir):
    with open(coco_file, 'r') as f:
        coco_data = json.load(f)
    
    # 创建类别ID映射
    category_map = {cat['id']: i for i, cat in enumerate(coco_data['categories'])}
    
    # 处理每张图像
    for img_info in coco_data['images']:
        img_id = img_info['id']
        img_width = img_info['width']
        img_height = img_info['height']
        img_path = os.path.join(img_dir, img_info['file_name'])
        
        # 检查图像是否存在
        if not os.path.exists(img_path):
            continue
        
        # 获取对应的标注
        annotations = [ann for ann in coco_data['annotations'] if ann['image_id'] == img_id]
        
        # 创建YOLO格式标注文件
        yolo_file = os.path.join(output_dir, os.path.splitext(img_info['file_name'])[0] + '.txt')
        with open(yolo_file, 'w') as f:
            for ann in annotations:
                cat_id = category_map[ann['category_id']]
                bbox = ann['bbox']  # [x, y, width, height]
                
                # 转换为中心坐标
                x_center = (bbox[0] + bbox[2]/2) / img_width
                y_center = (bbox[1] + bbox[3]/2) / img_height
                width = bbox[2] / img_width
                height = bbox[3] / img_height
                
                f.write(f"{cat_id} {x_center} {y_center} {width} {height}\n")

# 使用示例
coco_to_yolo('instances_train2017.json', 'train2017/', 'labels/train/')
3.3 创建数据配置文件

data/目录下创建custom.yaml

train: ../datasets/custom_dataset/images/train/
val: ../datasets/custom_dataset/images/val/
test: ../datasets/custom_dataset/images/test/

nc: 80  # 类别数量
names: ['person', 'bicycle', 'car', ...]  # 类别名称列表
4. 模型训练
4.1 选择预训练模型

YOLOv8 提供多种模型大小选择:

模型 参数量 计算量 (GFLOPs) 精度 ([email protected]) 推理速度 (ms)
YOLOv8n 3.2M 8.7 37.3 9.2
YOLOv8s 11.2M 28.6 44.9 12.0
YOLOv8m 25.9M 78.9 50.2 18.2
YOLOv8l 43.7M 165.2 52.9 23.8
YOLOv8x 68.2M 257.8 53.9 37.5
4.2 训练命令

使用 CLI 训练:

yolo train model=yolov8s.pt data=data/custom.yaml epochs=100 imgsz=640 batch=16

或使用 Python API:

from ultralytics import YOLO

# 加载模型
model = YOLO("yolov8s.pt")

# 训练模型
results = model.train(
    data="data/custom.yaml",
    epochs=100,
    imgsz=640,
    batch=16,
    device=0,  # 指定GPU ID,-1表示CPU
    workers=8,
    project="yolov8_results",
    name="custom_train",
    pretrained=True,
    optimizer="Adam",
    lr0=0.001
)
4.3 关键训练参数解析
  • model: 指定预训练模型路径
  • data: 指定数据集配置文件
  • epochs: 训练轮次
  • imgsz: 输入图像尺寸
  • batch: 批次大小
  • device: 训练设备
  • workers: 数据加载线程数
  • optimizer: 优化器类型 (SGD, Adam, RMSProp 等)
  • lr0: 初始学习率
5. 模型评估

训练完成后,使用以下命令评估模型性能:

yolo val model=runs/detect/train/weights/best.pt data=data/custom.yaml

或使用 Python API:

# 加载训练好的模型
model = YOLO("runs/detect/train/weights/best.pt")

# 评估模型
metrics = model.val()
print(metrics.box.map)    # 平均精度均值([email protected]:0.95)
print(metrics.box.map50)  # [email protected]
print(metrics.box.map75)  # [email protected]
print(metrics.box.maps)   # 每个类别的mAP

评估结果将生成混淆矩阵、PR 曲线和 F1 曲线等可视化图表。

6. 模型推理与部署
6.1 图像 / 视频推理
yolo predict model=runs/detect/train/weights/best.pt source="path/to/image.jpg"

或处理视频:

yolo predict model=runs/detect/train/weights/best.pt source="path/to/video.mp4"

使用 Python API

# 加载模型
model = YOLO("runs/detect/train/weights/best.pt")

# 对单张图像进行推理
results = model("path/to/image.jpg")

# 处理推理结果
for r in results:
    boxes = r.boxes  # 边界框信息
    masks = r.masks  # 分割掩码信息(如果是分割模型)
    keypoints = r.keypoints  # 关键点信息(如果是姿态模型)
    probs = r.probs  # 分类概率(如果是分类模型)
6.2 部署优化

导出模型为 ONNX 格式用于 TensorRT 部署:

yolo export model=runs/detect/train/weights/best.pt format=onnx imgsz=640

或使用 Python API:

# 导出模型
success = model.export(format="onnx", imgsz=640)

使用 TensorRT 加速推理:

import cv2
import torch
import numpy as np
import tensorrt as trt

# 加载TensorRT引擎
def load_engine(engine_path):
    with open(engine_path, 'rb') as f, trt.Runtime(trt.Logger(trt.Logger.WARNING)) as runtime:
        return runtime.deserialize_cuda_engine(f.read())

# 推理函数
def inference(engine, img):
    with engine.create_execution_context() as context:
        # 准备输入数据
        input_tensor = preprocess(img)
        
        # 分配GPU内存
        inputs, outputs, bindings = [], [], []
        stream = torch.cuda.Stream()
        
        for binding in engine:
            size = trt.volume(engine.get_binding_shape(binding))
            dtype = trt.nptype(engine.get_binding_dtype(binding))
            tensor = torch.zeros(size, dtype=dtype).cuda()
            bindings.append(int(tensor.data_ptr()))
            
            if engine.binding_is_input(binding):
                inputs.append({'tensor': tensor})
            else:
                outputs.append({'tensor': tensor})
        
        # 执行推理
        inputs[0]['tensor'] = input_tensor
        context.execute_async_v2(bindings=bindings, stream_handle=stream.cuda_stream)
        stream.synchronize()
        
        # 后处理结果
        output = outputs[0]['tensor'].cpu().numpy()
        return postprocess(output)

# 图像预处理和结果后处理函数(根据模型输入输出格式调整)
def preprocess(img):
    # 调整大小、归一化等操作
    img = cv2.resize(img, (640, 640))
    img = img.transpose((2, 0, 1))
    img = np.ascontiguousarray(img, dtype=np.float32)
    img /= 255.0
    tensor = torch.from_numpy(img).cuda().unsqueeze(0)
    return tensor

def postprocess(output):
    # 解析检测结果
    # ...
    return detections
7. 高级技巧与实战案例
7.1 自定义模型结构

可以通过修改配置文件来自定义模型结构,例如在models/目录下创建custom.yaml

# 从YOLOv8s继承主干网络
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 3, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C2f, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C2f, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 6, C2f, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C2f, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# 自定义检测头
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C2f, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C2f, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C2f, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C2f, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc]],  # Detect(P3, P4, P5)
  ]
7.2 多 GPU 训练

使用 DDP(分布式数据并行)进行多 GPU 训练:

yolo train model=yolov8l.pt data=data/custom.yaml epochs=50 imgsz=640 batch=32 device=0,1,2,3
7.3 模型融合与集成

通过模型融合提高检测性能:

# 加载多个训练好的模型
models = [
    YOLO("runs/detect/train1/weights/best.pt"),
    YOLO("runs/detect/train2/weights/best.pt"),
    YOLO("runs/detect/train3/weights/best.pt")
]

# 集成推理
def ensemble_inference(models, img_path):
    results = []
    for model in models:
        result = model(img_path)
        results.append(result)
    
    # 融合多个模型的检测结果
    # 可以使用加权平均、NMS等方法
    # ...
    
    return fused_results
8. 常见问题与解决方案
  1. CUDA 内存不足

    • 减小 batch_size
    • 使用更小的模型
    • 启用半精度训练 (half=True)
  2. 训练过程中 loss 不下降

    • 检查数据标注是否正确
    • 调整学习率
    • 尝试不同的优化器
  3. 推理速度慢

    • 导出模型为 TensorRT 格式
    • 减小输入图像尺寸
    • 使用 GPU 进行推理
9. 总结与展望

通过本指南,你已经掌握了 YOLOv8 从环境搭建到实际部署的全流程。YOLOv8 凭借其卓越的性能和易用性,在安防监控、自动驾驶、工业检测等领域都有广泛的应用前景。建议你通过实际项目不断实践和优化,探索更多高级应用场景。

你可能感兴趣的:(YOLO,深度学习,目标检测,计算机视觉,神经网络,人工智能)