零基础入门AI: YOLOv5 详解与项目实战
一、YOLOv5 概述
1.1 基本介绍
YOLOv5(You Only Look Once version 5)是一个开源的目标检测框架,由 Glenn Jocher 及其团队开发,属于 Ultralytics 公司,在 GitHub 上发布。它是 YOLO 系列算法的第五代版本,旨在提供高效、灵活且易于使用的物体检测解决方案。相比于之前的版本,YOLOv5 引入了许多改进,使其成为工业界和学术界广泛采用的选择。
1.2 版本规格
YOLOv5 有 YOLOv5n、YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x 五个版本。这几个模型的结构基本一样,不同的是depth_multiple 模型深度和 width_multiple 模型宽度这两个参数。就和我们买衣服的尺码大小排序一样,YOLOv5n 网络是 YOLOv5系列中深度最小、特征图的宽度最小的网络。其他三种都是在此基础上不断加深,不断加宽其参数量依次上升,当然了其效果也是越来越好。
性能对比表:
模型 | 尺寸(像素) | mAPval 50-95 | mAPval 50 | 参数量(M) | FLOPs@640(B) | 适用场景 |
---|---|---|---|---|---|---|
YOLOv5n | 640 | 28.0 | 45.7 | 1.9 | 4.5 | 移动设备/嵌入式系统 |
YOLOv5s | 640 | 37.4 | 56.8 | 7.2 | 16.5 | 边缘设备 |
YOLOv5m | 640 | 45.4 | 64.1 | 21.2 | 49.0 | 常规硬件 |
YOLOv5l | 640 | 49.0 | 67.3 | 46.5 | 109.1 | 高端硬件 |
YOLOv5x | 640 | 50.7 | 68.9 | 86.7 | 205.7 | 高性能硬件 |
1.3 主要特点
-
高性能:
- YOLOv5 在多种硬件平台上表现出色,特别适合实时目标检测任务
- 通过优化网络结构和训练流程,YOLOv5 在多种数据集上达到了较高的精度和较快的推理速度
-
易于使用:
- YOLOv5 提供了简洁的 API 和详细的文档,使得用户可以轻松地进行模型训练、评估和部署
- 支持多种框架和语言,包括 PyTorch、ONNX、TensorRT 等
-
模块化设计:
- YOLOv5 采用了模块化的设计理念,使得用户可以方便地进行模型定制和扩展
- 支持多种预训练模型和配置文件,用户可以根据自己的需求选择合适的模型
二、技术架构与核心改进
2.1 主要改进点
- 主干网络是修改后的 CSPDarknet53,后面跟了 SPPF 模块
- 网络最开始增加 Focus 结构
- 颈部网络采用 PANet、FPN
- 激活函数换成了 SiLU、Swish
- 采用 CloU 损失
2.2 Focus 模块(早期版本)
YOLOv5 刚推出时,为了提升模型效率,采用了 Focus 模块 作为网络的初始特征提取层,传统卷积下采样会丢失部分空间信息,Focus 模块旨在在不丢失信息的前提下进行高效下采样。
核心目标: 将高分辨率图像的空间信息通过切片操作转换为通道信息,从而实现高效、无信息损失的下采样。
Focus 模块是一种用于特征提取的卷积神经网络层,用于将输入特征图中的信息进行压缩和组合,从而提取出更高层次的特征表示,它被用作网络中的第一个卷积层,用于对输入特征图进行下采样,以减少计算量和参数量。
Focus 层在 YOLOv5 中是图片进入主干网络前,对图片进行切片操作,原理与 Yolov2 的 passthrough 层类似,采用切片操作把高分辨率的图片(特征图)拆分成多个低分辨率的图片(特征图),即隔列采样+拼接。
具体操作流程:
- 输入阶段:假设输入一张图像大小为 640x640x3
- 切片操作:640 x 640 x 3的图像输入 Focus 结构,采用切片操作,每隔一个像素拿到一个值
- 拼接转换:然后进行一个连接(concat),变成 320 x 320 x 12 的特征图
- 卷积处理:经过一次 32 个卷积核的卷积操作,最终输出 320 x 320 x 32 的特征图
注意: 在 YOLOv5 刚提出来的时候,有 Focus 结构,从 YOLOv5 第六版开始,就舍弃了这个结构,改用 k=6×6,stride=2 的常规卷积。
2.3 网络结构
YOLOv5 的整体网络结构基于 CSPDarknet53 主干网络和 PANet 颈部网络,包含以下几个核心组件:
2.3.1 CSP1_X 与 CSP2_X
-
CSP1_X:
- 定义:带 shortcut(残差连接)的 CSP 模块
- 结构特点:内部包含带有 shortcut 的 Bottleneck 结构
- 应用场景:主要用于 backbone 部分,如 CSPDarknet53,增强特征提取能力
- X 的含义:表示 bottleneck 的数量
-
CSP2_X:
- 定义:不带 shortcut 的 CSP 模块
- 结构特点:内部没有 shortcut 连接,仅通过卷积操作进行特征提取
- 应用场景:主要用于 neck 部分,如 PANet(Path Aggregation Network),进行特征聚合
- X 的含义:表示 bottleneck 或其他卷积模块的数量
2.3.2 自适应Anchor的计算
在 YOLOv3、YOLOv4 中,训练不同的数据集时,计算初始 Anchor 的值是通过单独的程序运行的。但 YOLOv5 中将此功能嵌入到代码中,每次训练时会自适应的计算不同训练集中的最佳 Anchor 值。
实现方式:
- 在训练开始前,YOLOv5 会自动加载训练集中的标注框
- 使用 K-Means 聚类算法计算 Anchor
- 将结果作为初始 Anchor 值用于模型初始化
源码位置: utils/autoanchor.py/check_anchors()
2.3.3 激活函数
YOLOv5 使用了 SiLU 激活函数、Swish 激活函数两种激活函数。
SiLU 激活函数:
- YOLOv5 的 Backbone 和 Neck 模块和 YOLOv4 中大致一样,都采用 CSPDarkNet 和 FPN+PAN 的结构,但是网络中其他部分进行了调整,其中 YOLOv5 使用的激活函数是 SiLU
- 数学表达式:SiLU(x)=x⋅σ(x)SiLU(x) = x·\sigma(x)SiLU(x)=x⋅σ(x)
- 特性:具备无上界有下届、平滑、非单调的特性
Swish 激活函数:
- Swish 激活函数是一个近似于 SiLU 函数的非线性激活函数
- 数学表达式:Swish(x)=x⋅σ(βx)Swish(x) = x·\sigma(\beta x)Swish(x)=x⋅σ(βx)
- β\betaβ是一个可调节的参数,通常设定为 1
2.3.4 Bottleneck 结构
Bottleneck 是用于减少参数和计算量的结构,其设计灵感来自于ResNet。
结构组成:
- 1x1卷积:用于减少特征图的通道数
- 3x3卷积:用于提取特征,后接一个 Batch Normalization 层和 ReLU 激活函数
- 1x1卷积:用于恢复特征图的通道数,后接一个BN层
- 跳跃连接(Shortcut):将输入直接加到输出上,以形成残差连接
2.3.5 C3 模块
YOLOv5 中的 C3 模块在 CSP上进行了优化,非常相似但略有不同。YOLOv5 一共使用过两种 CSP 模块:
BottleneckCSP(v4.0版本之前):
- 结构特点: 包含多个带 shortcut 的 Bottleneck
- 激活函数:LeakyReLU
- 用途:主要用于早期 YOLOv5 的 backbone
C3(v4.0版本之后):
- 结构特点: 不再使用 shortcut(即 Bottleneck 不带残差连接)
- 激活函数:SiLU
- 用途:广泛用于 backbone 和 neck(如 PANet)
2.3.6 SPPF 模块
SPPF(Spatial Pyramid Pooling Fast)模块是对SPP模块的优化改进。
创新点:
- 将卷积核大小变成相同,然后将并行变成了串行+并行
- 2个K5池化=1个K9池化,3个K5池化=1个K13池化
- 在结果相同的基础上,速度更快,计算量更小
等效感受野计算公式:
对于连续堆叠 n 层,每层使用大小为 k 的核的操作(例如卷积或池化),其等效感受野大小可以通过以下公式计算:
K等效=1+n(k−1)K_{等效}=1+n(k−1)K等效=1+n(k−1)
层数 n | 卷积核大小 k | 等效感受野 |
---|---|---|
1 | 5 | 1+1×(5−1)=5 |
2 | 5 | 1+2×(5−1)=9 |
3 | 5 | 1+3×(5−1)=13 |
SPP 和 SPPF 区别:
SPPF通过串行连接多个池化层来实现与SPP相同的多尺度特征提取效果,但计算效率更高。
2.4 输出头设计
YOLOv5 的输出头设计灵活度较高,支持多种尺寸:
- 输入图像尺寸:通常为 640x640(或者其它尺寸,如 416x416 等)
- 输出特征图:YOLOv5 使用大、中、小三个尺寸
- 输出尺寸:
- 大目标: 通常是输入图像尺寸的 1/32
- 中目标: 通常是输入图像尺寸的 1/16
- 小目标: 通常是输入图像尺寸的 1/8
计算公式:
假设输入图像尺寸为640x640,具体的特征图尺寸如下:
大目标:64032×64032=20×20中目标:64016×64016=40×40小目标:6408×6408=80×80
\text{大目标:}\frac{640}{32}\times\frac{640}{32}=20\times20\\
\text{中目标:}\frac{640}{16}\times\frac{640}{16}=40\times40\\
\text{小目标:}\frac{640}8\times\frac{640}8=80\times80
大目标:32640×32640=20×20中目标:16640×16640=40×40小目标:8640×8640=80×80
三、实战应用
3.1 开源项目介绍
YOLOV5并没有学术论文,是一个开源项目,是 Ultralytics 公司于 2020 年6月9 日发布的。项目可以在 GitHub 上获取:【https://github.com/ultralytics/yolov5】
预训练模型说明:
这些模型的结构是一样的,区别在于网络的深度和宽度,网络的深度指的就是 C3 模块中 Bottleneck 的数量,网络的宽度是指网络每层输出的通道数。
3.2 项目构建与配置
3.2.1 项目获取
- 通过 GitHub 获取官方源码:【https://github.com/ultralytics/yolov5】
- 国内用户可以使用 Gitee 镜像:【https://gitee.com/monkeycc/yolov5】
- 将源码复制到项目开发文件夹中
3.2.2 环境配置
- 配置 Python 解释器(建议使用 Anaconda 创建的虚拟环境)
- 安装 requirements.txt 中的依赖(已安装PyTorch的情况下注释掉相关行)
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
3.2.3 模型下载
从官方提供的模型库中下载合适的预训练模型,复制到项目中。
3.3 快速入门
3.3.1 推理测试
使用以下命令进行推理测试:
python detect.py --weights yolov5s.pt --source data/images/bus.jpg
参数说明:
--weights
: 指定模型权重文件路径--source
: 指定输入源,可以是图像、视频、摄像头、目录等- 推理结果默认保存到
runs/detect
目录
3.3.2 数据集获取与标注
数据集来源:
- 安全帽数据集:【https://www.kaggle.com/datasets/snehilsanyal/construction-site-safety-image-dataset-roboflow】
标注工具:
- 使用 labelImg 工具进行标注
- 安装:
pip install labelimg
- 启动:在激活环境下执行
labelimg
命令
标注流程:
- 选择 YOLO 模式创建标签
- 使用快捷键进行标注:
- w: 绘制矩形框
- d: 下一张图片
- a: 上一张图片
- Del: 删除标注框
- Ctrl+s: 保存
标注结果:
- 生成
.txt
文件:存储每一张图片的标注信息(标签序号、标注框的中心坐标、标注框的相对宽和高) - 生成
classes.txt
:类别信息文件
3.3.3 数据集配置
- 在项目中创建
datasets
文件夹 - 在
datasets
中创建子文件夹(如helmet
)存放数据集 - 复制并修改配置文件:
- 复制
data/coco128.yaml
为helmet.yaml
- 修改路径和类别信息
- 复制
配置文件示例:
path: ./datasets/helmet
train: train/images
val: val/images
test: names:0: head1: helmet2: person
- 修改模型配置文件
models/yolov5s.yaml
中的类别数
3.4 模型训练
3.4.1 训练命令
python train.py \--data data/helmet.yaml \--img 640 \--epochs 25 \--weights yolov5s.pt \--cfg models/yolov5s.yaml \--batch-size 2 \--device 0
参数说明:
--data
: 数据集配置文件路径--img
: 输入图像尺寸--epochs
: 训练周期数--weights
: 初始权重文件路径--cfg
: 模型配置文件路径--batch-size
: 批量大小--device
: 训练设备(0表示GPU 0,cpu表示CPU)
3.4.2 训练过程监控
训练过程中显示的关键指标:
- Epoch: 训练进度
- Gpu_mem: GPU内存使用情况
- box_loss: 边界框回归损失
- obj_loss: 对象存在性损失
- cls_loss: 分类损失
- Instances: 检测到的目标实例数量
- Size: 输入图像大小
3.4.3 恢复训练
如果训练过程中意外停止,可以使用以下命令恢复训练:
python train.py --weights runs/train/exp/weights/last.pt --resume
3.5 模型导出与推理
3.5.1 导出ONNX格式
python export.py --weights yolov5s.pt --img 640 --batch 1 --device 0 --include onnx
3.5.2 YOLO格式推理
from yolov5 import detect
detect.run(weights='yolov5s.onnx', # 权重文件路径source='data/images', # 输入源路径img_size=640, # 输入图像尺寸conf_thres=0.25, # 置信度阈值iou_thres=0.45, # IoU阈值max_det=1000, # 最大检测数量device='0', # 设备view_img=False, # 显示检测结果save_txt=False, # 保存检测结果为txt文件save_conf=False, # 保存置信度到txt文件save_crop=False, # 裁剪并保存检测到的对象nosave=False, # 保存图像/视频classes=None, # 检测所有类agnostic_nms=False, # 类无关的非极大值抑制augment=False, # 推理增强visualize=False, # 可视化特征图update=False, # 更新所有模型project='runs/detect', # 结果保存目录name='exp', # 结果保存子目录exist_ok=False, # 允许现有目录line_thickness=3, # 画框线条粗细hide_labels=False, # 隐藏标签hide_conf=False, # 隐藏置信度half=False, # 半精度推理dnn=False # 使用OpenCV DNN模块
)
3.5.3 ONNX格式推理
import onnxruntime as ort
import numpy as np
import cv2# 创建ONNX Runtime推理会话
providers = ['CUDAExecutionProvider'] # 或 ['CPUExecutionProvider']
session = ort.InferenceSession('yolov5s.onnx', providers=providers)# 预处理图像
img = cv2.imread('data/images/bus.jpg')
img = cv2.resize(img, (640, 640))
img = img.transpose((2, 0, 1)) # HWC to CHW
img = np.expand_dims(img, axis=0).astype(np.float32) / 255.0# 推理
outputs = session.run(None, {'images': img})
print(outputs[0].shape)
四、项目结构与配置详解
4.1 源码目录结构
yolov5/
├── data/ # 数据集配置和超参数
│ ├── hyps/ # 超参数配置
│ ├── images/ # 测试图像
│ ├── scripts/ # 数据集下载脚本
│ └── *.yaml # 数据集配置文件
├── models/ # 模型定义
│ ├── common.py # 通用模块
│ ├── experimental.py # 实验性代码
│ ├── tf.py # TensorFlow版本
│ ├── yolo.py # YOLO特定模块
│ └── *.yaml # 模型配置文件
├── utils/ # 工具函数
│ ├── activations.py # 激活函数
│ ├── augmentations.py # 数据增强
│ ├── autoanchor.py # 自动Anchor计算
│ ├── dataloader.py # 数据加载
│ ├── loss.py # 损失函数
│ └── metrics.py # 评估指标
├── datasets/ # 自定义数据集
├── runs/ # 训练和推理结果
├── detect.py # 目标检测脚本
├── train.py # 训练脚本
├── val.py # 验证脚本
└── requirements.txt # 依赖环境
4.2 数据集目录结构
datasets/
└── helmet/ # 数据集名称├── test/ # 测试集(可选)│ └── images/ # 测试图像├── train/ # 训练集│ ├── images/ # 训练图像│ └── labels/ # 标注文件└── valid/ # 验证集├── images/ # 验证图像└── labels/ # 标注文件
4.3 训练结果目录
runs/
├── detect/ # 推理结果
│ └── exp/ # 实验1,依次递增
└── train/ # 训练结果└── exp/ # 实验1,依次递增└── weights/ # 模型权重├── best.pt # 最佳权重└── last.pt # 最后权重
4.4 训练参数配置详解
超参数文件: data/hyps/
目录下的yaml文件
主要参数说明:
lr0
: 初始学习率 (SGD=1E-2, Adam=1E-3)lrf
: 最终学习率 (lr0 * lrf)momentum
: SGD动量/Adam beta1weight_decay
: 优化器权重衰减warmup_epochs
: 热身周期数box
: 边界框损失增益cls
: 分类损失增益obj
: 目标检测损失增益hsv_h
: 图像HSV-Hue增强hsv_s
: 图像HSV-Saturation增强hsv_v
: 图像HSV-Value增强flipud
: 图像上下翻转概率fliplr
: 图像左右翻转概率mosaic
: 图像马赛克增强概率
4.5 模型结构参数详解
模型配置文件: models/
目录下的yaml文件
主要参数:
nc
: 类别数量depth_multiple
: 模型深度系数width_multiple
: 层通道数系数anchors
: 锚框配置backbone
: 主干网络结构head
: 检测头结构
模块定义格式: [from, number, module, args]
from
: 输入来源(-1表示上一层)number
: 模块重复次数module
: 模块名称(定义在common.py中)args
: 初始化参数
五、扩展功能应用
5.1 实例分割
下载yolov5s-seg.pt
文件、自己训练,可以看开发手册:【https://docs.ultralytics.com/tasks/classify/】
python segment/predict.py --weights yolov5s-seg.pt --source data/images/bus.jpg
5.2 图像分类
下载yolov5s-cls.pt
文件、自己训练,可以看开发手册:【https://docs.ultralytics.com/tasks/classify/】
python classify/predict.py --weights yolov5s-cls.pt --source data/images/bus.jpg
六、项目实战:车牌检测与识别
6.1 项目介绍
使用 YOLOv5 框架完成目标检测任务,实现车牌检测和号码识别。
技术流程:
- 目标检测阶段:找到车牌位置并裁剪保存
- 文字识别阶段:使用 PaddleOCR 识别车牌号码
6.2 数据集处理
6.2.1 数据集获取
- 使用 CCPD(中国城市车牌数据集)
- 开源地址:【https://gitcode.com/Resource-Bundle-Collection/f81da/】
6.2.2 标注数据处理
- 从文件名解析标注信息(包含坐标信息)
- 坐标转换:左上/右下坐标 → 中心点+宽高(归一化)
- 单类别标注:车牌(类别0)
- 按标准格式组织训练集和验证集
6.3 模型训练
- 使用
yolov5s.pt
作为预训练权重 - 初始训练200个epochs,根据效果调整
- 监控训练指标,适时调整超参数
6.4 推理与集成
import torch
from PIL import Image# 加载自定义模型
model = torch.hub.load('ultralytics/yolov5', 'custom', path='license_plate.pt')# 推理
results = model('input_image.jpg')# 裁剪检测区域
crops = results.crop()
for crop in crops:plate_image = crop['im'] # 提取车牌图像# 接入PaddleOCR进行文字识别
七、实践与优化
7.1 性能优化
- 数据增强策略:根据模型尺寸选择合适的增强强度
- 超参数调优:参考官方提供的超参数配置文件
- 模型量化:导出ONNX/TensorRT格式提升推理速度
- 硬件加速:合理配置batch size以避免内存溢出
7.2 训练技巧
- 学习率调度:使用cosine annealing或one-cycle策略
- 早停机制:监控验证集性能,防止过拟合
- 模型集成:融合多个模型的预测结果提升精度
- 数据平衡:处理类别不平衡问题,使用focal loss等
7.3 部署考虑
- 模型格式选择:根据部署环境选择pt、onnx或tensorrt格式
- 内存优化:使用半精度(float16)推理减少内存占用
- 批量处理:合理设置batch size平衡延迟和吞吐量
- 硬件适配:针对不同硬件平台进行特定优化
八、资源与支持
8.1 官方资源
- GitHub仓库:【https://github.com/ultralytics/yolov5】
- 官方文档:【https://docs.ultralytics.com/】
- 预训练模型:【https://github.com/ultralytics/yolov5/tree/master/models】
8.2 社区支持
- GitHub Issues:问题反馈和功能请求
- Discord社区:实时交流和技术讨论
- Stack Overflow:技术问题解答
8.3 学习资源
- 官方教程:包含从入门到进阶的完整指南
- 论文解读:相关技术论文和分析文章
- 实战案例:各种应用场景的实现示例
注意: 本文档基于 YOLOv5 v7.0 版本编写,不同版本可能存在差异,请以官方文档和代码为准。建议定期查看官方更新以获取最新特性和优化。