目录
1.选择模型
PaddleX 提供了11个端到端的目标检测模型,具体可参考https://github.com/PaddlePaddle/PaddleX/blob/release/3.0-beta/docs/tutorials/models/support_model_list.md,其中部分模型的benchmark如下:
注:以上精度指标为 COCO2017 (https://cocodataset.org/#home)验证集
mAP(0.5:0.95),GPU 推理耗时基于 NVIDIA Tesla T4 机器,精度类型为 FP32, CPU 推理速度基于
Intel® Xeon® Gold 5117 CPU @ 2.00GHz,线程数为8,精度类型为 FP32。
简单来说,表格从上到下,模型推理速度更快,从下到上,模型精度更高。本次是按照教程以PP-YOLOE_plus-S模型为例,完成一次模型全流程开发。你们也可以依据自己的实际使用场景,判断并选择一个合适的模型做训练,训练完成后可在产线内评估合适的模型权重,并最终用于实际使用场景中。
2.环境配置
和上一篇推文一致,基于win10系统CUDA11.8系统下的本地配置教程(
python -m pip install paddlepaddle-gpu==3.0.0b1 -i https://www.paddlepaddle.org.cn/packages/stable/cu118/
)。paddle版本为
3.0.0-beta1
,前文已经介绍过
paddleX
的安装,本文不过多赘述。
3.数据准备和校验
3.1 数据准备
本教程采用行人跌倒检测数据集作为示例数据集,可通过以下命令获取示例数据集。
ubuntu系统下数据集获取命令:
cd /path/to/paddlex
wget https://paddle-model-ecology.bj.bcebos.com/paddlex/data/fall_det.tar -P ./dataset
tar-xf ./dataset/fall_det.tar -C ./dataset/
或者Windows简单粗暴一点,网页打开链接https://paddle-model-ecology.bj.bcebos.com/paddlex/data/fall_det.tar直接下载,再解压缩到
cd /path/to/paddlex/dataset
中。
*当后续业务中您需要使用自备的已标注数据集时,需要按照 PaddleX 的格式要求对自备数据集进行调整,以满足 PaddleX 的数据格式要求。关于数据格式介绍,您可以参考PaddleX
数据格式介绍(https://github.com/PaddlePaddle/PaddleX/blob/release/3.0-beta/docs/tutorials/data/dataset_format.md)。如果您有一批待标注数据,可以参考通用目标检测数据标注指南完成数据标注。
3.2 数据集校验
在对数据集校验时,只需一行命令:
python main.py -c paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml -oGlobal.mode=check_dataset -oGlobal.dataset_dir=./dataset/fall_det
格外注意数据集的地址
dataset_dir=./dataset/fall_det
别搞错了。
执行上述命令后,PaddleX 会对数据集进行校验,并统计数据集的基本信息。命令运行成功后会在 log 中打印出绿色的
Check dataset passed !
信息,同时相关产出会保存在当前目录的
./output/check_dataset
目录下,产出目录中包括可视化的示例样本图片和样本分布直方图。
校验结果文件保存在
./output/check_dataset_result.json
,校验结果文件具体内容为:
上述校验结果中,check_pass 为 True 表示数据集格式符合要求,其他部分指标的说明如下:
- attributes.num_classes:该数据集类别数为 1,此处类别数量为后续训练需要传入的类别数量;
- attributes.train_samples:该数据集训练集样本数量为 1224;
- attributes.val_samples:该数据集验证集样本数量为 216;
- attributes.train_sample_paths:该数据集训练集样本可视化图片相对路径列表;
- attributes.val_sample_paths:该数据集验证集样本可视化图片相对路径列表;
注:只有通过数据校验的数据才可以训练和评估。
3.3 数据集格式转换/数据集划分
如需对数据集格式进行转换或是重新划分数据集,可通过修改配置文件或是追加超参数的方式进行设置。数据集校验相关的参数可以通过修改配置文件中CheckDataset下的字段进行设置,配置文件中部分参数的示例说明如下:
CheckDataset:
- convert: enable: 是否进行数据集格式转换,为True时进行数据集格式转换,默认为False;
- src_dataset_type: 如果进行数据集格式转换,则需设置源数据集格式,数据可选源格式为LabelMe、VOC; split:
- enable: 是否进行重新划分数据集,为True时进行数据集格式转换,默认为False; train_percent: 如果重新划分数据集,则需要设置训练集的百分比,类型为 0-100 之间的任意整数,需要保证和val_percent值加和为 100;
- val_percent: 如果重新划分数据集,则需要设置验证集的百分比,类型为 0-100 之间的任意整数,需要保证和train_percent值加和为 100;
数据转换和数据划分支持同时开启,对于数据划分原有标注文件会被在原路径下重命名为
xxx.bak
,以上参数同样支持通过追加命令行参数的方式进行设置,例如重新划分数据集并设置训练集与验证集比例,训练集与验证集比例8:2划分:
-oCheckDataset.split.enable=True -oCheckDataset.split.train_percent=80-oCheckDataset.split.val_percent=20
4.模型训练和模型评估
4.1 模型训练
在训练之前,请确保您已经对数据集进行了校验。完成 PaddleX 模型的训练,只需如下一条命令:
python main.py -c paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml -o Global.mode=train -o Global.dataset_dir=./dataset/fall_det -o Train.num_classes=1
当我运行该句时出现报错如下:
查错后增加下参数
-o Global.device =gpu:0
,因为是单卡GPU下运行,也确认paddle是gpu版本
即解决了前面的报错,但是出现了新的报错
但是修改后出现了新的错误
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x8f in position 7:
illegal multibyte sequence
看起来还有一个encoding报错,应该是win默认gbk编码导致的 ,可以试一下
set PYTHONUTF8=1
命令行代码。设置后再次运行
python main.py -c paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml -o Global.mode=train -o Global.dataset_dir=./dataset/fall_det -o Train.num_classes=1 -o Global.device=gpu:0 -o Train.epochs_iters=10
已经跑通。
在 PaddleX 中模型训练支持:修改训练超参数、单机单卡/多卡训练等功能,只需
修改配置文件
或
追加命令行参数
。
PaddleX 中每个模型都提供了模型开发的配置文件,用于设置相关参数。模型训练相关的参数可以通过修改配置文件中Train下的字段进行设置,配置文件中部分参数的示例说明如下:
- Global: mode:模式,支持数据校验(check_dataset)、模型训练(train)、模型评估(evaluate);
- device:训练设备,可选cpu、gpu、xpu、npu、mlu,除 cpu 外,多卡训练可指定卡号,如:gpu:0,1,2,3,如果系统为windows系统,只支持单卡训练,即gpu:0;
- Train:训练超参数设置;
- epochs_iters:训练轮次数设置;
- learning_rate:训练学习率设置;
更多超参数介绍,可以参考PaddleX 超参数介绍(https://github.com/PaddlePaddle/PaddleX/blob/release/3.0-beta/docs/tutorials/base/hyperparameters_introduction.md)。
注: 以上参数可以通过追加命令行参数的形式进行设置,如
- 指定模式为模型训练:
-o Global.mode=train
;- 指定前 2 卡 gpu训练:
-o Global.device=gpu:0,1
;- 设置训练轮次数为 10:
-o Train.epochs_iters=10
。 模型训练过程中,PaddleX 会自动保存模型权重文件,默认为output,如需指定保存路径,可通过配置文件中-o Global.output
字段 PaddleX对您屏蔽了动态图权重和静态图权重的概念。在模型训练的过程中,会同时产出动态图和静态图的权重,在模型推理时,默认选择静态图权重推理。
训练产出解释:
在完成模型训练后,所有产出保存在指定的输出目录(默认为./output/)下,通常有以下产出:
train_result.json
:训练结果记录文件,记录了训练任务是否正常完成,以及产出的权重指标、相关文件路径等;train.log
:训练日志文件,记录了训练过程中的模型指标变化、loss 变化等;config.yaml
:训练配置文件,记录了本次训练的超参数的配置;.pdparams、.pdema、.pdopt.pdstate、.pdiparams、.pdmodel
:模型权重相关文件,包括网络参数、优化器、EMA、静态图网络参数、静态图网络结构等;跑完的页面是这样的 会在output/best_model
下输出
4.2 模型评估
在完成模型训练后,可以对指定的模型权重文件在验证集上进行评估,验证模型精度。使用 PaddleX 进行模型评估,只需一行命令:
python main.py -c paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml \
-o Global.mode=evaluate \
-o Global.dataset_dir=./dataset/fall_det
与模型训练类似,模型评估支持修改配置文件或追加命令行参数的方式设置。
注:在模型评估时,需要指定模型权重文件路径,每个配置文件中都内置了默认的权重保存路径,如需要改变,只需要通过追加命令行参数的形式进行设置即可,如
-o Evaluate.weight_path=./output/best_model.pdparams
。
4.3 校验结果是否正确查看
打开记录文件(output/check_dataset_result.json)内容如下
2. 模型训练结果记录文件(output/train_result.json)内容如下
3. 模型评估结果内容如下
4. 行人跌倒检测如下
5.模型调优
在经过模型训练和评估后,可以通过调整超参数来提升模型的精度。通过合理调整训练轮数,您可以控制模型的训练深度,避免过拟合或欠拟合;而学习率的设置则关乎模型收敛的速度和稳定性。因此,在优化模型性能时,务必审慎考虑这两个参数的取值,并根据实际情况进行灵活调整,以获得最佳的训练效果。
推荐在调试参数时遵循控制变量法
- 首先固定训练轮次为 10,批大小为 8。
- 基于 PP-YOLOE_plus-S模型启动三个实验,学习率分别为:0.00002,0.0001,0.0005。
- 可以发现实验二精度最高的配置为学习率为0.0001,在该训练超参数基础上,改变训练论次数,观察不同轮次的精度结果,发现轮次在 50epoch 时基本达到了最佳精度。
结果汇总- 学习率探寻实验结果:
实验轮次学习率batch_size训练环境mAP@0.5实验一100.000028单卡0.910实验二100.00018单卡0.894实验二增加训练轮次500.00018单卡0.921实验二续增训练轮次1000.00018单卡0.928实验三100.00058单卡0.727
mAP介绍
[email protected]
: mean Average Precision(IoU=0.5): 即将IoU设为0.5时,计算每一类的所有图片的AP,然后所有类别求平均,即mAP。
[email protected]:.95
(mAP@[.5:.95]):表示在不同IoU阈值(从0.5到0.95,步长0.05)(0.5、0.55、0.6、0.65、0.7、0.75、0.8、0.85、0.9、0.95)上的平均mAP。
AP
(Average Precision):是单个类别平均精确度,而
mAP
是所有类别的平均精确度
AP
是
Precision-Recall Curve
曲线下面的面积
注: 本教程为单卡教程,如果您有多张GPU那会更加快速实验,而单卡则需通过调整训练卡数完成本次实验,但最终指标未必和上述指标对齐,属正常情况。
实验结果中mAP@0.5值可在模型输出目录的train.log文件中获得
学习率原理介绍
学习率(Learning rate)作为监督学习以及深度学习中重要的超参,其决定着目标函数能否收敛到局部最小值以及何时收敛到最小值。合适的学习率能够使目标函数在合适的时间内收敛到局部最小值.
以梯度下降算法为例,观察不同的学习率对代价损失函数的收敛过程的影响(以凸函数为例梯度(坡度)是指斜坡的倾斜度或倾斜度,Descent:下降,该算法是迭代的(iterative),意味着我们需要多次进行多次计算才能得到最优的结果)
梯度下降公式如下:
θ
j
=
θ
j
−
α
Δ
J
(
θ
)
Δ
θ
j
\theta_j = \theta_j-\alpha \frac{\Delta J(\theta)}{\Delta \theta_j}
θj=θj−αΔθjΔJ(θ)
当学习率设置的过小时,收敛过程如下:
当学习率设置的过大时,收敛过程如下:
如上图(左所示),一开始成本/损失函数(cost function)上的point下降的较快,说明学习率较大,步长大,随着该point的下降变慢,学习率逐渐减小,步长变慢。梯度下降算法就是为了找到损失函数的最小值。
学习率调整
(1)离散下降
对于深度学习来说,每
t
t
t 轮学习,学习率减半。对于监督学习来说,初始设置一个较大的学习率,然后随着迭代次数的增加,减小学习率。
(2)指数减缓(exponential decay)
学习率按训练轮数增长指数差值递减。例如:
α
=
0.9
5
e
p
o
c
h
_
n
u
m
∙
α
0
\alpha = 0.95^{epoch\_num}\bullet \alpha_0
α=0.95epoch_num∙α0
又或者公式为:
α
=
k
e
p
o
c
h
_
n
u
m
\alpha = \frac{k}{\sqrt{epoch\_num}}
α=epoch_numk
其中
e
p
o
c
h
_
n
u
m
epoch\_num
epoch_num为当前epoch的迭代轮数。第二种方法则会引入另一个超参数
k
k
k
(3)分数减缓
对于深度学习来说,学习率按照公式
α
=
α
1
+
d
e
c
a
y
_
r
a
t
e
∗
e
p
o
c
h
_
n
u
m
\alpha = \frac{\alpha}{1+decay\_rate*epoch\_num}
α=1+decay_rate∗epoch_numα变化,
d
e
c
a
y
_
r
a
t
e
decay\_rate
decay_rate控制减缓幅度。
可以由下图看出,固定学习率时,当到达收敛状态时,会在最优值附近一个较大的区域内摆动;而当随着迭代轮次的增加而减小学习率,会使得在收敛时,在最优值附近一个更小的区域内摆动。(之所以曲线震荡朝向最优值收敛,是因为在每一个mini-batch中都存在噪音)。因此,选择一个合适的学习率,对于模型的训练将至关重要。下面来了解一些学习率调整的方法。
如果我们对每次迭代的学习进行记录,并绘制学习率(对数尺度)与损失,我们会看到,随着学习率的提高,从某个点开始损失会停止下降并开始提高。在实践中,学习速率的理想情况应该是从图的左边到最低点(如下图所示)。在本例中,是从 0.001 到 0.01。
)
因此,想得到最佳学习速率是很难做到的。下图演示了配置学习速率时可能遇到的不同情况。此外,学习速率对模型收敛到局部极小值(也就是达到最好的精度)的速度也是有影响的。因此,从正确的方向做出正确的选择意味着我们可以用更短的时间来训练模型。
学习率过大的问题:
当学习率过大时,梯度下降可能会
在最小值点附近"震荡"而无法收敛
。这是因为大的学习率使得每一步的更新都很大,导致函数曲面上的"山谷"变得陡峭,难以找到真正的最小值点。
过大的学习率还可能导致优化过程不稳定。在训练过程中,梯度下降的每一次迭代都可能改变参数的更新方向,如果学习率过大,这种改变可能会
跳过真正的最小值点
,导致优化过程停滞不前。
学习率过小的问题:
当学习率过小的时候,梯度下降可能会收敛得太慢。这是因为小的学习率使得每一步的更新都很小,需要更多的迭代次数才能达到最小值点。
此外,过小的学习率还可能导致
"局部最小值"
问题。在多峰值的函数中,梯度下降可能会陷入
局部最小值
,而无法找到
全局最小值
。这是因为梯度下降对于当前位置的梯度非常敏感,如果学习率过小,它可能只会沿着当前的梯度方向前进一小步,而无法跳出局部最小值。
针对上述2类问题,有以下几种应对策略:
(1) 动态调整学习率:在训练过程中,根据优化进程的反馈来动态调整学习率。例如,可以使用
学习率衰减策略
,即随着训练轮次的增加,逐渐减小学习率。也可以使用
学习率自适应策略
,如
Adam算法
,它可以根据梯度的分布动态调整每个参数的学习率。
(2) 添加正则化项:为了防止过拟合和模型复杂度过高,可以在损失函数中添加正则化项,如
L1正则化
和
L2正则化
。这些正则化项可以有效地控制模型的复杂度,并提高模型的泛化能力。
(3) 使用更复杂的优化算法:除了梯度下降法
之外,还有许多其他的优化算法可以用于深度学习,如
牛顿法
、
拟牛顿法
、
共轭梯度法
等。这些算法通常可以提供更好的优化性能和更快的收敛速度。
(4) 初始化策略:良好的初始化策略可以帮助优化算法更快地找到最小值点。例如,可以使用高斯分布或均匀分布来初始化权重矩阵的参数。此外,还可以使用预训练模型作为初始模型进行微调。
(5) 数据增强:通过增加数据集的大小和多样性,可以有效地提高模型的泛化能力和鲁棒性。数据增强可以通过随机变换、裁剪、旋转
等方式实现。
(6) 早停法:在训练过程中,我们可以观察模型的损失函数值随训练轮次的变化情况。当损失函数值变化不大时,可以认为模型已经收敛,此时可以停止训练并保存模型
。这种方法可以
防止过拟合
和
模型复杂度过高
。
上图用的方法是由 Loshchilov&Hutter 提出的预热重启(Warm Restarts)随机梯度下降。这种方法使用余弦函数作为周期函数,并在每个周期最大值时重新开始学习速率。「预热」是因为学习率重新开始时并不是从头开始的,而是由模型在最后一步收敛的参数决定的。通过周期性跳过「山脉」的办法缩短训练时间,使用这些方法除了可以节省时间外,还可以在不调整的情况下提高分类准确性,而且可以减少迭代次数。
batchsize/epoch/iteration介绍
为什么需要batchsize/epoch/iteration?
当数据太大的时候,我们不能一次把所有的数据传递给计算机。因此我们需要将数据分成更小的大小,并将其一个接一个地交给我们的计算机,并在每一步结束时更新神经网络的权重。由于一个epoch太大,不能一次输入到计算机中,我们将它分成几个较小的批次(batches)。 batches是指单个批次中出现的训练样例总数。Iteration 是指一个epoch中需要的batch的个数(迭代数)
随着epoch次数的增加,神经网络中权值变化的次数增多,曲线从欠拟合到最优再到过拟合。
batchsize的设置技巧
一般而言,根据GPU显存,设置为最大,而且一般要求是8的倍数(比如16,32,64),GPU内部的并行计算效率最高。
或者选择一部分数据,设置几个8的倍数的Batch_Size,看看loss的下降情况,再选用效果更好的值。
总结:
batch_size设的大一些,收敛得快,也就是需要训练的次数少,准确率上升的也很稳定,但是实际使用起来精度不高;
batch_size设的小一些,收敛得慢,可能准确率来回震荡,因此需要把基础学习速率降低一些,但是实际使用起来精度较高。
batchsize对模型训练有什么影响?
1.训练速度
batch size大小会影响模型的训练速度。 较大的batch size可以更快地处理训练数据,因为在每个epoch中,较大的batch size可以同时处理更多的数据,从而减少了训练时间。相反,较小的batch size需要更多的迭代才能完成一个epoch的训练,因此训练时间更长。但是,较大的batch size也可能导致GPU显存不足,从而导致训练速度下降。
2.训练稳定性
batch size大小还会影响模型的训练稳定性。较小的batch size可以提高模型的训练稳定性,因为在每个epoch中,模型会更新多次,每次更新的权重都会有所不同,这有助于避免局部最优解。 另一方面,较大的batch size可能会导致模型过拟合,因为在每个epoch中,模型只进行一次权重更新,这使得模型更容易陷入局部最优解。
3.内存消耗
batch size大小还会影响内存消耗。较大的batch size需要更多的内存来存储样本和网络权重,因此可能会导致内存不足, 从而影响训练效果。另一方面,较小的batch size需要更少的内存,但也可能会导致训练时间变长。
4.梯度下降
batch size大小还会影响梯度下降。在深度学习中,梯度下降是一种常用的优化算法,用于调整模型的权重。较小的batch size可以使模型更容易收敛,因为每个batch中的样本更接近于独立同分布的分布,使得梯度下降的方向更加一致。另一方面,较大的batch size可能会导致梯度下降方向不一致,从而影响训练效果。
5.1 学习率实验
5.1.1 实验一
模式为模型训练:
-o Global.mode=train
轮次为10:
-o Train.epochs_iters=10
学习率为0.00002:
-o Train.learning_rate=0.00002
训练环境为单卡:
-o Global.device=gpu:0
基于 PP-YOLOE_plus-S 模型:
paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml
batch_size为8: 在
PP-YOLOE_plus-S.yaml
中设置
可以直接修改.yaml文件或者在下面代码中加命令行参数
python main.py -c paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml -o Global.mode=train -o Global.dataset_dir=./dataset/fall_det
运行结果如下,mAP@0.5值为0.910:
5.1.2 实验二
模式为模型训练:
-o Global.mode=train
轮次为10:
-o Train.epochs_iters=10
学习率为0.0001:
-o Train.learning_rate=0.0001
训练环境为单卡:
-o Global.device=gpu:0
基于 PP-YOLOE_plus-S 模型:
paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml
batch_size为8: 在
PP-YOLOE_plus-S.yaml
中设置
运行结果如下,mAP@0.5值为0.894:
5.1.3 实验三
模式为模型训练:
-o Global.mode=train
轮次为10:
-o Train.epochs_iters=10
学习率为0.0005:
-o Train.learning_rate=0.0005
训练环境为单卡:
-o Global.device=gpu:0
基于 PP-YOLOE_plus-S 模型:
paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml
batch_size为8: 在
PP-YOLOE_plus-S.yaml
中设置
运行结果如下,mAP@0.5值为0.727:
5.2 epoch 实验
5.2.1 实验四
模式为模型训练:
-o Global.mode=train
轮次为50:
-o Train.epochs_iters=50
学习率为0.0001:
-o Train.learning_rate=0.0001
训练环境为单卡:
-o Global.device=gpu:0
基于 PP-YOLOE_plus-S 模型:
paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml
batch_size为8: 在
PP-YOLOE_plus-S.yaml
中设置
运行结果如下,mAP@0.5值为0.921:
5.2.2 实验五
模式为模型训练:
-o Global.mode=train
轮次为100:
-o Train.epochs_iters=100
学习率为0.0001:
-o Train.learning_rate=0.0001
训练环境为单卡:
-o Global.device=gpu:0
基于 PP-YOLOE_plus-S 模型:
paddlex/configs/object_detection/PP-YOLOE_plus-S.yaml
batch_size为8: 在
PP-YOLOE_plus-S.yaml
中设置
运行结果如下,mAP@0.5值为0.928:
版权归原作者 Winifred_*₍˄·͈༝·͈˄*₎ 所有, 如有侵权,请联系我们删除。