【Python】科研代码学习:十一 Optimization [Optimizer, Schedule]
- Optimizer 前置知识
- 优化器在 `torch` 中的调用
- 优化器在 `transformers` 中的调用
- `AdamW` 优化器
- Scheduler 前置知识
- 调度器在 `transformers` 中的调用
Optimizer 前置知识
- 什么是
Optimizer
优化器?首先来学习一下
【知乎:优化器-optimizer 汇总】
按照这里的学习文章,说一下重要的内容,讲一下基本逻辑;优点;缺点
※ Optimizer
优化器就是有如下不同的版本,主要解决的是关于梯度、学习率、样本批次、权重等计算
SGD (Stochastic Gradient Descent)
随机梯度下降法
每次选取哪个样本是随机的;更新速度快;损失波动大BGD (Batch Gradient Descent)
批量梯度下降法
每次将所有样本的梯度求和;梯度更新平滑;内存消耗大,容易进入局部最优解MBGD (Mini-batch Gradient Descent)
小批量梯度下降法
每一次利用一小批样本n
梯度计算;收敛更稳定,速度较快;没有考虑数据集的稀疏度影响
一般n=50~256
Momentum
动量梯度下降法
考虑了梯度方向的惯性;减少权重优化中的震荡问题;缺少一些减速的适应性NAG (Nesterov Accelerated Gradient)
牛顿动量梯度下降法
Momentum
的改进,用了二阶指数平滑;表现更好;没有考虑不同参数的重要程度AdaGrad (Adaptive Gradient Algorithm)
自适应学习率梯度下降法
可以对学习率自动调整;减少了学习率的手动调节;学习率会收缩到很小Adam
学习了Adagrad
与Momentum
;能适应系数梯度,缓解梯度震荡;AdamW
将权重衰减和学习率解耦;实验结果显示比Adam
有更好的泛化性能
优化器在 torch
中的调用
- PyTorch 中最常用的优化器是:
torch.optim.SGD:随机梯度下降优化器
torch.optim.Adam:自适应矩估计优化器
torch.optim.Adagrad:自适应梯度优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
优化器在 transformers
中的调用
- 【HF官网-Doc-Transformers-Optimization】
在 API 中,主要就是如下几个:
AdamW (PyTorch)
AdaFactor (PyTorch)
AdamWeightDecay (TensorFlow)
- 现在主流是用
AdamW
的,就介绍一下这个吧
AdamW
优化器
- 首先看一下源码,哦,他就是从
torch.Optimizer
继承过来的,实现了自己的一个类AdamW
。看一下参数
params(Iterable[nn.parameter.Parameter])
:提供模型的参数
lr(float)
:学习率,默认为0.001
betas(Tuple[float,float])
,即Adam
中的(b1,b2)
,默认为(0.9,0.999)
eps
:epsilon,默认为1e-06
weight_decay
:解耦后的权重缩减,默认为0.0
correct_bias(bool)
:是否修复Adam
中的偏差值 bias,默认为 True
- 方法:
step()
,表示一步优化步骤。 - 用法一:可以作为
torch.optimizer
类,自己实现一个torch.nn
,直接使用 - 用法二:比较方便的是搭配
transformers
中的trainingArguments
:
参考 【Python】科研代码学习:七 TrainingArguments,Trainer
在TrainingArguments
中,可以设置optim
属性,默认即为adamw_torch
;可以设置weight_decay, adam_beta1, adam_beta2, adam_epsilon
等属性的值
Scheduler 前置知识
- 而什么又是
Scheduler
调度器呢?
※Scheduler
调度器主要是,对于已经选择好的优化器Optimizer
,利用epoch、时间等变化对学习率进行调整
【学习率】torch.optim.lr_scheduler学习率10种调整方法整理
可以看一下torch.optim.lr_scheduler
中为我们提供的一些调度器
LambdaLR
:初始 lr 乘以给定函数
MultiplicativeLR
:当前 lr 乘以给定函数
StepLR
:以固定间隔成倍衰减初始 lr
MultiStepLR
:以设定的时间间隔成倍衰减初始 lr
ExponentialLR
:指数衰减初始 lr
CosineAnnealingLR
:余弦函数式变化 lr
ReduceLROnPlateau
:当某一指标不再提升时,降低 lr
CyclicLR
:周期调整 lr
CosineAnnealingWarmRestarts
:余弦退火
调度器在 transformers
中的调用
-
首先最重要的一个,是
SchedulerType
相当于,我们通过这个类似枚举类,来指明我们使用的是哪种调度器
可以看一下,有线性的,余弦的,多项式的,常数的,带预热的等
※详细可以看官网API,每个调度器如何影响lr
-
比如这个是带预热的余弦调度器
-
最主要的还是配合
TrainingArguments
使用
参考 【Python】科研代码学习:七 TrainingArguments,Trainer
在TrainingArguments
中,可以设置lr_scheduler_type
,无需我们自己创建一个调度器,HF会按照输入的调度器名字,自动创建对应的调度器。