第四篇:目标检测深入(YOLO系列重点)#
核心篇章 - 深入讲解YOLO系列从v1到YOLO11的完整演进,理论与实战并重
篇章定位#
本篇是整个计算机视觉笔记的重点篇章,专注于目标检测领域最重要的YOLO系列算法。从2016年YOLOv1的横空出世,到2024年YOLO11的最新进展,我们将系统学习YOLO如何改变目标检测领域。
为什么YOLO如此重要?#
- 单阶段检测的开创者 - 将检测问题转换为回归问题,实现真正的实时检测
- 工业界首选方案 - 在速度和精度间达到最佳平衡,广泛应用于生产环境
- 持续快速迭代 - 从v1到v11,每一代都带来显著的性能提升和创新
- 易用性强 - Ultralytics提供的API简洁高效,降低了应用门槛
内容结构#
第9章:YOLO系列演进(理论核心)#
深入讲解YOLO各版本的架构演进和核心创新:
9.1 YOLOv1-v3:单阶段检测的崛起
- YOLOv1:开创性的单阶段检测
- YOLOv2(YOLO9000):Anchor机制引入
- YOLOv3:多尺度特征金字塔
9.2 YOLOv4-v5:工程优化与实用化
- YOLOv4:Bag of Freebies和Bag of Specials
- YOLOv5:Ultralytics的工程实现
9.3 YOLOv6-v7:架构创新
- YOLOv6:工业应用优化
- YOLOv7:可训练Bag-of-Freebies
9.4 YOLOv8:Ultralytics新一代
- Anchor-free设计
- 多任务统一框架
- 性能基准
9.5 YOLOv9、YOLOv10、YOLO11:最新进展
- YOLOv9:PGI和GELAN
- YOLOv10:NMS-free设计
- YOLO11:当前最优方案
9.6 YOLO-World:开放词汇检测
- 零样本检测能力
- 与视觉-语言模型的结合
第10章:YOLO实战项目(代码实战)#
基于最新的YOLOv8和YOLO11的完整实战:
10.1 YOLOv8快速上手
- 环境配置
- 预训练模型使用
- 多种推理模式
10.2 自定义数据集训练
- 数据集准备和标注
- 训练配置详解
- 训练监控和调优
10.3 模型导出与部署
- ONNX导出
- TensorRT加速
- 边缘设备部署
10.4 实战:构建实时检测系统
- 视频流处理
- 性能优化
- 完整项目架构
技术栈#
核心库:
- ultralytics==8.3.0+ # 官方YOLO实现
- torch>=1.8.0 # PyTorch深度学习框架
- opencv-python # 图像处理
- onnx # 模型导出
- onnxruntime # ONNX推理
可选加速:
- tensorrt # NVIDIA GPU加速
- openvino # Intel CPU优化学习路径建议#
初学者路径#
- 先看第9章了解YOLO发展历程(重点关注9.4 YOLOv8)
- 直接进入第10章动手实践
- 从10.1快速上手开始,逐步深入
- 完成一个自定义数据集的训练项目
进阶路径#
- 系统学习第9章所有版本的演进
- 理解每个版本的核心创新点
- 第10章深入学习模型优化和部署
- 尝试将YOLO应用到实际生产环境
研究路径#
- 精读第9章各版本的论文原文
- 对比分析不同版本的架构差异
- 研究YOLOv9的PGI、YOLOv10的NMS-free等前沿技术
- 探索YOLO-World的开放词汇检测能力
实践项目建议#
入门项目#
- 项目1:使用YOLOv8完成一个简单的物体检测任务
- 项目2:在自己的数据集上训练YOLOv8模型
- 项目3:实现实时视频流检测
进阶项目#
- 项目4:对比YOLOv8、YOLOv10、YOLO11的性能
- 项目5:将YOLOv8模型导出为ONNX并优化推理速度
- 项目6:在边缘设备(如树莓派、Jetson)上部署YOLO
高级项目#
- 项目7:使用YOLO-World实现零样本检测
- 项目8:结合目标跟踪算法实现多目标跟踪系统
- 项目9:开发一个完整的视频分析系统
性能对比一览#
基于COCO数据集的最新性能(2024年数据):
| 模型 | mAP 50-95 | 参数量 | 推理速度(A100) | 特点 |
|---|---|---|---|---|
| YOLOv8n | 37.3 | 3.2M | 0.99ms | 轻量高效 |
| YOLOv8s | 44.9 | 11.2M | 1.20ms | 速度精度平衡 |
| YOLOv8m | 50.2 | 25.9M | 1.83ms | 中等规模 |
| YOLOv8l | 52.9 | 43.7M | 2.39ms | 高精度 |
| YOLOv8x | 53.9 | 68.2M | 3.53ms | 最高精度 |
| YOLOv9c | 53.0 | 25.5M | - | 创新架构 |
| YOLOv10x | 54.4 | 29.5M | 10.70ms | NMS-free |
| YOLO11m | 51.5 | 20.1M | - | 参数更少,性能更优 |
| YOLO11x | 54.7 | 56.9M | 11.3ms | 当前最优 |
应用场景#
YOLO系列在以下场景表现出色:
- 自动驾驶 - 实时检测车辆、行人、交通标志
- 智能监控 - 异常行为检测、人员计数
- 工业质检 - 产品缺陷检测、零件识别
- 零售分析 - 商品识别、货架管理
- 医疗影像 - 病灶检测、细胞计数
- 体育分析 - 运动员追踪、姿态分析
- 农业应用 - 作物病害检测、成熟度判断
- 安防领域 - 周界入侵检测、可疑物品识别
学习目标#
完成本篇学习后,你将能够:
- ✅ 理解YOLO系列从v1到v11的完整演进脉络
- ✅ 掌握单阶段检测器的核心原理和关键技术
- ✅ 熟练使用Ultralytics库进行模型训练和推理
- ✅ 能够在自定义数据集上训练高性能检测模型
- ✅ 掌握模型优化和部署的完整流程
- ✅ 能够将YOLO应用到实际项目中
- ✅ 了解最新的检测技术趋势(开放词汇检测等)
参考资源#
官方文档#
- Ultralytics官方文档 - 最权威的参考
- Ultralytics GitHub - 源码和示例
论文原文#
- YOLOv1: “You Only Look Once: Unified, Real-Time Object Detection” (CVPR 2016)
- YOLOv2: “YOLO9000: Better, Faster, Stronger” (CVPR 2017)
- YOLOv3: “YOLOv3: An Incremental Improvement” (arXiv 2018)
- YOLOv4: “YOLOv4: Optimal Speed and Accuracy of Object Detection” (arXiv 2020)
- YOLOv7: “YOLOv7: Trainable bag-of-freebies” (CVPR 2023)
- YOLOv9: “YOLOv9: Learning What You Want to Learn” (arXiv 2024)
- YOLOv10: “YOLOv10: Real-Time End-to-End Object Detection” (arXiv 2024)
社区资源#
- Roboflow - 数据集管理和标注平台
- Ultralytics HUB - 云端训练和部署平台
开始学习#
准备好了吗?让我们从第8章开始,先了解目标检测的基础知识,然后进入YOLO的精彩演进历程!
下一步:第8章:目标检测基础
更新日期:2024年11月 基于版本:ultralytics 8.3.0+, YOLO11
第8章:目标检测基础#
基础篇 - 理解目标检测任务、评价指标与经典方法
本章概览#
在深入YOLO之前,我们需要先理解目标检测的基本概念。本章将系统介绍:
- 目标检测任务定义
- 评价指标(IoU、mAP)
- 两阶段检测方法(R-CNN系列)
- 为什么需要单阶段检测
8.1 目标检测任务#
8.1.1 什么是目标检测?#
目标检测 = 定位 + 分类
输入:一张图像
输出:图像中所有目标的位置(边界框)和类别
每个检测结果包含:
- 边界框: (x, y, w, h) 或 (x1, y1, x2, y2)
- 类别: person, car, dog, ...
- 置信度: 0-1之间的概率值8.1.2 与相关任务的区别#
| 任务 | 输出 | 示例 |
|---|---|---|
| 图像分类 | 单个类别标签 | “这是一只猫” |
| 目标检测 | 多个边界框 + 类别 | “左边有只猫,右边有只狗” |
| 语义分割 | 像素级类别 | 每个像素属于哪个类别 |
| 实例分割 | 检测 + 分割掩码 | 每个物体的精确轮廓 |
8.1.3 应用场景#
1. 自动驾驶
- 行人检测、车辆检测
- 交通标志识别
- 障碍物检测
2. 安防监控
- 人脸检测
- 异常行为检测
- 入侵检测
3. 工业检测
- 缺陷检测
- 零件识别
- 产品计数
4. 零售应用
- 商品识别
- 货架管理
- 无人结算
8.2 评价指标#
8.2.1 IoU(交并比)#
Intersection over Union 衡量预测框与真实框的重叠程度:
IoU = 交集面积 / 并集面积
示例:
真实框: [100, 100, 200, 200]
预测框: [110, 110, 210, 210]
交集: 90 × 90 = 8100
并集: 100×100 + 100×100 - 8100 = 11900
IoU = 8100 / 11900 ≈ 0.68Python实现:
def calculate_iou(box1, box2):
"""
计算两个边界框的IoU
Args:
box1, box2: [x1, y1, x2, y2] 格式的边界框
Returns:
iou: 交并比值
"""
# 计算交集
x1_inter = max(box1[0], box2[0])
y1_inter = max(box1[1], box2[1])
x2_inter = min(box1[2], box2[2])
y2_inter = min(box1[3], box2[3])
# 交集面积
inter_width = max(0, x2_inter - x1_inter)
inter_height = max(0, y2_inter - y1_inter)
inter_area = inter_width * inter_height
# 各自面积
box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
# 并集面积
union_area = box1_area + box2_area - inter_area
# IoU
iou = inter_area / union_area if union_area > 0 else 0
return iouIoU阈值的含义:
| IoU阈值 | 含义 |
|---|---|
| 0.5 | COCO标准(宽松) |
| 0.75 | 严格匹配 |
| 0.5:0.95 | COCO mAP(多阈值平均) |
8.2.2 Precision与Recall#
精确率(Precision):预测为正的样本中,真正为正的比例
Precision = TP / (TP + FP)
= 正确检测数 / 总检测数召回率(Recall):所有正样本中,被正确预测的比例
Recall = TP / (TP + FN)
= 正确检测数 / 真实目标总数示例:
场景:图像中有10个目标,模型检测出8个框
正确检测(TP): 6个
错误检测(FP): 2个
漏检(FN): 4个
Precision = 6 / 8 = 0.75 (75%的检测是正确的)
Recall = 6 / 10 = 0.6 (找到了60%的目标)8.2.3 AP与mAP#
AP(Average Precision):PR曲线下的面积
def calculate_ap(precisions, recalls):
"""
计算单个类别的AP
Args:
precisions: 精确率列表
recalls: 召回率列表
Returns:
ap: 平均精确率
"""
# 在召回率点上插值
recalls = [0] + list(recalls) + [1]
precisions = [0] + list(precisions) + [0]
# 从右向左取最大值(单调递减)
for i in range(len(precisions) - 2, -1, -1):
precisions[i] = max(precisions[i], precisions[i + 1])
# 计算面积
ap = 0
for i in range(1, len(recalls)):
ap += (recalls[i] - recalls[i - 1]) * precisions[i]
return apmAP(mean Average Precision):所有类别AP的平均值
mAP = (1/N) × Σ AP_i
其中N是类别数COCO评价标准:
| 指标 | 定义 |
|---|---|
| AP | IoU=0.5:0.95的平均mAP |
| AP50 | IoU=0.5时的mAP |
| AP75 | IoU=0.75时的mAP |
| AP_S | 小目标(area<32²)的AP |
| AP_M | 中目标(32²<area<96²)的AP |
| AP_L | 大目标(area>96²)的AP |
8.3 两阶段检测器#
8.3.1 R-CNN(2014)#
Regions with CNN Features
核心思想:
- 使用选择性搜索(Selective Search)生成约2000个候选区域
- 对每个区域用CNN提取特征
- 使用SVM进行分类
- 边界框回归精修位置
流程:
图像
↓
选择性搜索 → 2000个候选区域
↓
对每个区域:
├── resize到固定尺寸(227×227)
├── CNN提取特征(AlexNet)
├── SVM分类
└── 边界框回归
↓
NMS后处理 → 最终检测结果问题:
- 每张图像需要2000次前向传播,非常慢
- 训练复杂,多阶段流程
- 测试速度:~47秒/张图
8.3.2 Fast R-CNN(2015)#
改进:
- 整张图像只需一次CNN前向传播
- 使用RoI Pooling从特征图中提取区域特征
- 多任务损失(分类 + 回归)
流程:
图像
↓
CNN → 整图特征图
↓
候选区域(仍用选择性搜索)
↓
RoI Pooling → 固定尺寸特征
↓
全连接层 → 分类 + 回归RoI Pooling:
def roi_pooling(feature_map, roi, output_size):
"""
将任意大小的RoI转换为固定尺寸的特征
Args:
feature_map: CNN特征图 (C, H, W)
roi: 候选区域 [x1, y1, x2, y2]
output_size: 输出尺寸 (7, 7)
Returns:
pooled: (C, 7, 7) 的特征
"""
# 将RoI划分为 output_size 个bins
# 对每个bin做max pooling
...改进效果:
- 训练:比R-CNN快9倍
- 测试:比R-CNN快213倍(~2秒/张图)
- 但候选区域生成仍是瓶颈
8.3.3 Faster R-CNN(2016)#
核心创新:Region Proposal Network (RPN)
用神经网络替代选择性搜索,实现端到端训练!
RPN架构:
输入特征图
↓
3×3卷积 (滑动窗口)
↓
┌────────────┴────────────┐
↓ ↓
1×1卷积 1×1卷积
↓ ↓
分类层(2k通道) 回归层(4k通道)
↓ ↓
前景/背景 边界框调整
(是否有物体) (dx, dy, dw, dh)
k = anchor数量(通常9个)Anchor机制:
每个位置预设k个anchor:
- 3种尺度: 128², 256², 512²
- 3种比例: 1:1, 1:2, 2:1
共9个anchor
特征图大小: 60×40
总anchor数: 60 × 40 × 9 = 21,600完整流程:
图像
↓
Backbone(VGG/ResNet) → 特征图
↓
RPN → 候选区域(~2000个)
↓
RoI Pooling → 固定尺寸特征
↓
分类 + 边界框回归
↓
NMS → 最终结果性能:
- 5 FPS (VGG-16)
- 17 FPS (ZF Net)
- 开启了实时检测的可能
8.3.4 两阶段方法总结#
| 方法 | 候选区域 | 特征提取 | 速度 | mAP |
|---|---|---|---|---|
| R-CNN | 选择性搜索 | 每个区域单独 | 47s | 58.5 |
| Fast R-CNN | 选择性搜索 | 共享特征图 | 2s | 70.0 |
| Faster R-CNN | RPN | 共享特征图 | 0.2s | 73.2 |
两阶段的优缺点:
优点:
- 精度高
- 可以处理复杂场景
缺点:
- 速度相对较慢
- 结构复杂
- 候选区域与分类分开优化
8.4 为什么需要单阶段检测?#
8.4.1 两阶段的速度瓶颈#
Faster R-CNN的计算分布:
- Backbone前向: 40%
- RPN: 15%
- RoI Pooling + FC: 35%
- NMS后处理: 10%
即使用RPN,仍需要两次预测:
1. RPN: 是否有物体
2. Detection Head: 是什么物体8.4.2 单阶段的思路#
核心想法:能否一次性同时预测位置和类别?
两阶段:
图像 → 特征 → 候选区域 → 分类/回归
单阶段:
图像 → 特征 → 直接回归位置+类别这就是YOLO的核心思想!
8.4.3 单阶段 vs 两阶段#
| 特性 | 两阶段 | 单阶段 |
|---|---|---|
| 代表 | Faster R-CNN | YOLO, SSD |
| 速度 | 较慢(5-17 FPS) | 较快(30-150 FPS) |
| 精度 | 较高 | 早期较低,现已接近 |
| 结构 | 复杂 | 简洁 |
| 训练 | 多阶段 | 端到端 |
| 小目标 | 较好 | 早期较差,现已改进 |
本章小结#
核心知识点#
目标检测任务
- 定位 + 分类
- 输出:边界框 + 类别 + 置信度
评价指标
- IoU:衡量框的重叠程度
- Precision/Recall:精确率与召回率
- mAP:综合评价指标
两阶段检测器
- R-CNN → Fast R-CNN → Faster R-CNN
- 核心创新:RPN替代选择性搜索
- 问题:速度仍不够快
单阶段检测的动机
- 追求实时性能
- 端到端简洁设计
下一步#
现在你已经理解了目标检测的基础知识,让我们进入第9章,学习YOLO如何开创单阶段检测的新时代!
参考资源:
第9章:YOLO系列演进#
核心章节 - 从YOLOv1到YOLO11,系统学习YOLO如何改变目标检测领域
本章概览#
本章将深入讲解YOLO(You Only Look Once)系列算法的完整演进历程。从2016年YOLOv1的横空出世,到2024年YOLO11的最新进展,我们将系统学习:
- YOLO如何开创单阶段检测范式
- 每一代YOLO的核心创新点
- 架构演进的内在逻辑
- 性能提升的技术路径
为什么要学习YOLO演进史?#
- 理解算法发展脉络 - 看清目标检测技术的演进方向
- 掌握核心创新思想 - 每一代都有独特的贡献
- 为实战打下基础 - 理论指导实践应用
- 跟上最新进展 - YOLO仍在快速迭代中
章节结构#
- 9.1 YOLOv1-v3:单阶段检测的崛起
- 9.2 YOLOv4-v5:工程优化与实用化
- 9.3 YOLOv6-v7:架构创新
- 9.4 YOLOv8:Ultralytics新一代
- 9.5 YOLOv9、YOLOv10、YOLO11:最新进展
- 9.6 YOLO-World:开放词汇检测
9.1 YOLOv1-v3:单阶段检测的崛起#
9.1.1 YOLOv1:开创性的单阶段检测#
论文:You Only Look Once: Unified, Real-Time Object Detection (CVPR 2016)
作者:Joseph Redmon et al.
核心思想#
YOLOv1的革命性贡献在于:将目标检测重新定义为单一回归问题,而非传统的两阶段流程(候选区域 + 分类)。
传统检测器(如R-CNN)的流程:
图像 → 候选区域生成 → 特征提取 → 分类 + 边界框回归YOLOv1的流程:
图像 → CNN → 直接输出 [类别概率 + 边界框坐标]架构设计#
1. 网格划分
将输入图像划分为 S×S 网格(论文中S=7)。如果物体的中心落在某个网格内,该网格就负责检测这个物体。
2. 边界框预测
每个网格预测 B 个边界框(B=2),每个边界框包含:
- (x, y): 边界框中心相对于网格的偏移
- (w, h): 边界框的宽高(相对于整张图像)
- confidence: 置信度 = Pr(Object) × IOU
3. 类别预测
每个网格预测 C 个类别概率(PASCAL VOC中C=20)
4. 输出张量
最终输出:S × S × (B×5 + C) = 7 × 7 × 30
网络结构:
输入: 448×448×3
↓
24个卷积层(受GoogLeNet启发)
↓
2个全连接层
↓
输出: 7×7×30损失函数#
YOLOv1使用多任务损失(Multi-Part Loss):
Loss = λcoord × 坐标损失
+ 置信度损失(有物体)
+ λnoobj × 置信度损失(无物体)
+ 分类损失关键参数:
- λcoord = 5:增加坐标损失的权重
- λnoobj = 0.5:降低背景框的权重
优缺点#
优势:
- 速度快:45 FPS(标准版),155 FPS(Fast YOLO)
- 全局推理:看到整张图像,减少背景误检
- 通用性强:可用于艺术品等非标准领域
局限:
- 每个网格只能检测一个物体,小物体检测困难
- 泛化能力有限,对新的长宽比敏感
- 定位精度不如两阶段方法
9.1.2 YOLOv2(YOLO9000):更好、更快、更强#
论文:YOLO9000: Better, Faster, Stronger (CVPR 2017)
作者:Joseph Redmon, Ali Farhadi
YOLOv2在v1的基础上进行了全面改进,论文副标题"Better, Faster, Stronger"概括了三个方向的提升。
Better:准确度提升#
1. Batch Normalization
- 在所有卷积层后添加BN
- mAP提升2%,去除dropout
2. High Resolution Classifier
- 先在ImageNet 448×448上微调分类网络
- mAP提升约4%
3. Anchor Boxes
- 引入Faster R-CNN的Anchor机制
- 使用K-means聚类数据集获取先验框尺寸
- 提高召回率
4. Dimension Clusters
- 在数据集上运行K-means得到5个anchor boxes
- 比手工设计的anchor更适合数据集
5. Direct Location Prediction
- 预测相对于网格的偏移,使用sigmoid约束
- 稳定训练过程
6. Fine-Grained Features
- 引入Passthrough Layer(类似ResNet的identity mapping)
- 将26×26的特征图与13×13的融合
- 提升小物体检测能力
7. Multi-Scale Training
- 每10个batch随机选择不同尺寸{320, 352, …, 608}
- 增强对不同尺寸的鲁棒性
Faster:速度提升#
Darknet-19:
- 新的backbone网络
- 19个卷积层 + 5个maxpool层
- 使用全局平均池化代替全连接
- 参数量少,速度快
输入: 416×416×3
↓
Darknet-19(19 conv layers)
↓
输出: 13×13×1024Stronger:检测类别扩展#
YOLO9000:能检测9000多个类别
WordTree层次结构:
- 结合ImageNet和COCO数据集
- 构建WordNet概念层次树
- 支持多级分类预测
性能#
- YOLOv2-416:67 FPS,76.8 mAP (VOC 2007)
- YOLOv2-544:40 FPS,78.6 mAP
- 在速度和精度上都超越了SSD和Faster R-CNN
9.1.3 YOLOv3:渐进式改进#
论文:YOLOv3: An Incremental Improvement (arXiv 2018)
作者:Joseph Redmon, Ali Farhadi
YOLOv3的改进更加务实,论文标题也很坦诚:“渐进式改进”。
核心改进#
1. Darknet-53
更深的backbone网络,借鉴ResNet的残差结构:
输入: 256×256×3
↓
1x Conv: 32 filters
↓
2x Conv: 64 filters ┐
↓ │ Residual Block ×1
Skip Connection ←────┘
↓
2x Conv: 128 filters ┐
↓ │ Residual Block ×2
Skip Connection ←────┘
↓
2x Conv: 256 filters ┐
↓ │ Residual Block ×8
Skip Connection ←────┘
↓
2x Conv: 512 filters ┐
↓ │ Residual Block ×8
Skip Connection ←────┘
↓
2x Conv: 1024 filters┐
↓ │ Residual Block ×4
Skip Connection ←────┘性能对比:
- Darknet-53比Darknet-19准确度高
- 比ResNet-152快,精度相当
- 比ResNet-101快,精度更高
2. 多尺度预测(Feature Pyramid)
在3个不同尺度上进行预测:
13×13 (大物体) ←─ Conv Layers
↑
26×26 (中物体) ←─ Upsample + Concat
↑
52×52 (小物体) ←─ Upsample + Concat每个尺度预测3个anchor boxes,共9个anchors。
3. 类别预测改进
- 使用逻辑回归代替softmax
- 支持多标签分类(如"人"和"女性"同时)
- 更适合复杂场景
4. 损失函数优化
- 边界框坐标:平方误差损失
- 物体置信度:二元交叉熵
- 类别预测:二元交叉熵(支持多标签)
性能表现#
COCO数据集(test-dev):
- YOLOv3-320:28.2 mAP,22 ms
- YOLOv3-416:31.0 mAP,29 ms
- YOLOv3-608:33.0 mAP,51 ms
特点:
- 小物体检测显著提升(APS:18.3)
- 中物体表现优异(APM:35.4)
- 大物体略低于RetinaNet(APL:41.9 vs 44.3)
YOLOv3的实践意义#
虽然论文标题谦虚,但YOLOv3是一个里程碑:
- 多尺度预测成为标配
- 速度和精度达到良好平衡
- 成为工业界主流方案
9.2 YOLOv4-v5:工程优化与实用化#
9.2.1 YOLOv4:Bag of Freebies和Bag of Specials#
论文:YOLOv4: Optimal Speed and Accuracy of Object Detection (arXiv 2020)
作者:Alexey Bochkovskiy, Chien-Yao Wang, Hong-Yuan Mark Liao
YOLOv4的出现标志着YOLO进入"工程化集大成"时代。论文系统性地总结了目标检测的技巧。
核心贡献#
YOLOv4将检测技巧分为两类:
Bag of Freebies (BoF):只增加训练成本,不增加推理成本 Bag of Specials (BoS):略微增加推理成本,但显著提升精度
架构组成#
YOLOv4 = Backbone + Neck + Head
1. Backbone:CSPDarknet53
Cross Stage Partial(CSP)连接:
- 将特征图分成两部分
- 一部分经过Dense Block
- 另一部分直接连接到末尾
- 减少计算量,增强梯度流
2. Neck:SPP + PAN
SPP(Spatial Pyramid Pooling):
- 多尺度池化{1×1, 5×5, 9×9, 13×13}
- 增大感受野
PAN(Path Aggregation Network):
- 在FPN基础上添加bottom-up路径
- 增强低层特征的传播
3. Head:YOLOv3 Head
保持YOLOv3的检测头设计
Bag of Freebies(训练技巧)#
数据增强:
- Mosaic augmentation:将4张图像拼接
- Self-Adversarial Training (SAT)
- CutMix、MixUp
- 随机擦除
正则化:
- DropBlock
- Label Smoothing
损失函数:
- CIoU Loss:考虑重叠面积、中心距离、宽高比
# CIoU Loss伪代码
CIoU = IoU - (ρ²(b, b_gt) / c²) - αv
其中:
ρ²: 中心点距离
c²: 最小外接矩形对角线距离
v: 宽高比一致性
α: 权重系数Bag of Specials(推理技巧)#
增强感受野:
- SPP
- ASFF(Adaptively Spatial Feature Fusion)
注意力机制:
- SE(Squeeze-and-Excitation)
- SAM(Spatial Attention Module)
激活函数:
- Mish激活:Mish(x) = x * tanh(ln(1 + e^x))
后处理:
- DIoU-NMS:考虑中心点距离的NMS
性能表现#
MS COCO(test-dev):
- YOLOv4-CSP:43.0 mAP,Tesla V100 62 FPS
- 相比YOLOv3,AP提升10%,FPS提升12%
突破:
- 在通用GPU(GTX 1080 Ti)上实现实时检测
- 成为工业界首选方案
9.2.2 YOLOv5:Ultralytics的工程实现#
发布时间:2020年6月(与YOLOv4几乎同时)
开发者:Glenn Jocher (Ultralytics)
特点:工程化、易用性、生产就绪
YOLOv5 vs YOLOv4#
YOLOv5不是学术论文,而是工程实现。主要改进:
1. 架构改进
- Backbone:CSPDarknet(Focus结构)
- Neck:PA-FPN
- Head:YOLOv3-like head
Focus结构:
# Focus层:将空间信息压缩到通道
def focus(x, channel):
# 将 (b, c, w, h) → (b, 4c, w/2, h/2)
return concat([
x[::2, ::2], # 左上
x[1::2, ::2], # 右上
x[::2, 1::2], # 左下
x[1::2, 1::2] # 右下
])2. 数据增强
- Mosaic增强(从YOLOv4继承)
- 自适应anchor计算
- 自适应图像缩放
3. 模型尺寸系列
提供5个不同规模的模型:
| 模型 | 参数量 | 适用场景 |
|---|---|---|
| YOLOv5n | 1.9M | 移动端/边缘设备 |
| YOLOv5s | 7.2M | 实时应用 |
| YOLOv5m | 21.2M | 平衡性能 |
| YOLOv5l | 46.5M | 高精度 |
| YOLOv5x | 86.7M | 最高精度 |
4. 训练策略
- 自动学习率调整
- 自动混合精度(AMP)训练
- EMA(Exponential Moving Average)权重更新
- 多尺度训练
5. 工程化优势
- PyTorch原生实现,易于理解和修改
- 完善的训练脚本和工具链
- 支持导出ONNX、TensorRT、CoreML等格式
- 丰富的文档和社区支持
代码示例#
# YOLOv5的简洁API
from models.yolo import Model
# 加载模型
model = Model('yolov5s.yaml')
model.load_state_dict(torch.load('yolov5s.pt'))
# 推理
results = model(img)
# 训练
python train.py --data coco.yaml --weights yolov5s.pt --epochs 300性能#
COCO val2017:
- YOLOv5s:37.4 mAP,~140 FPS(V100)
- YOLOv5m:45.4 mAP,~100 FPS
- YOLOv5l:49.0 mAP,~75 FPS
- YOLOv5x:50.7 mAP,~50 FPS
争议与影响#
争议点:
- 命名争议(并非Joseph Redmon的官方延续)
- 发布时间紧跟YOLOv4引发讨论
积极影响:
- 极大降低了YOLO的使用门槛
- 推动YOLO在工业界的广泛应用
- 为后续YOLOv6-v8奠定基础
9.3 YOLOv6-v7:架构创新#
9.3.1 YOLOv6:工业应用优化#
发布时间:2022年6月
开发者:美团视觉智能部
特点:面向工业应用的深度优化
核心创新#
1. BiC(Bi-directional Concatenation)模块
- 替代传统的Neck结构
- 双向特征融合
- 减少参数量,提升速度
2. Anchor-Free设计
- 采用Anchor-free检测头
- 简化模型结构
- 提升小物体检测能力
3. SimCSPSPPF Backbone
- 优化的CSP结构
- 融合SPPF(Fast SPP)
- 平衡速度和精度
4. 自蒸馏训练
- 使用更大的模型作为教师
- 提升小模型性能
- 无推理成本增加
模型系列#
| 模型 | mAP | 延迟(T4) | 参数量 |
|---|---|---|---|
| YOLOv6-N | 37.5 | 1.2ms | 4.7M |
| YOLOv6-T | 41.3 | 2.9ms | 9.7M |
| YOLOv6-S | 45.0 | 3.5ms | 18.5M |
| YOLOv6-M | 50.0 | 7.0ms | 34.9M |
| YOLOv6-L | 52.8 | 11.4ms | 59.6M |
工业化特性#
- 支持量化感知训练(QAT)
- INT8量化精度损失小
- 针对NVIDIA GPU和ARM处理器优化
- 提供完整的部署工具链
9.3.2 YOLOv7:可训练Bag-of-Freebies#
论文:YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors (CVPR 2023)
作者:Chien-Yao Wang, Alexey Bochkovskiy, Hong-Yuan Mark Liao
YOLOv7是YOLOv4作者团队的最新力作,标题"Trainable bag-of-freebies"道出了核心贡献。
核心创新#
1. E-ELAN(Extended Efficient Layer Aggregation Network)
E-ELAN是对ELAN的扩展:
- 使用expand、shuffle、merge cardinality策略
- 在不破坏原始梯度路径的情况下增强学习能力
- 提升特征表达能力
架构对比:
ELAN:
Input → Conv → [Conv × 2] → [Conv × 2] → Concat → Conv
E-ELAN:
Input → Conv → [Group Conv × 2] → [Shuffle] → [Conv × 2] → Concat → Conv2. Model Scaling for Concatenation-based Models
针对基于concatenation的模型提出缩放策略:
- 深度缩放:调整模块重复次数
- 宽度缩放:调整通道数
- 复合缩放:同时缩放计算块和过渡层
3. Planned Re-parameterized Convolution
RepConv:训练时使用多分支,推理时融合为单路
# 训练时
output = conv3x3(x) + conv1x1(x) + identity(x)
# 推理时(融合后)
output = fused_conv3x3(x) # 单个3x3卷积4. Coarse-to-Fine Lead Guided Label Assignment
改进标签分配策略:
- Lead head:粗粒度分配,提供先验
- Auxiliary head:细粒度优化
- 训练时双头,推理时仅保留lead head
架构设计#
YOLOv7架构:
Input (640×640)
↓
E-ELAN Backbone
↓
SPPCSPC (Spatial Pyramid Pooling CSP)
↓
E-ELAN Neck (PA-FPN)
↓
RepConv Head
↓
Output (3个尺度)变体:
- YOLOv7:基础版本
- YOLOv7-X:扩展版本,更深更宽
- YOLOv7-W6:针对1280分辨率
- YOLOv7-E6、E6E:针对更高分辨率
性能表现#
MS COCO test-dev:
| 模型 | mAP | V100推理速度 | 参数量 | FLOPs |
|---|---|---|---|---|
| YOLOv7 | 51.4 | 161 FPS | 36.9M | 104.7G |
| YOLOv7-X | 53.1 | 114 FPS | 71.3M | 189.9G |
| YOLOv7-W6 | 54.9 | 84 FPS | 70.4M | 360.0G |
| YOLOv7-E6 | 56.0 | 56 FPS | 97.2M | 515.2G |
| YOLOv7-D6 | 56.6 | 44 FPS | 154.7M | 806.8G |
| YOLOv7-E6E | 56.8 | 36 FPS | 151.7M | 843.2G |
亮点:
- YOLOv7在640×640下达到51.4% AP
- 速度比YOLOv5快120%
- 比YOLOX快180%
- 比PP-YOLOE快140%
Trainable Bag-of-Freebies#
YOLOv7提出的可训练BoF技巧:
1. Planned Re-parameterization
- 不同深度使用不同的re-parameterization模块
2. Auxiliary Head + Coarse-to-Fine
- 辅助头用于训练优化
- 推理时去除,无额外成本
3. Batch Normalization in Concatenation
- 在concatenation层添加BN
- 改善梯度流
9.4 YOLOv8:Ultralytics新一代#
发布时间:2023年1月
开发者:Ultralytics (Glenn Jocher团队)
特点:统一框架,支持多任务
YOLOv8是Ultralytics继YOLOv5后的又一力作,代表着YOLO走向成熟和多样化。
9.4.1 核心特性#
1. Anchor-Free设计
YOLOv8彻底抛弃anchor:
- 简化模型设计
- 加速后处理(无需anchor box生成)
- 更好的泛化能力
2. 新的Backbone:C2f模块
C2f(Cross Stage Partial with 2 convolutions and more):
- 融合YOLOv5的C3和YOLOv7的ELAN设计
- 更丰富的梯度流
- 保持轻量级
C2f vs C3对比:
# C3 (YOLOv5)
class C3(nn.Module):
def __init__(self, c1, c2, n=1):
self.cv1 = Conv(c1, c2//2)
self.cv2 = Conv(c1, c2//2)
self.m = nn.Sequential(*[Bottleneck(c2//2, c2//2) for _ in range(n)])
self.cv3 = Conv(c2, c2)
# C2f (YOLOv8)
class C2f(nn.Module):
def __init__(self, c1, c2, n=1):
self.cv1 = Conv(c1, 2*c2)
self.cv2 = Conv((2+n)*c2, c2)
self.m = nn.ModuleList(Bottleneck(c2, c2) for _ in range(n))
# 每个Bottleneck的输出都concat到一起3. 解耦头(Decoupled Head)
分离分类和回归任务:
Feature Map
├── Classification Branch → Class Probabilities
└── Regression Branch → Bounding Boxes4. 新的损失函数
分类损失:Varifocal Loss(VFL)
- 关注正样本的置信度
- 对不平衡问题更鲁棒
回归损失:DFL(Distribution Focal Loss) + CIoU
- DFL将连续值转换为离散分布
- CIoU考虑重叠、距离、宽高比
5. Task-Aligned Assigner
改进的样本分配策略:
- 同时考虑分类分数和IoU
- 自适应地选择正负样本
- 提升训练效果
9.4.2 多任务支持#
YOLOv8统一框架支持5种计算机视觉任务:
1. Object Detection(目标检测)
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
results = model('image.jpg')2. Instance Segmentation(实例分割)
model = YOLO('yolov8n-seg.pt')
results = model('image.jpg') # 返回masks3. Image Classification(图像分类)
model = YOLO('yolov8n-cls.pt')
results = model('image.jpg')4. Pose Estimation(姿态估计)
model = YOLO('yolov8n-pose.pt')
results = model('person.jpg') # 返回关键点5. Oriented Bounding Boxes(旋转框检测)
model = YOLO('yolov8n-obb.pt')
results = model('aerial.jpg') # 返回旋转边界框9.4.3 模型变体#
YOLOv8提供5个尺寸的模型:
Detection Models (COCO val2017):
| 模型 | mAP50-95 | 速度(A100) | 参数量 | FLOPs |
|---|---|---|---|---|
| YOLOv8n | 37.3 | 0.99ms | 3.2M | 8.7G |
| YOLOv8s | 44.9 | 1.20ms | 11.2M | 28.6G |
| YOLOv8m | 50.2 | 1.83ms | 25.9M | 78.9G |
| YOLOv8l | 52.9 | 2.39ms | 43.7M | 165.2G |
| YOLOv8x | 53.9 | 3.53ms | 68.2M | 257.8G |
Segmentation Models:
- YOLOv8n-seg: 36.7 mAP (box), 30.5 mAP (mask)
- YOLOv8s-seg: 44.6 / 36.8
- YOLOv8m-seg: 49.9 / 40.8
- YOLOv8l-seg: 52.3 / 42.6
- YOLOv8x-seg: 53.4 / 43.4
9.4.4 API设计#
Python API:简洁直观
from ultralytics import YOLO
# 加载模型
model = YOLO('yolov8n.yaml') # 从配置构建
model = YOLO('yolov8n.pt') # 加载预训练权重
model = YOLO('yolov8n.yaml').load('yolov8n.pt') # 组合
# 训练
results = model.train(
data='coco8.yaml',
epochs=100,
imgsz=640,
batch=16,
device=0
)
# 验证
metrics = model.val(data='coco8.yaml')
print(metrics.box.map) # mAP50-95
print(metrics.box.map50) # mAP50
# 推理
results = model('path/to/image.jpg')
results = model(['im1.jpg', 'im2.jpg']) # 批量
results = model('video.mp4') # 视频
# 导出
model.export(format='onnx')
model.export(format='engine', device=0) # TensorRTCLI命令:
# 训练
yolo detect train data=coco8.yaml model=yolov8n.pt epochs=100 imgsz=640
# 验证
yolo detect val model=yolov8n.pt data=coco8.yaml
# 推理
yolo detect predict model=yolov8n.pt source='image.jpg'
# 导出
yolo export model=yolov8n.pt format=onnx9.4.5 性能特点#
优势:
- 精度提升:相比YOLOv5,mAP平均提升2-3%
- 速度优化:Anchor-free设计加速后处理
- 易用性强:统一API,支持多任务
- 部署友好:支持多种导出格式
- 文档完善:官方文档详尽
适用场景:
- 实时目标检测
- 实例分割任务
- 边缘设备部署
- 工业质检应用
- 智能监控系统
9.5 YOLOv9、YOLOv10、YOLO11:最新进展#
9.5.1 YOLOv9:PGI和GELAN#
论文:YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information (arXiv 2024)
作者:Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao
发布时间:2024年2月
YOLOv9从信息理论角度重新审视深度学习,提出了两项关键创新。
核心贡献#
1. PGI (Programmable Gradient Information)
问题:深度网络中的信息瓶颈
- 随着网络加深,信息逐渐丢失
- 梯度消失/爆炸问题
- 可靠性降低
解决方案:PGI机制
主分支:用于推理
辅助分支:提供完整梯度信息(仅训练时)原理:
- 使用可逆函数(Reversible Functions)保证信息完整性
- 辅助分支生成可靠的梯度
- 主分支学习目标任务
数学表达:
X = v_ζ(r_ψ(X))
其中:
r_ψ: 信息转换函数
v_ζ: 信息恢复函数
确保信息可逆,无损失2. GELAN (Generalized Efficient Layer Aggregation Network)
GELAN是一种通用的高效网络架构:
特点:
- 轻量级设计
- 灵活的模块组合
- 优秀的参数利用率
- 高效的计算性能
架构:
Input
↓
GELAN Block 1 ─┐
↓ │
GELAN Block 2 ─┤ Concatenation
↓ │
GELAN Block 3 ─┘
↓
Output与CSP的区别:
- CSP:将特征图分成两部分
- GELAN:所有分支都参与计算,然后聚合
模型变体#
| 模型 | mAP50-95 | 参数量 | FLOPs |
|---|---|---|---|
| YOLOv9t | 38.3 | 2.0M | 7.7G |
| YOLOv9s | 46.8 | 7.2M | 26.7G |
| YOLOv9m | 51.4 | 20.1M | 76.8G |
| YOLOv9c | 53.0 | 25.5M | 102.8G |
| YOLOv9e | 55.6 | 58.1M | 192.5G |
性能对比#
vs YOLOv7:
- YOLOv9c: 参数量少42%,计算量少21%,精度相当
vs YOLOv8:
- YOLOv9e: 参数量少15%,计算量少25%,mAP提升1.7%
vs YOLO MS-S:
- YOLOv9s: 参数和计算量更少,AP提升0.4-0.6%
使用示例#
from ultralytics import YOLO
# 加载YOLOv9模型
model = YOLO('yolov9c.pt')
# 训练(注意:需要更多资源和时间)
results = model.train(
data='coco8.yaml',
epochs=500,
imgsz=640,
batch=16
)
# 推理
results = model('image.jpg')
# 导出
model.export(format='onnx')注意事项:
- YOLOv9训练需要更多资源
- 训练时间比YOLOv8更长
- 但推理性能更优
9.5.2 YOLOv10:NMS-Free端到端检测#
论文:YOLOv10: Real-Time End-to-End Object Detection (arXiv 2024)
作者:Ao Wang et al. (清华大学)
发布时间:2024年5月
YOLOv10的最大突破:消除NMS(Non-Maximum Suppression)
核心创新#
1. NMS-Free Training
传统YOLO流程:
网络输出 → 生成大量候选框 → NMS筛选 → 最终结果YOLOv10流程:
网络输出 → 直接得到最终结果(每个物体一个框)实现方式:Consistent Dual Assignments
- One-to-Many分支:训练时使用,提供丰富监督信号
- One-to-One分支:推理时使用,每个物体对应一个预测
2. 效率与精度优化
Efficiency Optimizations:
a) Lightweight Classification Head
- 使用深度可分离卷积(Depthwise Separable Conv)
- 减少分类头的计算量
b) Spatial-Channel Decoupled Downsampling
- 空间下采样和通道变换解耦
- 减少信息损失
c) Rank-Guided Block Design
- 根据特征的"内在冗余度"调整架构
- 在不同stage使用不同复杂度的block
Accuracy Enhancements:
a) Large-Kernel Convolutions
- 使用大核卷积(7x7)
- 扩大感受野
b) Partial Self-Attention (PSA)
- 仅在部分特征上使用自注意力
- 平衡性能和计算成本
模型变体#
YOLOv10提供6个变体,针对不同应用场景:
| 模型 | mAP50-95 | 延迟(T4) | 参数量 | FLOPs |
|---|---|---|---|---|
| YOLOv10-N | 38.5 | 1.84ms | 2.3M | 6.7G |
| YOLOv10-S | 46.3 | 2.49ms | 7.2M | 21.6G |
| YOLOv10-M | 51.1 | 4.74ms | 15.4M | 59.1G |
| YOLOv10-B | 52.5 | 5.74ms | 19.1M | 92.0G |
| YOLOv10-L | 53.2 | 7.28ms | 24.4M | 120.3G |
| YOLOv10-X | 54.4 | 10.70ms | 29.5M | 160.4G |
性能亮点#
速度对比:
- YOLOv10-S 比 RT-DETR-R18 快1.8倍,精度相当
- YOLOv10-B 比 YOLOv9-C 延迟降低46%,参数少25%,精度相当
NMS-Free的优势:
- 推理延迟降低(无需NMS后处理)
- 端到端可优化
- 更稳定的输出
使用示例#
from ultralytics import YOLO
# 加载YOLOv10模型
model = YOLO('yolov10n.pt') # 或 s/m/b/l/x
# 推理(无需NMS后处理)
results = model('image.jpg')
# 训练
model.train(
data='coco8.yaml',
epochs=100,
imgsz=640
)
# 导出(部分格式支持)
model.export(format='onnx') # ✅
model.export(format='engine') # ✅ TensorRT
# 注意:NCNN导出可能有限制9.5.3 YOLO11:当前最优方案#
发布时间:2024年9月
开发者:Ultralytics
版本号:YOLO11(也称YOLOv11)
YOLO11是Ultralytics的最新旗舰模型,在YOLOv8基础上进一步优化。
核心改进#
1. 增强的架构设计
- 改进的Backbone和Neck结构
- 更好的特征提取能力
- 优化的特征融合机制
2. 参数效率提升
相比YOLOv8m:
- 参数量减少22%
- mAP反而提高
- 计算效率更优
3. 优化的训练流程
- 更快的训练收敛
- 改进的数据增强策略
- 优化的损失函数
模型性能#
Detection (COCO val2017):
| 模型 | mAP50-95 | 速度(T4) | 参数量 | FLOPs |
|---|---|---|---|---|
| YOLO11n | 39.5 | 1.5ms | 2.6M | 6.5G |
| YOLO11s | 47.0 | 2.5ms | 9.4M | 21.5G |
| YOLO11m | 51.5 | 4.7ms | 20.1M | 68.0G |
| YOLO11l | 53.4 | 6.2ms | 25.3M | 86.9G |
| YOLO11x | 54.7 | 11.3ms | 56.9M | 194.9G |
关键指标对比(YOLO11m vs YOLOv8m):
- mAP: 51.5 vs 50.2 (+1.3%)
- 参数量: 20.1M vs 25.9M (-22%)
- FLOPs: 68.0G vs 78.9G (-14%)
多任务支持#
YOLO11同样支持多种任务:
1. Detection
model = YOLO('yolo11n.pt')2. Segmentation
model = YOLO('yolo11n-seg.pt')3. Classification
model = YOLO('yolo11n-cls.pt')4. Pose Estimation
model = YOLO('yolo11n-pose.pt')5. Oriented Bounding Boxes
model = YOLO('yolo11n-obb.pt')使用示例#
from ultralytics import YOLO
# 加载YOLO11模型
model = YOLO('yolo11n.pt')
# 训练
results = model.train(
data='coco8.yaml',
epochs=100,
imgsz=640,
batch=16,
device=0
)
# 验证
metrics = model.val(data='coco8.yaml')
# 推理
results = model('image.jpg')
results = model('video.mp4') # 视频
# 导出
model.export(format='onnx')
model.export(format='engine') # TensorRT
model.export(format='coreml') # CoreML适用场景#
- 边缘设备:YOLO11n/s参数少,适合移动端
- 云端部署:YOLO11m/l平衡性能
- 高精度需求:YOLO11x最高精度
- 实时应用:所有变体都支持实时推理
9.6 YOLO-World:开放词汇检测#
论文:YOLO-World: Real-Time Open-Vocabulary Object Detection
开发者:Tencent AI Lab & Ultralytics
发布时间:2024年
YOLO-World代表了目标检测的新方向:开放词汇检测(Open-Vocabulary Detection)
9.6.1 什么是开放词汇检测?#
传统检测:
- 只能检测训练时见过的类别
- 例如:COCO的80个类别
开放词汇检测:
- 可以检测任意文本描述的物体
- 无需重新训练
- 零样本检测能力
示例:
# 传统YOLO:只能检测预定义类别
classes = ['person', 'car', 'dog'] # 训练时固定
# YOLO-World:可以检测任意物体
model.set_classes(['laptop', 'coffee mug', 'smartphone']) # 动态设置
model.set_classes(['red car', 'person wearing hat']) # 支持描述性文本9.6.2 核心技术#
1. Vision-Language Pre-training
YOLO-World基于视觉-语言预训练:
- 使用大规模图像-文本对数据集
- 学习视觉和语言的联合表示
- 支持zero-shot推理
2. Re-parameterizable Vision-Language Path Aggregation Network (RepVL-PAN)
融合视觉和语言特征:
图像特征 ──┐
├─ RepVL-PAN ─→ 检测结果
文本特征 ──┘3. Region-Text Contrastive Loss
对比学习损失:
- 正样本:匹配的区域和文本
- 负样本:不匹配的区域和文本
- 学习区域-文本对齐
9.6.3 模型变体#
| 模型 | Zero-Shot AP | 参数量 | 特点 |
|---|---|---|---|
| YOLO-World-S | 35.4 | 13.4M | 轻量级 |
| YOLO-World-M | 43.0 | 34.3M | 平衡 |
| YOLO-World-L | 45.7 | 59.5M | 高精度 |
v2版本:
yolov8s-worldv2.pt:支持训练和导出yolov8m-worldv2.pt:推荐用于自定义训练yolov8l-worldv2.pt:最高精度
9.6.4 使用示例#
1. 基础使用
from ultralytics import YOLOWorld
# 加载预训练模型
model = YOLOWorld('yolov8s-world.pt')
# 设置自定义类别
model.set_classes(['person', 'bus', 'car'])
# 推理
results = model('image.jpg')
results[0].show()2. 动态切换类别
# 场景1:检测交通工具
model.set_classes(['car', 'bus', 'truck', 'bicycle'])
results = model('traffic.jpg')
# 场景2:检测动物
model.set_classes(['dog', 'cat', 'bird', 'horse'])
results = model('animals.jpg')
# 场景3:检测办公用品
model.set_classes(['laptop', 'mouse', 'keyboard', 'monitor'])
results = model('office.jpg')3. 保存自定义模型
# 设置类别后保存
model.set_classes(['person', 'car', 'dog'])
model.save('custom_yolov8s_world.pt')
# 之后可以直接加载
model = YOLOWorld('custom_yolov8s_world.pt')
results = model('image.jpg') # 使用保存的类别4. 训练自定义数据
from ultralytics import YOLOWorld
# 使用worldv2模型(支持训练)
model = YOLOWorld('yolov8s-worldv2.pt')
# 在自定义数据上训练
model.train(
data='custom_data.yaml',
epochs=100,
imgsz=640
)
# 导出
model.export(format='onnx') # worldv2支持导出9.6.5 应用场景#
1. 零样本检测
- 检测罕见物体
- 无需收集训练数据
2. 快速原型开发
- 快速验证想法
- 无需训练模型
3. 多场景应用
- 同一模型适应不同场景
- 动态调整检测类别
4. 长尾类别检测
- 处理训练数据不足的类别
- 利用预训练知识
9.6.6 性能特点#
优势:
- 零样本检测能力
- 灵活的类别设置
- 实时推理速度
- 无需重新训练
局限:
- 精度略低于专用检测器
- 对描述性文本的理解有限
- 需要合适的类别描述
vs 传统YOLO:
- 传统YOLO:固定类别,精度高
- YOLO-World:开放类别,灵活性强
9.7 YOLO系列总结与展望#
9.7.1 演进时间线#
2016 YOLOv1 开创单阶段检测
↓
2017 YOLOv2 Anchor + 多尺度
↓
2018 YOLOv3 多尺度预测 + Darknet-53
↓
2020 YOLOv4 Bag of Freebies/Specials
YOLOv5 工程化实现
↓
2022 YOLOv6 工业优化
YOLOv7 Trainable BoF
↓
2023 YOLOv8 Anchor-free + 多任务
↓
2024 YOLOv9 PGI + GELAN
YOLOv10 NMS-free
YOLO11 当前最优
YOLO-World 开放词汇9.7.2 技术趋势#
1. Anchor-Free成为主流
- YOLOv1: 直接预测
- YOLOv2-v7: Anchor-based
- YOLOv8+: Anchor-free
2. 端到端优化
- YOLOv10: 消除NMS
- 未来: 完全端到端可微
3. 多任务统一
- 检测、分割、分类、姿态估计
- 统一框架,降低学习成本
4. 开放词汇能力
- YOLO-World: 零样本检测
- 与大模型结合
9.7.3 版本选择建议#
项目需求导向:
| 需求 | 推荐版本 | 理由 |
|---|---|---|
| 工业部署 | YOLOv8/YOLO11 | 稳定、文档完善 |
| 最高精度 | YOLO11x/YOLOv9e | SOTA性能 |
| 边缘设备 | YOLO11n/YOLOv8n | 轻量级 |
| 学术研究 | YOLOv9/v10 | 创新技术 |
| 零样本检测 | YOLO-World | 开放词汇 |
| 快速原型 | YOLOv8 | 易用性强 |
学习路径建议:
- 入门:从YOLOv8开始,API简洁,文档丰富
- 进阶:学习YOLO11,了解最新优化
- 研究:深入YOLOv9/v10的创新技术
- 探索:尝试YOLO-World的开放词汇能力
9.7.4 未来展望#
技术方向:
- 与大模型深度融合
- 更强的零样本/少样本能力
- 端到端全流程优化
- 更高效的架构设计
应用拓展:
- 3D目标检测
- 视频理解
- 多模态融合
- 边缘智能
本章小结#
本章系统学习了YOLO系列从v1到v11的完整演进:
核心里程碑:
- YOLOv1:开创单阶段检测范式
- YOLOv3:多尺度预测成为标准
- YOLOv5:工程化降低使用门槛
- YOLOv8:Anchor-free + 多任务统一
- YOLO11:参数效率与性能的最优平衡
- YOLO-World:开启开放词汇时代
技术演进脉络:
- 检测范式:Anchor → Anchor-free → End-to-end
- 架构设计:Darknet → CSP → C2f → GELAN
- 训练策略:基础增强 → BoF/BoS → PGI
- 应用范围:单一检测 → 多任务 → 开放词汇
下一步: 完成理论学习后,让我们在第10章动手实践,用YOLOv8/YOLO11构建实际项目!
参考资源:
第10章:YOLO实战项目#
实战核心 - 从零开始,掌握YOLO的完整应用流程
本章概览#
本章将通过完整的实战项目,学习如何使用YOLOv8/YOLO11解决实际的目标检测问题。我们将覆盖从环境配置到模型部署的完整流程。
学习目标:
- 掌握YOLO的完整使用流程
- 能够在自定义数据集上训练模型
- 理解模型优化和部署技巧
- 构建实用的检测系统
实战项目:
- 使用预训练模型进行检测
- 准备自定义数据集并训练
- 模型导出和性能优化
- 构建实时检测系统
10.1 YOLOv8快速上手#
10.1.1 环境配置#
系统要求:
- Python >= 3.8
- PyTorch >= 1.8
- CUDA >= 11.0 (GPU加速,可选)
安装ultralytics库:
# 方式1:使用pip(推荐)
pip install ultralytics
# 方式2:从源码安装(获取最新功能)
git clone https://github.com/ultralytics/ultralytics.git
cd ultralytics
pip install -e .
# 验证安装
yolo version依赖检查:
# check_environment.py
import torch
from ultralytics import YOLO
print(f"PyTorch版本: {torch.__version__}")
print(f"CUDA可用: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"CUDA版本: {torch.version.cuda}")
print(f"GPU设备: {torch.cuda.get_device_name(0)}")
# 测试YOLO
model = YOLO('yolov8n.pt')
print("✅ Ultralytics YOLO安装成功!")10.1.2 预训练模型使用#
可用的预训练模型:
| 模型 | 任务 | 预训练数据集 |
|---|---|---|
| yolov8n.pt | 检测 | COCO |
| yolov8s.pt | 检测 | COCO |
| yolov8m.pt | 检测 | COCO |
| yolov8l.pt | 检测 | COCO |
| yolov8x.pt | 检测 | COCO |
| yolov8n-seg.pt | 分割 | COCO |
| yolov8n-pose.pt | 姿态 | COCO-Pose |
| yolov8n-cls.pt | 分类 | ImageNet |
| yolov8n-obb.pt | 旋转框 | DOTAv1 |
基础推理示例:
参见代码文件:code/chapter10_yolo_practice/yolov8_quickstart.py
10.1.3 理解检测结果#
Results对象结构:
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
results = model('image.jpg')
# Results是一个列表,每张图像对应一个Result对象
result = results[0]
# 主要属性
print(result.boxes) # 边界框信息
print(result.masks) # 分割掩码(如果是分割任务)
print(result.keypoints) # 关键点(如果是姿态任务)
print(result.probs) # 分类概率(如果是分类任务)
print(result.orig_img) # 原始图像
print(result.path) # 图像路径
# Boxes对象
boxes = result.boxes
print(boxes.xyxy) # 坐标格式: [x1, y1, x2, y2]
print(boxes.xywh) # 坐标格式: [x_center, y_center, width, height]
print(boxes.conf) # 置信度
print(boxes.cls) # 类别ID
print(boxes.data) # 完整数据 [x1, y1, x2, y2, conf, cls]可视化和保存:
# 方法1:直接显示
result.show()
# 方法2:保存到文件
result.save('result.jpg')
# 方法3:自定义绘制
import cv2
import numpy as np
img = result.orig_img.copy()
for box in result.boxes:
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy().astype(int)
conf = float(box.conf[0])
cls = int(box.cls[0])
# 绘制边界框
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
# 绘制标签
label = f"{model.names[cls]} {conf:.2f}"
cv2.putText(img, label, (x1, y1-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imwrite('custom_result.jpg', img)10.1.4 不同输入源的推理#
图像推理:
# 单张图像
results = model('image.jpg')
# 多张图像
results = model(['img1.jpg', 'img2.jpg', 'img3.jpg'])
# 文件夹
results = model('images/')
# URL
results = model('https://ultralytics.com/images/bus.jpg')
# NumPy数组
import cv2
img = cv2.imread('image.jpg')
results = model(img)
# PIL Image
from PIL import Image
img = Image.open('image.jpg')
results = model(img)视频推理:
# 视频文件
results = model('video.mp4', stream=True)
for result in results:
result.show() # 实时显示
# 或保存帧
# result.save(f'frame_{result.frame}.jpg')
# 摄像头
results = model(0, stream=True) # 0是默认摄像头
for result in results:
result.show()
if cv2.waitKey(1) & 0xFF == ord('q'):
break批量推理:
# 批量处理以提高速度
results = model(['img1.jpg', 'img2.jpg'], batch=2)
# 调整推理参数
results = model(
'image.jpg',
conf=0.5, # 置信度阈值
iou=0.7, # NMS的IoU阈值
imgsz=640, # 图像尺寸
device=0, # GPU设备
half=True, # 使用FP16
max_det=100, # 最大检测数
classes=[0, 2], # 只检测特定类别(person, car)
)10.2 自定义数据集训练#
10.2.1 数据集准备#
目录结构:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img1.jpg
│ │ ├── img2.jpg
│ │ └── ...
│ ├── val/
│ │ ├── img3.jpg
│ │ └── ...
│ └── test/ (可选)
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img1.txt
│ │ ├── img2.txt
│ │ └── ...
│ └── val/
│ ├── img3.txt
│ └── ...
└── data.yaml标注格式 (img1.txt):
# 每行一个目标: class x_center y_center width height
# 坐标都是归一化的 (0-1之间)
0 0.5 0.5 0.3 0.4
1 0.2 0.3 0.1 0.2数据集配置文件 (data.yaml):
# 数据集路径(相对或绝对路径)
path: /path/to/my_dataset # 数据集根目录
train: images/train # 训练图像(相对于path)
val: images/val # 验证图像(相对于path)
test: # 测试图像(可选)
# 类别
nc: 2 # 类别数量
names: # 类别名称
0: class1
1: class210.2.2 数据标注工具#
推荐工具:
LabelImg(最常用)
pip install labelImg labelImg- 输出格式选择YOLO
- 自动生成txt文件
Roboflow(在线工具)
- 支持协作标注
- 自动数据增强
- 一键导出YOLO格式
CVAT(功能强大)
- 支持多种标注任务
- 团队协作
- 导出时选择YOLO格式
从COCO格式转换:
from ultralytics.data.converter import convert_coco
# 转换COCO标注为YOLO格式
convert_coco(
labels_dir='path/to/coco/annotations/',
save_dir='path/to/yolo/labels/',
use_segments=False, # True表示分割任务
cls91to80=True # COCO91类到80类的映射
)10.2.3 数据增强#
内置数据增强(在训练时自动应用):
model.train(
data='data.yaml',
epochs=100,
# 数据增强参数
hsv_h=0.015, # HSV色调增强
hsv_s=0.7, # HSV饱和度
hsv_v=0.4, # HSV亮度
degrees=0.0, # 旋转角度
translate=0.1, # 平移比例
scale=0.5, # 缩放比例
shear=0.0, # 剪切角度
perspective=0.0, # 透视变换
flipud=0.0, # 上下翻转概率
fliplr=0.5, # 左右翻转概率
mosaic=1.0, # Mosaic增强概率
mixup=0.0, # MixUp增强概率
copy_paste=0.0, # Copy-Paste增强概率
)自定义数据增强:
import albumentations as A
from albumentations.pytorch import ToTensorV2
# 定义增强流程
transform = A.Compose([
A.RandomBrightnessContrast(p=0.5),
A.RandomGamma(p=0.5),
A.Blur(p=0.3),
A.MedianBlur(p=0.3),
A.GaussNoise(p=0.3),
], bbox_params=A.BboxParams(format='yolo'))
# 应用增强(需要自己写数据加载器)10.2.4 训练流程#
基础训练:
参见代码文件:code/chapter10_yolo_practice/yolov8_train_custom.py
训练参数详解:
model.train(
# === 数据相关 ===
data='data.yaml', # 数据集配置
epochs=100, # 训练轮数
batch=16, # 批量大小(-1为自动)
imgsz=640, # 图像尺寸
# === 优化器相关 ===
optimizer='auto', # 优化器: SGD, Adam, AdamW, auto
lr0=0.01, # 初始学习率
lrf=0.01, # 最终学习率 (lr0 * lrf)
momentum=0.937, # SGD动量
weight_decay=0.0005, # 权重衰减
warmup_epochs=3.0, # 预热轮数
warmup_momentum=0.8, # 预热动量
warmup_bias_lr=0.1, # 预热偏置学习率
# === 模型相关 ===
pretrained=True, # 使用预训练权重
patience=50, # 早停耐心值
save=True, # 保存检查点
save_period=-1, # 每N轮保存一次(-1表示仅最后)
# === 设备相关 ===
device=0, # 设备: 0, [0,1], cpu
workers=8, # 数据加载线程数
amp=True, # 自动混合精度训练
# === 验证相关 ===
val=True, # 每轮后验证
plots=True, # 保存训练图表
# === 其他 ===
seed=0, # 随机种子
deterministic=True, # 确定性训练
single_cls=False, # 单类训练
rect=False, # 矩形训练
cos_lr=False, # 余弦学习率
close_mosaic=10, # 最后N轮禁用mosaic
resume=False, # 恢复训练
project='runs/detect', # 项目目录
name='exp', # 实验名称
exist_ok=False, # 覆盖已存在的实验
)多GPU训练:
# 使用所有可用GPU
yolo detect train data=data.yaml model=yolov8n.pt epochs=100 device=0,1,2,3
# Python API
model.train(data='data.yaml', device=[0, 1, 2, 3])恢复训练:
# 从检查点恢复
model = YOLO('runs/detect/exp/weights/last.pt')
model.train(resume=True)10.2.5 训练监控#
实时监控:
# 使用回调函数
from ultralytics.utils import callbacks
def on_train_epoch_end(trainer):
print(f"Epoch {trainer.epoch}: Loss={trainer.loss}")
callbacks.on_train_epoch_end = on_train_epoch_end
model.train(data='data.yaml', epochs=100)TensorBoard可视化:
# 启动TensorBoard
tensorboard --logdir runs/detect
# 在浏览器打开 http://localhost:6006Weights & Biases集成:
from ultralytics import YOLO
# 自动集成W&B(需要先登录)
# wandb login
model = YOLO('yolov8n.pt')
model.train(
data='data.yaml',
epochs=100,
project='my-yolo-project', # W&B项目名
)10.2.6 模型验证#
验证训练好的模型:
from ultralytics import YOLO
# 加载训练好的模型
model = YOLO('runs/detect/exp/weights/best.pt')
# 验证
metrics = model.val(
data='data.yaml',
split='val', # 或 'test'
imgsz=640,
batch=16,
conf=0.25,
iou=0.6,
device=0,
)
# 查看指标
print(f"mAP50-95: {metrics.box.map}")
print(f"mAP50: {metrics.box.map50}")
print(f"mAP75: {metrics.box.map75}")
# 各类别的AP
for i, ap in enumerate(metrics.box.ap_class_index):
print(f"{model.names[i]}: {metrics.box.ap[ap]:.3f}")混淆矩阵分析:
# 训练时会自动生成混淆矩阵
# 查看: runs/detect/exp/confusion_matrix.png
# 或手动生成
from ultralytics.utils.plotting import plot_results
plot_results(file='runs/detect/exp/results.csv')10.3 模型导出与部署#
10.3.1 模型导出#
参见代码文件:code/chapter10_yolo_practice/yolov8_export.py
支持的导出格式:
| 格式 | 参数 | 用途 |
|---|---|---|
| PyTorch | .pt | Python推理 |
| TorchScript | torchscript | 部署 |
| ONNX | onnx | 跨平台 |
| OpenVINO | openvino | Intel优化 |
| TensorRT | engine | NVIDIA GPU |
| CoreML | coreml | iOS/macOS |
| TF SavedModel | saved_model | TensorFlow |
| TF GraphDef | pb | TensorFlow |
| TFLite | tflite | 移动端 |
| TFLite Edge TPU | edgetpu | Edge TPU |
| TF.js | tfjs | Web |
| PaddlePaddle | paddle | 百度飞桨 |
| NCNN | ncnn | 移动端 |
导出示例:
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
# ONNX导出(最通用)
model.export(format='onnx')
# TensorRT导出(NVIDIA GPU加速)
model.export(format='engine', device=0, half=True)
# CoreML导出(iOS)
model.export(format='coreml')
# TFLite导出(移动端)
model.export(format='tflite')10.3.2 ONNX推理#
使用ONNX Runtime:
import onnxruntime as ort
import numpy as np
import cv2
# 加载ONNX模型
session = ort.InferenceSession(
'yolov8n.onnx',
providers=['CUDAExecutionProvider', 'CPUExecutionProvider']
)
# 预处理
img = cv2.imread('image.jpg')
img = cv2.resize(img, (640, 640))
img = img.transpose(2, 0, 1) # HWC -> CHW
img = img.astype(np.float32) / 255.0
img = np.expand_dims(img, 0) # 添加batch维度
# 推理
input_name = session.get_inputs()[0].name
outputs = session.run(None, {input_name: img})
# 后处理
predictions = outputs[0] # shape: (1, 84, 8400)
# 需要进行NMS等后处理...完整的ONNX推理流程:
import onnxruntime as ort
import cv2
import numpy as np
class YOLOv8ONNX:
def __init__(self, onnx_path, conf_threshold=0.5, iou_threshold=0.5):
self.session = ort.InferenceSession(onnx_path)
self.conf_threshold = conf_threshold
self.iou_threshold = iou_threshold
self.input_name = self.session.get_inputs()[0].name
def preprocess(self, img):
img = cv2.resize(img, (640, 640))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.transpose(2, 0, 1)
img = img.astype(np.float32) / 255.0
return np.expand_dims(img, 0)
def postprocess(self, outputs, orig_shape):
predictions = outputs[0].transpose(0, 2, 1) # (1, 84, 8400) -> (1, 8400, 84)
boxes, scores, class_ids = [], [], []
for pred in predictions[0]:
# pred: [x, y, w, h, cls0_conf, cls1_conf, ...]
box = pred[:4]
class_scores = pred[4:]
class_id = np.argmax(class_scores)
conf = class_scores[class_id]
if conf > self.conf_threshold:
# 转换坐标
x, y, w, h = box
x1 = x - w/2
y1 = y - h/2
x2 = x + w/2
y2 = y + h/2
boxes.append([x1, y1, x2, y2])
scores.append(conf)
class_ids.append(class_id)
# NMS
indices = cv2.dnn.NMSBoxes(
boxes, scores, self.conf_threshold, self.iou_threshold
)
results = []
for i in indices:
results.append({
'box': boxes[i],
'score': scores[i],
'class_id': class_ids[i]
})
return results
def detect(self, img):
orig_shape = img.shape[:2]
input_tensor = self.preprocess(img)
outputs = self.session.run(None, {self.input_name: input_tensor})
return self.postprocess(outputs, orig_shape)
# 使用
detector = YOLOv8ONNX('yolov8n.onnx')
img = cv2.imread('image.jpg')
results = detector.detect(img)10.3.3 TensorRT加速#
导出TensorRT引擎:
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
# 导出TensorRT引擎
model.export(
format='engine',
device=0, # GPU设备
half=True, # FP16精度
workspace=4, # 工作空间大小(GB)
simplify=True, # 简化ONNX
dynamic=False, # 动态batch
)使用TensorRT推理:
from ultralytics import YOLO
# 直接加载TensorRT引擎
model = YOLO('yolov8n.engine')
# 推理(速度显著提升)
results = model('image.jpg')性能对比:
| 模型格式 | 延迟(V100) | 加速比 |
|---|---|---|
| PyTorch (FP32) | 3.5ms | 1.0x |
| ONNX (FP32) | 2.8ms | 1.25x |
| TensorRT (FP32) | 1.5ms | 2.3x |
| TensorRT (FP16) | 0.8ms | 4.4x |
10.3.4 移动端部署#
iOS (CoreML):
# 导出CoreML
model.export(format='coreml', nms=True)
# iOS Swift代码
// import CoreML
// let model = try yolov8n(configuration: MLModelConfiguration())
// let prediction = try model.prediction(image: pixelBuffer)Android (TFLite):
# 导出TFLite
model.export(format='tflite', int8=True) # INT8量化
# Android Kotlin代码
// import org.tensorflow.lite.Interpreter
// val interpreter = Interpreter(loadModelFile())
// interpreter.run(inputArray, outputArray)边缘设备 (NCNN):
# 导出NCNN
model.export(format='ncnn')
# C++代码
// #include "ncnn/net.h"
// ncnn::Net net;
// net.load_param("yolov8n.param");
// net.load_model("yolov8n.bin");10.4 实战:构建实时检测系统#
10.4.1 项目需求分析#
项目目标:构建一个实时视频检测系统
功能需求:
- 支持多种输入源(摄像头、视频文件、RTSP流)
- 实时检测并显示结果
- 支持录制检测结果
- 性能监控(FPS、延迟)
- 可配置的检测参数
技术选型:
- 检测模型:YOLOv8n/s(平衡速度和精度)
- 视频处理:OpenCV
- 界面:OpenCV GUI 或 Gradio
- 部署:Docker容器化
10.4.2 系统架构设计#
┌─────────────────────────────────────────┐
│ Input Sources │
│ (Webcam / Video / RTSP Stream) │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Frame Preprocessing │
│ (Resize, Normalize, Format) │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ YOLO Detection Engine │
│ (Model Inference + Post-process) │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Result Rendering │
│ (Draw Boxes, Labels, FPS) │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Output & Storage │
│ (Display / Save / Stream) │
└─────────────────────────────────────────┘10.4.3 完整代码实现#
主系统类:
# real_time_detector.py
import cv2
import time
from ultralytics import YOLO
from collections import deque
import numpy as np
class RealTimeDetector:
"""实时目标检测系统"""
def __init__(self, model_path='yolov8n.pt', conf_threshold=0.5):
"""
Args:
model_path: YOLO模型路径
conf_threshold: 置信度阈值
"""
self.model = YOLO(model_path)
self.conf_threshold = conf_threshold
# 性能监控
self.fps_queue = deque(maxlen=30)
self.process_times = deque(maxlen=100)
# 统计信息
self.frame_count = 0
self.detection_count = 0
def detect_frame(self, frame):
"""
检测单帧
Args:
frame: 输入图像(BGR)
Returns:
result: YOLO检测结果
process_time: 处理时间(ms)
"""
start_time = time.time()
# YOLO推理
results = self.model(
frame,
conf=self.conf_threshold,
verbose=False
)
process_time = (time.time() - start_time) * 1000
self.process_times.append(process_time)
return results[0], process_time
def draw_results(self, frame, result):
"""
在图像上绘制检测结果
Args:
frame: 输入图像
result: YOLO检测结果
Returns:
frame: 绘制后的图像
"""
# 复制图像避免修改原图
annotated_frame = frame.copy()
# 绘制边界框
boxes = result.boxes
if boxes is not None:
for box in boxes:
# 获取坐标和信息
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy().astype(int)
conf = float(box.conf[0])
cls = int(box.cls[0])
# 绘制矩形
color = self._get_color(cls)
cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)
# 绘制标签
label = f"{self.model.names[cls]} {conf:.2f}"
label_size, _ = cv2.getTextSize(
label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1
)
# 标签背景
cv2.rectangle(
annotated_frame,
(x1, y1 - label_size[1] - 10),
(x1 + label_size[0], y1),
color,
-1
)
# 标签文字
cv2.putText(
annotated_frame,
label,
(x1, y1 - 5),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
(255, 255, 255),
1
)
self.detection_count += 1
return annotated_frame
def draw_stats(self, frame):
"""
绘制统计信息
Args:
frame: 输入图像
Returns:
frame: 添加统计信息后的图像
"""
# 计算FPS
if len(self.fps_queue) > 0:
fps = len(self.fps_queue) / sum(self.fps_queue)
else:
fps = 0
# 计算平均处理时间
avg_process_time = np.mean(self.process_times) if self.process_times else 0
# 准备统计文本
stats = [
f"FPS: {fps:.1f}",
f"Process Time: {avg_process_time:.1f}ms",
f"Frame: {self.frame_count}",
f"Detections: {self.detection_count}",
]
# 绘制半透明背景
overlay = frame.copy()
cv2.rectangle(overlay, (10, 10), (300, 120), (0, 0, 0), -1)
cv2.addWeighted(overlay, 0.6, frame, 0.4, 0, frame)
# 绘制统计文本
y_offset = 30
for stat in stats:
cv2.putText(
frame,
stat,
(20, y_offset),
cv2.FONT_HERSHEY_SIMPLEX,
0.6,
(0, 255, 0),
2
)
y_offset += 25
return frame
def process_video(self, source=0, output_path=None, display=True):
"""
处理视频流
Args:
source: 视频源(0=摄像头,路径=视频文件,URL=RTSP流)
output_path: 输出视频路径(可选)
display: 是否显示结果
"""
# 打开视频流
cap = cv2.VideoCapture(source)
if not cap.isOpened():
raise ValueError(f"无法打开视频源: {source}")
# 获取视频属性
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"视频源信息: {width}x{height} @ {fps}FPS")
# 创建视频写入器
writer = None
if output_path:
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
# 重置统计
self.frame_count = 0
self.detection_count = 0
print("开始处理... (按'q'退出)")
try:
while True:
frame_start = time.time()
# 读取帧
ret, frame = cap.read()
if not ret:
break
self.frame_count += 1
# 检测
result, process_time = self.detect_frame(frame)
# 绘制结果
annotated_frame = self.draw_results(frame, result)
# 绘制统计信息
annotated_frame = self.draw_stats(annotated_frame)
# 保存视频
if writer:
writer.write(annotated_frame)
# 显示
if display:
cv2.imshow('YOLO Real-Time Detection', annotated_frame)
# 按键处理
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('s'): # 截图
cv2.imwrite(f'screenshot_{self.frame_count}.jpg', annotated_frame)
print(f"截图已保存: screenshot_{self.frame_count}.jpg")
# 更新FPS
frame_time = time.time() - frame_start
self.fps_queue.append(frame_time)
finally:
# 清理资源
cap.release()
if writer:
writer.release()
if display:
cv2.destroyAllWindows()
print(f"\n处理完成!")
print(f"总帧数: {self.frame_count}")
print(f"总检测数: {self.detection_count}")
print(f"平均FPS: {self.frame_count / sum(self.fps_queue):.2f}")
def _get_color(self, class_id):
"""获取类别颜色"""
np.random.seed(class_id)
return tuple(np.random.randint(0, 255, 3).tolist())
# 使用示例
if __name__ == '__main__':
# 创建检测器
detector = RealTimeDetector(
model_path='yolov8n.pt',
conf_threshold=0.5
)
# 处理摄像头
detector.process_video(source=0, output_path='output.mp4')
# 或处理视频文件
# detector.process_video(source='input.mp4', output_path='output.mp4')
# 或处理RTSP流
# detector.process_video(source='rtsp://...', display=True)10.4.4 性能优化技巧#
1. 模型优化:
# 使用较小的模型
detector = RealTimeDetector('yolov8n.pt') # 而非yolov8x.pt
# 降低输入分辨率
results = model(frame, imgsz=416) # 默认640
# 使用FP16精度
results = model(frame, half=True)
# 减少检测类别
results = model(frame, classes=[0, 2, 5]) # 只检测特定类别2. 多线程处理:
from threading import Thread
from queue import Queue
class ThreadedDetector(RealTimeDetector):
"""多线程检测器"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.frame_queue = Queue(maxsize=10)
self.result_queue = Queue(maxsize=10)
def capture_thread(self, source):
"""视频捕获线程"""
cap = cv2.VideoCapture(source)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
self.frame_queue.put(frame)
cap.release()
def detection_thread(self):
"""检测线程"""
while True:
frame = self.frame_queue.get()
if frame is None:
break
result, _ = self.detect_frame(frame)
self.result_queue.put((frame, result))
def process_video_threaded(self, source=0):
"""多线程处理"""
# 启动捕获线程
capture = Thread(target=self.capture_thread, args=(source,))
capture.daemon = True
capture.start()
# 启动检测线程
detection = Thread(target=self.detection_thread)
detection.daemon = True
detection.start()
# 主线程显示
while True:
if not self.result_queue.empty():
frame, result = self.result_queue.get()
annotated = self.draw_results(frame, result)
annotated = self.draw_stats(annotated)
cv2.imshow('Detection', annotated)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()3. GPU批处理:
def batch_detect(self, frames):
"""批量检测多帧"""
results = self.model(frames, batch=len(frames))
return results10.4.5 Gradio Web界面#
构建Web应用:
import gradio as gr
from ultralytics import YOLO
# 加载模型
model = YOLO('yolov8n.pt')
def detect_image(image, conf_threshold):
"""图像检测函数"""
results = model(image, conf=conf_threshold)
return results[0].plot()
def detect_video(video, conf_threshold):
"""视频检测函数"""
# 处理视频并返回
pass
# 创建Gradio界面
with gr.Blocks() as demo:
gr.Markdown("# YOLO实时检测系统")
with gr.Tab("图像检测"):
with gr.Row():
image_input = gr.Image()
image_output = gr.Image()
image_conf = gr.Slider(0, 1, 0.5, label="置信度阈值")
image_btn = gr.Button("检测")
image_btn.click(
detect_image,
inputs=[image_input, image_conf],
outputs=image_output
)
with gr.Tab("视频检测"):
with gr.Row():
video_input = gr.Video()
video_output = gr.Video()
video_conf = gr.Slider(0, 1, 0.5, label="置信度阈值")
video_btn = gr.Button("检测")
video_btn.click(
detect_video,
inputs=[video_input, video_conf],
outputs=video_output
)
# 启动应用
demo.launch(share=True)10.4.6 Docker容器化部署#
Dockerfile:
FROM ultralytics/ultralytics:latest
WORKDIR /app
# 复制应用代码
COPY real_time_detector.py /app/
COPY requirements.txt /app/
# 安装依赖
RUN pip install -r requirements.txt
# 下载模型
RUN yolo download yolov8n.pt
# 暴露端口(如果使用Gradio)
EXPOSE 7860
# 启动命令
CMD ["python", "real_time_detector.py"]docker-compose.yml:
version: '3.8'
services:
yolo-detector:
build: .
container_name: yolo_detector
runtime: nvidia # 使用GPU
environment:
- NVIDIA_VISIBLE_DEVICES=all
volumes:
- ./videos:/app/videos
- ./outputs:/app/outputs
ports:
- "7860:7860"
command: python app.py启动:
# 构建镜像
docker-compose build
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f10.5 最佳实践与常见问题#
10.5.1 最佳实践#
1. 数据集准备
- 确保标注质量:使用多人交叉验证
- 数据平衡:各类别样本数量要均衡
- 数据增强:适度使用,避免过度
- 验证集选择:确保与训练集分布一致
2. 训练策略
- 使用预训练权重:从COCO开始微调
- 学习率调整:使用warmup和cosine schedule
- 早停策略:设置patience避免过拟合
- 多尺度训练:提升对不同尺度的鲁棒性
3. 性能优化
- 选择合适的模型大小:n/s用于实时,m/l/x用于精度
- 量化加速:FP16或INT8量化
- 批处理:合理设置batch size
- TensorRT:在NVIDIA GPU上使用TensorRT
4. 部署建议
- 容器化:使用Docker统一环境
- 监控:添加性能监控和日志
- 版本管理:模型版本控制
- A/B测试:新旧模型对比测试
10.5.2 常见问题#
Q1: 训练loss不下降?
A: 检查以下几点:
- 学习率是否合适(尝试降低)
- 数据标注是否正确
- 是否使用了预训练权重
- batch size是否太小
Q2: mAP很低?
A: 可能原因:
- 训练轮数不够(增加epochs)
- 数据集质量问题(检查标注)
- 模型太小(尝试更大的模型)
- 超参数不合适(调整学习率、数据增强)
Q3: 推理速度慢?
A: 优化方法:
- 使用更小的模型(yolov8n)
- 降低输入分辨率
- 使用FP16/INT8
- TensorRT加速
- 批处理多张图像
Q4: GPU内存不足?
A: 解决方案:
- 减小batch size
- 使用更小的模型
- 降低图像分辨率
- 使用梯度累积
Q5: 检测结果不稳定?
A: 调整参数:
- 提高置信度阈值
- 调整NMS的IoU阈值
- 使用时序平滑(视频检测)
本章小结#
本章通过完整的实战项目,我们学习了:
核心技能:
- YOLOv8的快速上手和基础使用
- 自定义数据集的准备和训练流程
- 模型导出和多种部署方案
- 实时检测系统的完整开发
实战成果:
- 完整的训练pipeline
- 多格式模型导出(ONNX、TensorRT等)
- 实时检测系统原型
- Web应用和容器化部署
下一步:
- 探索YOLO的其他任务(分割、姿态估计)
- 学习模型优化技术(剪枝、蒸馏)
- 深入研究最新的YOLO变体
- 将YOLO应用到实际项目中
完整代码:
- yolov8_quickstart.py - 快速入门
- yolov8_train_custom.py - 自定义训练
- yolov8_export.py - 模型导出
参考资源:
恭喜你完成第四篇的学习!你已经掌握了YOLO系列从理论到实战的完整知识体系。