YOLOv5 (2) 训练模型指导

部署运行你感兴趣的模型镜像

上一篇文章我们已经部署了环境,接下来我们就要开始进行模型训练了

自定义训练

需要准备:训练集图片、验证集图片以及图片中所有目标的标注

一、训练集准备

1.原始图片

在本地PC端创建一个文件夹存放原始图片

我这里截图了一些打算测试的座舱域车机页面图

2.图片标注以及生成训练集

【如何通过原始图片生成训练集图片以及训练集标签呢?】

使用 roboflow 标注工具

https://app.roboflow.com/ces-vtecm/my-first-project-j7iyp/4

Roboflow是一款自动化训练数据工具,它提供了一种独特的标记方式,让开发者更轻松地为图像中的物体设定标签,以便YOLOv5能够更有效地识别。

图片标注步骤

①使用邮箱登陆

②创建项目

③上传原始图片

直接上传整个文件夹

④选择图片添加标签

⑤添加标签

⑥添加数据集

添加完全部图片的标签后将图像添加到数据集

⑦新建数据集版本

所有图片都添加后,新建数据集版本

⑧调整图片参数

⑨下载数据

下载到本地为zip包,解压后得到以下文件:

train文件夹中为训练集图片和训练集标签:

data.yaml为:(后续使用可能会修改内容)

3.导入训练集和验证集

①进入虚拟环境

再次进入ubuntu系统需要重新进入虚拟环境

source $HOME/miniconda/bin/activate

conda activate yolov5_rknn

②创建文件夹子文件夹

cd home/yolov5/

mkdir -p datasets/images/{train,val} datasets/labels/{train,val}

【参数说明】

-p  自动创建父目录(如果不存在)

{train,val}  批量创建多个子目录

结构如下:

datasets/
├── images
│   ├── train(存放训练集图片)
│   └── val  (存放验证集图片)
└── labels
    ├── train(存放对应训练集图片的标注文件)
    └── val  (存放对应验证集图片的标注文件)

③导入图片以及标签

训练集图片:

docker cp D:\test1.v1i.yolov5pytorch\train\images. 容器唯一标识符:/home/yolov5/datasets/images/train

验证集图片:

  • 验证集图片需要和训练集内图片不同,如果验证集包含训练集图片,模型会记住这些图片(过拟合),导致验证指标虚高,无法反映真实性能;
  • 验证集的目的是为了验证模型在从未见到的数据上面的表现,因此需使用全新图片,但是要保证验证集和训练集的图片,类别、场景分布类似,才具有验证价值;
  • 通常训练集图片数量和验证集图片数量的划分为7:3;

docker cp D:\验证集图片文件夹. 容器唯一标识符:/home/yolov5/datasets/images/val

训练集标签:

docker cp D:\test1.v1i.yolov5pytorch\train\labels. 容器唯一标识符:/home/yolov5/datasets/labels/train

验证集标签:

docker cp D:\验证集标签文件夹. 容器唯一标识符:/home/yolov5/datasets/labels/val

④导入data.yaml配置文件

在 YOLOv5 项目中,data.yaml 是一个配置文件,用于定义数据集的路径、类别信息以及训练/验证集的划分规则。

它是模型训练和验证的“数据指南”,告诉 YOLOv5 去哪里找数据、如何解析数据。

YOLOv5 的训练脚本(train.py)和验证脚本(val.py)依赖此文件定位数据。

这里将 data.yaml 配置文件存放到 datasets 路径下

修改数据集和验证集的路径信息

二、训练模型

1.开始训练

python train.py --img 640 --batch 16 --epochs 50 --data datasets/data.yaml --weights yolov5s.pt --workers 0

【参数说明】

train.py  训练脚本

--img 640  图片尺寸

--batch 16  批次大小,根据GPU内存调整

--epochs 50  训练轮次

--data datasets/data.yaml  数据集配置文件路径

--weights yolov5s.pt  预训练权重文件

--workers 0  数据加载的线程数(0表示仅主线程,避免多线程问题)

【BUG1】NumPy版本兼容性问题

【解决办法1】---采用√ 成功

查看到以下文件中存在np.int:

grep "astype(np.int" /home/yolov5/utils/datasets.py

grep "astype(np.int" /home/yolov5/utils/general.py

grep "astype(np.int" /home/yolov5/utils/metrics.py

替换文件中所有 np.int 为 int:

sed -i 's/\.astype(np\.int)/.astype(int)/g' /home/yolov5/utils/general.py
sed -i 's/\.astype(np\.int)/.astype(int)/g' /home/yolov5/utils/datasets.py

// metrics.py 应该不是直接改为int16,需要改为'int16' ---见BUG4

sed -i 's/\.astype(np\.int16)/.astype(int16)/g' /home/yolov5/utils/metrics.py

或者一个个修改(示例 datasets.py 文件的473行)

vim /home/yolov5/utils/datasets.py +473  // 代表修改文件的第473行

【解决办法2】---没尝试,怕修改版本会引发新的不兼容问题

查看NumPy版本号:

python -c "import numpy as np; print(np.__version__)"

发现版本号大于1.24版本,需要降级到1.23.5:

pip install numpy==1.23.5

【BUG2】类型转换问题

问题现象:Float类型无法转换为long int类型

分析:在 loss.py 文件中,gj.clamp_() 和 gi.clamp_() 操作需要返回整数类型(long int),但输入可能是浮点类型(Float),类型不匹配

原因:使用的PyTorch 2.4.0可能与YOLOv5 v6.0存在一些兼容性问题

查看gi.clamp_():
grep "clamp_(" /home/yolov5/utils/loss.py

修改文件第217行:vim /home/yolov5/utils/loss.py +217

修改:红色为修改后代码

# Define
b, c = t[:, :2].long().T  # image, class
gxy = t[:, 2:4]  # grid xy
gwh = t[:, 4:6]  # grid wh
gij = (gxy - offsets).long()
gi, gj = gij.T  # grid xy indices

# Append
a = t[:, 6].long()  # anchor indices
# indices.append((b, a, gj.clamp_(0, gain[3] - 1).round().to(torch.long), gi.clamp_(0, gain[2] - 1).round().to(torch.long)))  # image, anchor, grid indices  // 原代码

gi = gi.clamp(0, gain[2] - 1).long()
gj = gj.clamp(0, gain[3] - 1).long()
indices.append((b, a, gj, gi))

【BUG3】Pillow库版本兼容性问题

原因:Pillow 10.0.0之后的版本中移除了getsize()方法导致的兼容性问题

  • YOLOv5的绘图功能使用了Pillow库

  • 新版本Pillow改变了字体尺寸获取的API

查看 Pillow 版本:pip show Pillow

【解决办法1】---采用√ 成功

修改文件第86行:vim /home/yolov5/utils/plots.py +86

修改文件第112行:vim /home/yolov5/utils/plots.py +112

修改:红色为修改后代码

# 86行修改

if label:
        # w, h = self.font.getsize(label)  # text width, height  // 原代码
       bbox = self.font.getbbox(label)
       w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]

# 112行修改

def text(self, xy, text, txt_color=(255, 255, 255)):
        # Add text to image (PIL-only)
        # w, h = self.font.getsize(text)  # text width, height  // 原代码
        w, h = self.font.getbbox(text)[2:]

【解决办法2】---没尝试,怕修改版本会引发新的不兼容问题

降级Pillow版本

pip install pillow==9.5.0

【BUG4】未正确导入 numpy 的数据类型

分析:在 utils/metrics.py 中使用了 int16,但未正确导入 numpy 的数据类型

原因:YOLOv5 的某些版本在 metrics.py 中直接使用了 int16,但未添加 from numpy import int16 或 import numpy as np 并使用 np.int16(根据BUG1,我们不能使用np.int16)

(这个是BUG1修改后出现的新问题)

修改:m0, m1, _ = matches.transpose().astype('int16')  # 使用字符串 'int16' 而非变量

2.结束训练

正常等待结束:达到设定的 epochs=50 轮次,训练完成后自然退出;

3.训练结果

训练进度:

  • 33/49:当前 epoch(轮次)和总 epochs

  • 0G:GPU 内存占用(0 表示未使用 GPU,可能是 CPU 训练)

  • 0.08837:边界框损失(box loss),越小越好

  • 0.05251:目标检测损失(obj loss),越小越好

  • 0.07966:分类损失(cls loss),越小越好

  • 145:当前 batch 的标签数量。

  • 640:输入图像尺寸。

  • 67%:当前 epoch 的进度。

验证集指标:

  • Images:验证集图片数(36 张)

  • Labels:验证集标注框数(156 个)

  • P (Precision):精确率(预测为正样本中真实正样本的比例),当前 0.851(较低)

  • R (Recall):召回率(真实正样本中被正确预测的比例),当前 0.0109(很低)

  • mAP@.5:IoU 阈值为 0.5 时的平均精度(0.00845,性能较差)

  • mAP@.5:.95:IoU 阈值从 0.5 到 0.95 的平均精度(0.00169,性能较差)

4.持续训练

在开始训练时我们设置了轮次50次,使用官方预处理权重pt文件:

python train.py --img 640 --batch 16 --epochs 50 --data datasets/data.yaml --weights yolov5s.pt --workers 0
这个训练指令,每次执行都是独立训练,效果不会叠加

那么想要长期持续训练,应该怎么办呢?

首先,我们首次完成训练的轮次后,会生成一个runs文件夹保存我们的训练结果,在 /home/yolov5/runs/train/exp/weights 路径下有两个pt文件,best.pt 和 last.pt 是两个关键的模型权重文件,我们想要恢复训练需要使用到这两个权重文件;

best.pt 含义:是训练过程中在验证集上表现最优的模型权重

best.pt 特点:

1.保存的是验证集精度最高的版本,通常用于实际部署;

2.文件大小较小;

last.pt 含义:训练最后一个轮次的模型权重(无论性能如何)

last.pt 特点:

1.包含完整的模型状态(可继续训练);

2.文件较大(默认保留优化器状态,便于 --resume 训练);

指令对比

# 开始首次训练

python train.py --img 640 --batch 16 --epochs 50 --data datasets/data.yaml --weights yolov5s.pt --workers 0

# 恢复训练(从上次断点继续)

python train.py --resume /home/yolov5/runs/train/exp/weights/last.pt --epochs 50

【恢复训练 - 参数说明】

--epochs  总epoch数  这个应该和首次训练的轮次参数保持一致

--project runs/train --name exp1 训练结果保存

这个指令我理解是,我本来想要执行50轮次的训练,但是训练到轮次20时异常中断了,然后通过这个指令可以让剩下的轮次继续执行结束从21到50;

# 持续优化训练

原数据集:

python train.py --img 640 --batch 16 --epochs 50 --data datasets/data.yaml --weights /home/yolov5/runs/train/exp/weights/last.pt --epochs 50 --workers 0

有新增数据:

python train.py --img 640 --batch 16 --epochs 50 --data datasets/data.yaml --weights /home/yolov5/runs/train/exp/weights/best.pt --epochs 50 --workers 0

但是我现在不管有没有新增数据,都使用best.pt文件

您可能感兴趣的与本文相关的镜像

Yolo-v5

Yolo-v5

Yolo

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的Joseph Redmon 和Ali Farhadi 开发。 YOLO 于2015 年推出,因其高速和高精度而广受欢迎

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值