YOLOv5 自定义训练
[!TIP]
参考官方文档进行训练即可,训练其实是在YOLOv5预训练模型上再次训练权重
一、前置讲解
1.1模型(Model)是什么?
- 模型是一个结构 + 参数的组合
在深度学习里:
- 结构(Architecture):网络的层数、每层的类型、连接方式(比如 YOLOv5 的卷积层、CSP 模块、检测头等)
- 参数(Parameters):网络中每个卷积核、偏置、BN 参数等的数值
可以类比成:
模型结构 = 机器的设计图
参数 = 机器零件的具体尺寸和重量
1.2权重(Weights)是什么?
- 权重就是模型参数的数值
YOLOv5 的
.pt文件(best.pt、last.pt)就是权重文件,里面存储了:- 每一层的卷积核权重(weights)
- 偏置(bias)
- BatchNorm 的均值和方差
- 优化器状态(
last.pt里有,用于继续训练)
⚠️ 权重文件不包含完整的网络结构,只是数值。要用这些权重,你必须有对应的模型结构代码(YOLOv5 的 .yaml 或 model.py)。
1.3模型和权重的关系
可以用一个现实例子来理解:
| 类比 | 深度学习 |
|---|---|
| 机器人设计图 | 模型结构(YOLOv5s、YOLOv5m 等) |
| 机器人的零件尺寸和重量 | 权重(best.pt、last.pt) |
| 机器人整机 | 模型(结构 + 权重) |
所以:
- 模型结构 决定了网络能做什么(能力框架)
- 权重 决定了它具体的表现(训练后的知识)
- 模型文件(结构+权重) 才能直接用来推理
1.4执行检测测试时,YOLOv5 的代码会做几件事:
加载模型结构
- YOLOv5 的结构(网络层、连接方式)已经写在
models/yolov5s.yaml、models/yolov5m.yaml等文件里 - detect.py 会根据你训练时的配置,先在内存里创建一个“空的” YOLOv5 网络框架
- YOLOv5 的结构(网络层、连接方式)已经写在
加载权重
- 再把
best.pt或last.pt文件里的数值(卷积核权重、偏置等)填充到这个空网络里
- 再把
组合成完整模型
- 结构 + 权重 = 可用的模型
- 这个组合过程是在内存中完成的,所以你看不到一个新的“模型文件”生成
执行推理
- 用这个组合好的模型对输入图片进行前向计算,得到检测结果
二、环境准备
2.1数据集
2.1.1下载数据集
我这里是使用别人分享标注好的数据集,下载即可使用
行人、人类YOLO数据集(1000张已标注分类) - 幽络源免费数据集
2.1.2自定义数据集
- 标注数据集就像给小孩看图识字,你画框并写上类别名是“告诉他这个叫啥”,看多了,他就能自己认出来
- 可以看上面的文档链接,知晓标注数据集的意思,就是手动圈出大量想识别的东西,告诉模型 “这里是什么东西”,让它在训练时学会识别这些目标的特征。
生成标签文件
工具会把每张图片的标注信息保存成一个
.txt文件(YOLO 格式),内容类似:0 0.512 0.488 0.276 0.644解释:
class_id x_center y_center width heightclass_id:类别编号(从 0 开始)x_center、y_center、width、height:目标框的中心点和宽高,归一化到 0~1
- 通过不断调整网络参数,模型就能学会提取目标的共同特征(比如形状、颜色、纹理等),得到可泛化的识别能力,训练好的模型就能在新图片中自动找到并识别相同类别的目标。
(1) 数据集目录结构
YOLOv5 默认的数据集目录结构如下(以 dataset 为例):
dataset/
├── images/
│ ├── train/ # 训练集图片
│ └── val/ # 验证集图片
├── labels/
│ ├── train/ # 训练集标签(txt)
│ └── val/ # 验证集标签(txt)
└── data.yaml # 数据集配置文件注意:
images/train和labels/train的文件名必须一一对应,例如:images/train/0001.jpg labels/train/0001.txt标签文件是 YOLO 格式:
class_id x_center y_center width height坐标是
相对值
(归一化到 0~1)。
(2) 标注工具
常用的标注工具有:
LabelImg(简单易用)
Labelme(可标注分割)
Roboflow(在线标注+格式转换)
CVAT(团队协作)
标注完成后,导出为 YOLO 格式 标签。
(3) 编写 data.yaml
data.yaml 是 YOLOv5 训练时读取的数据集配置文件,示例如下:
# 数据集路径(绝对路径或相对路径)
train: E:/datasets/images/train
val: E:/datasets/images/val
# 类别数量
nc: 1
# 类别名称(建议写真实名称,方便可视化)
names: ['person']说明:
train/val:分别指向训练集和验证集图片文件夹nc:类别数量(单类别就是 1,多类别则是总数)names:类别名称列表,索引从 0 开始,必须和标注文件的class_id对应
例如:nc: 3 names: ['person', 'car', 'dog']
(4) 检查数据集是否正确
YOLOv5 提供了一个数据检查工具,你可以在终端运行:
python train.py --img 640 --batch 8 --epochs 1 --data data.yaml --weights yolov5s.pt --device cpu它会在训练前自动检查:
- 图片和标签数量是否匹配
- 标签格式是否正确
- 类别索引是否超出范围
2.2配置环境
(上面的文档链接,要求python版本要3.8及以上)
python --version
pip install torch torchvision torchaudio
(将前面下载的数据集解压到目录改名为yolo_train,也可以是其他名字)
cd E:\workSpaces\code\python\yolo_train
git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip install -r requirements.txt
三、开始训练
3.1源码目录结构
- 我们可以看一下工程结构,除了
yolov5,其他都是数据集解压的文件,我们主要看data.yaml文件的内容,可以看到数据集作者写的是相对路径上级,为了不必要的修改,所以YOLOv5的源码要和数据集同级目录

- 我们可以看下
yolo源码文件,其中bus.jpg是我找的一张带有人的图片,detect.py是训练完成后的运行检测脚本,export.py是训练完成后的模型导出其他格式的脚本,train.py是训练脚本 model是模型结构文件runs目录是运行检测和运行训练后的权重结果保存文件夹

3.2训练
- 很多嵌入式部署环境不支持
SiLU,所以需要用ReLU版本来保证算子兼容性,否则在转换 ONNX → RKNN 时会报算子不支持的错误。所以需要改变model/common.py激活函数替换

- 使用下面的命令
python train.py --img 640 --batch 8 --epochs 50 --data E:/workSpaces/code/python/yolo_train/data.yaml --weights yolov5s.pt --device cpu
--img 640 # 输入图片的宽高尺寸,通常用640
--batch 8 #批量大小,一次训练迭代中同时送入网络的图片数量,越大训练越快,但显存占用也越高
--epochs 50 #训练轮数,训练次数越多,模型越可能收敛,但也会更耗时,模型选一个数据最好的命名best
--data E:/workSpaces/code/python/yolo_train/data.yaml #数据集配置文件,前面解压的
--weights yolov5s.pt #预训练权重文件,我们是二次训练,如果要从零开始训练,可以写 --weights ''
--device cpu #指定训练用的设备,如果有GPU,可以是--device 0

- 如图,
AMD R7 8845 CPU训练时间大概2.2小时,在runs目录下生成了两个权重last.pt和best.pt,分别最后一次保存的模型权重和验证集性能最好的模型权重

四、测试自定义模型
python detect.py --weights runs/train/exp/weights/best.pt --img 640 --conf 0.25 --source bus.jpg
--conf 0.25 置信度阈值设为 0.25:只有置信度 ≥ 0.25 的预测框才会保留,其他的直接丢弃
五、转换模型
- 官方的
export.py不直接支持 RKNN,它支持的格式主要是下图

- 想转换为rknn,需要先转出onnx,然后使用RKNN-Toolkit2 来转换
python export.py --weights runs/train/exp/weights/best.pt --include onnx --img 640 --batch 1

转换RKNN,待完成
rknn-toolkit2/rknn-toolkit2/examples/onnx/yolov5


评论