YOLOv8 作为 Ultralytics 公司推出的最新一代目标检测算法,在保持高效推理速度的同时显著提升了检测精度。本指南将带你完成从环境搭建到实际项目部署的全过程,帮助你掌握这一先进技术。
推荐使用 Ubuntu 20.04/22.04 LTS 或 Windows 10/11 操作系统,确保至少具备 16GB RAM 和 NVIDIA GPU(RTX 30 系列或更高性能)。对于大规模训练,建议使用专用工作站或云服务器(如 AWS EC2 P3/P4 系列)。
首先安装 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 信息。
YOLOv8 使用特定的目录结构组织数据:
datasets/
└── custom_dataset/
├── images/
│ ├── train/
│ ├── val/
│ └── test/
└── labels/
├── train/
├── val/
└── test/
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/')
在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', ...] # 类别名称列表
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 |
使用 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
)
model
: 指定预训练模型路径data
: 指定数据集配置文件epochs
: 训练轮次imgsz
: 输入图像尺寸batch
: 批次大小device
: 训练设备workers
: 数据加载线程数optimizer
: 优化器类型 (SGD, Adam, RMSProp 等)lr0
: 初始学习率训练完成后,使用以下命令评估模型性能:
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 曲线等可视化图表。
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 # 分类概率(如果是分类模型)
导出模型为 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
可以通过修改配置文件来自定义模型结构,例如在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)
]
使用 DDP(分布式数据并行)进行多 GPU 训练:
yolo train model=yolov8l.pt data=data/custom.yaml epochs=50 imgsz=640 batch=32 device=0,1,2,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
CUDA 内存不足
half=True
)训练过程中 loss 不下降
推理速度慢
通过本指南,你已经掌握了 YOLOv8 从环境搭建到实际部署的全流程。YOLOv8 凭借其卓越的性能和易用性,在安防监控、自动驾驶、工业检测等领域都有广泛的应用前景。建议你通过实际项目不断实践和优化,探索更多高级应用场景。