【调优方法】——warmup预热
什么是warmup?
warmup是一种学习率预热的方法,是指在训练开始时使用较小的学习率,经过一段时间(如若干个epoch或steps)逐渐增加学习率,直到达到预先设置的学习率。
这种策略可以帮助模型在初期避免大幅度的参数更新。
为什么引入warmup?
- 模型初始化:刚开始时,模型参数通常是随机初始化的,模型对数据的理解几乎为0,较大的学习率会到导致模型在未充分理解数据的情况下,迅速作出较大的调整,导致模型的不稳定(震荡),容易导致“学偏”或发散。
- 逐步学习:使用小学习率可以让模型逐步适应数据特征,降低初期训练的不稳定性。随着训练的进行,模型对数据的理解加深,使用较大的学习率时更有可能稳定快速地收敛到有效的解。
- 局部最优:当接近目标时,使用小学习率能减少对当前已知特征的破坏,从而更有效地找到局部最优解。
warmup策略
这里介绍两种学习率gradual warmup策略:线性warmup和指数warmup。
1. 线性warmup(虚线)
- 从初始学习率0.0001开始,随着步骤的增加,学习率线性上升至目标学习率0.01.
- 在前100个步骤内,学习率逐渐增大,使模型在初期以较小的步伐适应数据,避免过拟合。
2. 指数warmup(点划线)
- 学习率从初始值0.0001开始,但其增长速率是指数级的,直至上升至目标学习率0.01.
- 在warmup阶段,学习率迅速提升,初期的学习速度较快,适合在模型已有一定知识的情况下进行快速收敛。
warmup改进
开始在ResNet论文中提出了constant warmup策略:使用一个110层的ResNet在cifar10上训练时,先用0.01的学习率训练直到训练误差低于80%(大概训练了400个steps),然后使用0.1的学习率进行训练。它的不足之处在于从一个很小的学习率一下变为比较大的学习率可能会导致训练误差突然增大。
于是18年Facebook提出了gradual warmup来解决这个问题,即从最初的小学习率开始,每个step增大一点点,直到达到最初设置的学习率进行训练。
gradual warmup 实现代码:
"""
Implements gradual warmup, if train_steps < warmup_steps, the
learning rate will be `train_steps/warmup_steps * init_lr`.
Args:
warmup_steps:warmup步长阈值,即train_steps<warmup_steps使用预热学习率,否则使用预设值学习率
train_steps:训练了的步长数
init_lr:预设置学习率
"""
import numpy as np
warmup_steps = 2500
init_lr = 0.1
# 模拟训练15000步
max_steps = 15000
for train_steps in range(max_steps):
if warmup_steps and train_steps < warmup_steps:
warmup_percent_done = train_steps / warmup_steps
warmup_learning_rate = init_lr * warmup_percent_done #gradual warmup_lr
learning_rate = warmup_learning_rate
else:
#learning_rate = np.sin(learning_rate) #预热学习率结束后,学习率呈sin衰减
learning_rate = learning_rate**1.0001 #预热学习率结束后,学习率呈指数衰减(近似模拟指数衰减)
if (train_steps+1) % 100 == 0:
print("train_steps:%.3f--warmup_steps:%.3f--learning_rate:%.3f" % (
train_steps+1,warmup_steps,learning_rate))
上述代码实现的warmup预热学习率及完成后衰减(sin/exp decay)的曲线图如下:
参考文献
原文地址:https://blog.csdn.net/weixin_44162361/article/details/143274549
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!