YOLOv5理论讲解
一、YOLOv5 整体架构解析
YOLOv5 延续了 YOLO 系列的 单阶段目标检测框架,包含 主干网络(Backbone)、颈部网络(Neck) 和 检测头(Head),但在结构设计上更注重 轻量化 和 硬件适应性。
1. 主干网络(Backbone)
-
CSPDarknet 优化:
基于 YOLOv4 的 CSPDarknet53,YOLOv5 进一步改进为 CSPDarknet(不同尺度版本),通过 跨阶段局部连接(CSP) 减少计算量,同时保持特征提取能力。
✅ 改进点:- 引入 动态深度和宽度因子(
depth_multiple
和width_multiple
),支持生成不同尺度模型(如 YOLOv5s/m/l/x),轻量化模型(如 YOLOv5s)更适合边缘设备。 - 早期版本包含 Focus 结构(将图像分块后拼接,减少下采样信息损失),但后续版本因兼容性问题移除,改为普通卷积。
- 激活函数从 LeakyReLU 改为 SiLU(又称 Swish),提升非线性表达能力。
- 引入 动态深度和宽度因子(
-
特征金字塔优化:
采用 跨层连接(FPN-like) 融合多尺度特征,增强对不同大小目标的检测能力。
2. 颈部网络(Neck)
- 路径聚合网络(PANet):
与 YOLOv4 相同,采用 PANet 结构,通过 自顶向下和自底向上的特征融合,增强特征传播效率。
✅ 改进点:- 轻量化设计:减少部分卷积层,通过调整通道数(如
width_multiple
)降低计算量。 - 更灵活的特征融合方式,支持动态输入尺寸下的高效计算。
- 轻量化设计:减少部分卷积层,通过调整通道数(如
3. 检测头(Head)
- 多尺度检测:
沿用 YOLOv4 的 3 尺度检测(小、中、大目标),但预测头结构更简洁,采用 解耦头(分类和回归分支分离)。
✅ 改进点:- 自适应锚框计算:训练时根据数据集自动优化锚框尺寸(YOLOv4 使用预设锚框),减少人工调参成本。
- 动态输入尺寸:支持训练和推理时的 自适应图片缩放(Letterbox 优化),通过计算黑边填充比例减少无效区域,提升推理效率(YOLOv4 需固定尺寸输入)。
二、YOLOv5 核心改进(对比 YOLOv4)
1. 模型轻量化与多尺度支持 ✅
- 统一架构设计:
通过 yaml 配置文件定义不同尺度模型(YOLOv5s/m/l/x),仅需调整depth_multiple
(深度因子)和width_multiple
(宽度因子)即可生成轻量化或高性能模型。- YOLOv5s:参数约 7MB,适合嵌入式设备;
- YOLOv5x:参数约 87MB,适合服务器端高精度需求。
- 对比 YOLOv4:
YOLOv4 仅有固定结构(如 CSPDarknet53),轻量化需手动修改网络,灵活性较低。
2. 自适应训练与推理优化 ✅
- 自适应锚框(Auto Anchor):
YOLOv5 在训练初期自动计算最优锚框(基于数据集),而 YOLOv4 使用预定义锚框(如 COCO 数据集的 9 组锚框),需人工调整。 - 自适应图片缩放(Letterbox 优化):
推理时根据图像长宽比计算最小黑边填充,减少无效背景区域(YOLOv4 直接缩放至固定尺寸,可能引入较多黑边),提升推理速度约 10%–20%。 - 动态输入尺寸:
支持训练和推理时的任意尺寸输入(需为 32 的倍数),而 YOLOv4 需固定尺寸(如 608x608)。
3. 代码工程化与部署支持 ✅
- PyTorch 原生实现:
YOLOv5 完全基于 PyTorch 框架,而 YOLOv4 使用 Darknet(C 语言),PyTorch 提供了更便捷的训练、调试和可视化工具(如 TensorBoard)。 - 多平台部署支持:
原生支持导出为 ONNX、TensorRT、CoreML、TorchScript 等格式,适配 CPU/GPU/边缘设备(如 NVIDIA Jetson、树莓派),YOLOv4 需额外工具转换。 - 代码简洁性:
代码结构更模块化,易于修改(如替换主干网络、调整数据增强策略),YOLOv4 的 Darknet 代码相对复杂。
4. 训练策略与数据增强
- 数据增强:
沿用 YOLOv4 的 Mosaic、MixUp、高斯模糊 等增强方式,但 YOLOv5 引入 自动增强(AutoAugment) 和 Copy-Paste(随机复制目标到其他图像),提升小目标检测性能。 - 优化器与学习率策略:
使用 SGD + 余弦退火学习率衰减,YOLOv4 采用阶梯式学习率衰减,余弦退火可更平滑地调整学习率,提升收敛稳定性。 - 混合精度训练:
原生支持 FP16 混合精度,减少显存占用并加速训练,YOLOv4 需手动配置。
5. 损失函数与正负样本分配
-
损失函数:
分类损失采用 交叉熵,回归损失采用 CIoU Loss(与 YOLOv4 相同),但 YOLOv5 引入 损失函数权重动态调整,根据目标大小自动分配损失权重。
-
正负样本分配:
YOLOv4 使用 基于锚框 IoU 的启发式分配,YOLOv5 早期版本沿用此方法,后期版本(如 v6.0+)引入 SimOTA(基于代价敏感的动态分配),提升正负样本匹配效率,但严格来说 SimOTA 属于后续更新,非 YOLOv5 初始版本特性。
6. 推理速度与精度平衡 ✅
- 速度优化:
- 减少卷积层的通道数(如使用
width_multiple
缩小通道); - 利用 PyTorch 的 JIT 编译 和 CUDA 优化,同等条件下 YOLOv5s 推理速度比 YOLOv4-tiny 更快。
- 减少卷积层的通道数(如使用
- 精度对比:
在 COCO 数据集上,YOLOv5s/m/l/x 的 AP(平均精度)略高于同级别轻量化模型(如 YOLOv4-tiny、YOLOv4-csp),但低于 YOLOv4 完整版(如 CSPDarknet53+PAN),体现其 速度-精度平衡 的设计目标。
三、YOLOv5 与 YOLOv4 关键差异总结
维度 | YOLOv4 | YOLOv5 |
---|---|---|
框架 | Darknet(C) | PyTorch |
模型尺度 | 单一结构(需手动修改轻量化) | 多尺度(s/m/l/x,通过因子自动调整) |
锚框机制 | 预定义锚框(需手动调参) | 自适应锚框(训练自动生成) |
输入尺寸 | 固定尺寸(如 608x608) | 动态尺寸 + 自适应缩放(减少黑边) |
部署支持 | 需要转换工具(如 ONNX 插件) | 原生支持多格式导出(ONNX/TensorRT 等) |
训练效率 | 混合精度需手动配置 | 原生支持 FP16/FP32 混合精度 |
代码维护 | 依赖 Darknet 生态,扩展性较低 | PyTorch 生态友好,代码模块化易修改 |
轻量化设计 | 依赖第三方轻量化版本(如 YOLOv4-tiny) | 原生支持轻量化(YOLOv5s 参数仅 7MB) |
数据增强 | Mosaic/MixUp + 手动配置 | 自动增强 + Copy-Paste + 更灵活的策略 |
源代码框架讲解
好的,我将深入讲解 YOLOv5 源代码的核心结构和功能,覆盖 95% 以上的知识点。以下是详细分析:
1. 核心文件夹结构
YOLOv5 的源代码主要分为以下几个核心模块:
yolov5/
├── models/ # 模型架构定义
├── utils/ # 工具函数和辅助模块
├── data/ # 数据集配置和加载
├── weights/ # 预训练模型权重
├── runs/ # 训练和推理结果保存目录
├── detect.py # 目标检测推理脚本
├── train.py # 模型训练脚本
├── val.py # 模型验证脚本
├── export.py # 模型导出脚本
└── requirements.txt # 依赖包列表
2. models/
文件夹
该文件夹定义了 YOLOv5 的模型架构,主要包含:
核心文件
-
common.py
:
实现了 YOLOv5 中通用的神经网络模块,如:Conv
:标准卷积 + BatchNorm + SiLU 激活Bottleneck
:残差块C3
:CSP Bottleneck with 3 convolutionsSPPF
:空间金字塔池化模块Focus
:下采样模块(仅早期版本使用)
-
yolo.py
:
定义了 YOLOv5 的核心模型结构:Model
类:解析模型配置文件(.yaml)并构建完整网络- 检测头(Detection Head):负责边界框预测、分类和置信度计算
-
.yaml
配置文件:
定义不同规模的模型架构(如yolov5s.yaml
,yolov5m.yaml
),包含:- 网络深度和宽度参数
- 锚点(anchors)配置
- 网络层结构定义
使用方法
# 从配置文件构建模型
from models.yolo import Model
model = Model(cfg='models/yolov5s.yaml')
3. utils/
文件夹
该文件夹包含大量工具函数和辅助模块,按功能划分为多个子模块:
数据处理 (utils/datasets.py
)
LoadImages
:加载图像或视频进行推理LoadWebcam
:从摄像头实时捕获图像LoadImagesAndLabels
:加载训练数据和标签- 数据增强:Mosaic 拼接、MixUp 混合、随机旋转、缩放等
训练辅助 (utils/train.py
, utils/loss.py
)
- 损失函数:
ComputeLoss
:计算总损失(边界框损失 + 分类损失 + 置信度损失)- GIoU/DIoU/CIoU 损失:更精确的边界框回归度量
- 优化器配置:支持 Adam、SGD 等
- 学习率调度:余弦退火、线性衰减等
模型工具 (utils/torch_utils.py
, utils/metrics.py
)
- 模型初始化:权重初始化策略
- 混合精度训练:使用 PyTorch 的 Automatic Mixed Precision (AMP)
- 评估指标:计算 mAP(mean Average Precision)、PR 曲线等
日志与可视化 (utils/loggers/
, utils/plots.py
)
- 日志记录:支持 TensorBoard、Weights & Biases (W&B) 等
- 可视化工具:绘制检测结果、训练曲线、混淆矩阵等
其他工具
utils/autoanchor.py
:自动计算数据集的最优锚点utils/general.py
:通用工具函数(如文件操作、进度条、系统信息等)
4. data/
文件夹
该文件夹管理数据集配置和加载,主要包含:
数据集配置文件 (.yaml)
- 定义数据集路径、类别数和类别名称
# 示例:coco128.yaml train: ../datasets/coco128/images/train2017/ val: ../datasets/coco128/images/train2017/nc: 80 # 类别数 names: ['person', 'bicycle', 'car', ...] # 类别名称
数据加载脚本
data/scripts/
:包含下载和准备数据集的脚本(如 COCO、VOC、YOLO 格式转换)
5. weights/
文件夹
存放预训练模型权重文件(.pt 格式),如:
yolov5s.pt
:YOLOv5-small 预训练权重yolov5m.pt
:YOLOv5-medium 预训练权重yolov5l.pt
:YOLOv5-large 预训练权重yolov5x.pt
:YOLOv5-xlarge 预训练权重
6. 核心脚本功能
train.py
:模型训练
# 示例:在 COCO 数据集上训练 YOLOv5s
python train.py --img 640 --batch 16 --epochs 100 \--data data/coco.yaml --cfg models/yolov5s.yaml \--weights yolov5s.pt --name exp1
关键参数:
--img
:输入图像尺寸--batch
:批处理大小--epochs
:训练轮数--data
:数据集配置文件--weights
:预训练权重路径
detect.py
:目标检测推理
# 示例:对图像/视频进行检测
python detect.py --source path/to/image/or/video \--weights runs/train/exp1/weights/best.pt \--conf 0.4 --iou 0.5
关键参数:
--source
:输入源(图像、视频、摄像头)--conf
:置信度阈值--iou
:NMS(非极大值抑制)的 IoU 阈值
val.py
:模型验证
# 示例:在验证集上评估模型性能
python val.py --data data/coco.yaml \--weights runs/train/exp1/weights/best.pt \--img 640 --batch 32
输出指标:mAP@0.5、mAP@0.5:0.95 等
export.py
:模型导出
# 示例:导出为 ONNX 格式
python export.py --weights yolov5s.pt \--img 640 --batch 1 --include onnx
支持格式:ONNX、TensorRT、TensorFlow、CoreML 等
7. 高级特性
多 GPU 训练
# 使用 DDP (Distributed Data Parallel) 进行多 GPU 训练
python -m torch.distributed.run --nproc_per_node 4 train.py ...
超参数优化
# 使用 hyperparameter evolution 搜索最优超参数
python train.py --hyp data/hyps/hyp.scratch.yaml --evolve
自定义数据集训练
- 准备数据集(按 YOLO 格式组织)
- 创建自定义
.yaml
配置文件 - 启动训练:
python train.py --data data/custom.yaml --weights yolov5s.pt
8. 代码扩展与集成
在自己的项目中使用 YOLOv5
# 直接导入 YOLOv5 模型
import torch# 加载预训练模型
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')# 进行推理
results = model('path/to/image.jpg')# 显示结果
results.show()
扩展 YOLOv5
- 添加自定义模块到
models/common.py
- 修改损失函数在
utils/loss.py
- 扩展数据增强方法在
utils/datasets.py
9. 版本差异与注意事项
- YOLOv5 与 YOLOv8:
YOLOv8 是 YOLOv5 的升级版,架构更简洁,性能更强,但 API 有较大变化。 - 不同版本的模型:
YOLOv5s/m/l/x 分别代表小/中/大/超大模型,参数量和性能逐步提升。 - 环境依赖:
需安装 PyTorch、OpenCV、NumPy 等依赖,建议使用 CUDA 加速。
总结
YOLOv5 的代码结构设计非常模块化,各文件夹职责清晰:
models/
:定义模型架构utils/
:提供工具函数和辅助模块data/
:管理数据集配置weights/
:存放预训练模型- 核心脚本:实现训练、推理、验证和导出功能
实战流程
以Linux下python,pytorch,CUDA(gpu)的环境为例
1. 数据准备与标注
1.1 数据集结构
YOLOv5要求数据集按以下结构组织:
datasets/
└── your_dataset/├── images/│ ├── train/│ ├── val/│ └── test/└── labels/├── train/├── val/└── test/
1.2 标签格式
每个图像对应一个.txt
标签文件,每行格式为:
class_id x_center y_center width height
- 坐标需归一化:
x_center = x / image_width
,其他同理 - 示例:
0 0.5 0.5 0.2 0.3
表示类别0(如人)的边界框
1.3 数据标注工具
- LabelImg(矩形框)
- CVAT(支持多边形、关键点)
1.4 创建数据配置文件
在data/
目录下创建.yaml
文件,例如your_dataset.yaml
:
train: ../datasets/your_dataset/images/train/
val: ../datasets/your_dataset/images/val/
test: ../datasets/your_dataset/images/test/nc: 3 # 类别数量
names: ['person', 'car', 'bike'] # 类别名称
2. 模型选择与配置
2.1 选择预训练模型
YOLOv5提供不同大小的预训练模型,平衡速度与精度:
模型 | 参数量 | 计算量(GFLOPs) | 精度(mAP@0.5) | FPS(RTX 3080) |
---|---|---|---|---|
YOLOv5n | 1.9M | 4.5 | 28.0 | 117 |
YOLOv5s | 7.2M | 16.5 | 37.4 | 91 |
YOLOv5m | 21.2M | 49.0 | 45.4 | 47 |
YOLOv5l | 46.5M | 109.1 | 49.0 | 30 |
YOLOv5x | 86.7M | 225.8 | 50.7 | 22 |
2.2 修改模型配置(可选)
如需自定义模型结构,修改models/
目录下的.yaml
文件,例如:
- 调整
nc
为类别数 - 修改
depth_multiple
和width_multiple
调整模型大小 - 增加/减少检测头层数
3. 模型训练
3.1 基础训练命令
python3 train.py --img 640 --batch 16 --epochs 100 \--data data/your_dataset.yaml \--cfg models/yolov5s.yaml \--weights yolov5s.pt \--name your_experiment
3.2 关键参数说明
参数 | 作用 |
---|---|
--img | 输入图像尺寸(如640 ),影响精度和速度 |
--batch | 批次大小,受GPU内存限制(如内存不足可设为8 或4 ) |
--epochs | 训练轮数,小数据集设为100-300 ,大数据集设为50-100 |
--data | 数据集配置文件路径(.yaml ) |
--weights | 预训练权重路径(从头训练用--weights '' ) |
--cache | 缓存图像以加速训练(--cache disk 或--cache ram ) |
--device | 指定GPU(如0 或0,1 )或CPU(cpu ) |
--hyp | 超参数配置文件(如data/hyps/hyp.scratch-low.yaml ) |
4. 调参策略
4.1 任务类型调参
4.1.1 小目标检测
- 输入尺寸:增大至
--img 1280
- 模型:使用更深的模型(如yolov5l/x)
- 数据增强:启用Mosaic(默认开启)和多尺度训练(
--multi-scale
) - 检测头:修改模型配置,增加小目标检测层
4.1.2 实时检测
- 输入尺寸:减小至
--img 320/416
- 模型:使用轻量级模型(如yolov5n/s)
- 优化:使用TensorRT导出模型(见后续部署部分)
4.1.3 高精度场景
- 模型:使用yolov5l/x
- 训练:增加轮数(
--epochs 300
) - 数据增强:启用所有增强(默认配置)
- 优化器:尝试Adam(
--optimizer Adam
)
4.2 超参数优化
使用内置的超参数优化工具:
python3 hypopt.py --img 640 --batch 16 --epochs 50 \--data data/your_dataset.yaml \--weights yolov5s.pt
4.3 数据增强参数调整
修改data/hyps/hyp.scratch-low.yaml
等配置文件:
# 常用数据增强参数
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增强概率
4.4 优化器选择
- SGD(默认):适用于大多数场景,泛化能力强
- Adam:收敛快,适合小数据集或精细调优(
--optimizer Adam
)
5. 模型评估与分析
5.1 验证模型性能
python3 val.py --weights runs/train/your_experiment/weights/best.pt \--data data/your_dataset.yaml \--img 640
5.2 关键评估指标
- mAP@0.5:IoU阈值为0.5时的平均精度,衡量定位准确性
- mAP@0.5:0.95:IoU阈值从0.5到0.95的平均mAP,衡量整体性能
- Precision:精确率(预测为正例中实际为正例的比例)
- Recall:召回率(实际正例中被正确预测的比例)
5.3 分析训练结果
- 查看
runs/train/your_experiment/results.png
:损失曲线、指标变化 - 查看混淆矩阵(
confusion_matrix.png
):分析类别混淆情况 - 查看PR曲线(
PR_curve.png
):精确率-召回率曲线
6. 模型推理与部署
6.1 推理命令
python3 detect.py --weights runs/train/your_experiment/weights/best.pt \--source path/to/image.jpg # 或视频、摄像头(0)、文件夹
6.2 导出模型
# 导出为ONNX(用于TensorRT、OpenCV等)
python3 export.py --weights best.pt --include onnx --imgsz 640 640# 导出为TensorRT(高性能推理)
python3 export.py --weights best.pt --include tensorrt --half
6.3 部署示例(Python+OpenCV)
import cv2
import numpy as np# 加载模型
net = cv2.dnn.readNetFromONNX('best.onnx')
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)# 预处理图像
img = cv2.imread('image.jpg')
blob = cv2.dnn.blobFromImage(img, 1/255.0, (640, 640), swapRB=True)
net.setInput(blob)# 推理
outputs = net.forward()# 后处理(解析预测结果)
# ...(此处省略后处理代码,需根据模型输出格式编写)
7. 高级技巧
7.1 迁移学习
冻结部分层以加速训练:
python3 train.py ... --freeze 10 # 冻结前10层(骨干网络)
7.2 多GPU训练
python3 -m torch.distributed.run --nproc_per_node 2 train.py ...
7.3 自定义损失函数
修改utils/loss.py
中的ComputeLoss
类,例如调整分类和定位损失的权重。
7.4 模型融合(Ensemble)
合并多个模型的预测结果以提高精度:
python3 val.py --weights model1.pt model2.pt model3.pt --ensemble
8. 常见问题与解决方案
-
CUDA内存不足:
- 减小
--batch-size
- 使用更小的模型(如yolov5s→yolov5n)
- 启用半精度训练(
--half
)
- 减小
-
训练不收敛:
- 检查标签格式是否正确
- 降低学习率(修改
hyp.yaml
中的lr0
) - 增加训练轮数
-
小目标检测效果差:
- 增大输入尺寸(如
--img 1280
) - 增加小目标训练样本
- 使用专用小目标检测模型(如YOLOv5-Ultralytics的v6.2版本及以后)
- 增大输入尺寸(如
我也想要成为那种可以给别人带去幸福的人。 —朝仓美羽