optimizer 优化器,用来根据参数的梯度进行沿梯度下降方向进行调整模型参数,使得模型loss不断降低,达到全局最低,通过不断微调模型参数,使得模型从训练数据中学习进行特征提取的能力。目前常用的优化器有SGD,Adam,AdamW等。
SGD
随机梯度下降
从训练样本中随机选取一个进行计算梯度,然后×学习率进行调整模型参数。
优点:训练速度快,对非凸函数效果好
缺点:局部最优点或鞍点是,梯度为0,无法继续更新参数,沿平缓进展慢,而沿陡峭方向震荡,难以快速收敛
w
t
+
1
=
w
t
?
α
?
g
t
w_{t+1}=w_t-α*g_t
wt+1?=wt??α?gt?
其中α为学习率,g_t为当前参数的梯度
SGD-M
SGD-with Momentum 在SGD的基础上引入一阶动量。
m
t
=
β
1
?
m
t
?
1
+
(
1
?
β
)
?
g
t
m_t=β_1*m_{t-1}+(1-β)*g_t
mt?=β1??mt?1?+(1?β)?gt?
加入动量因素,但并未完全解决震荡幅度过大和持续更新问题,当局部沟壑较深,依然会困在局部最优点内震荡
SGD with Nesterov Acceleration
NAG全称为Nesterov Accelerated Gradient 当前通过向累积动量方向前进后,计算当时的下降方向,然后根据累积动量和下一点的梯度方向,计算当前累积动量
AdaGrad
自适应学习率算法,为了模型某个参数度量历史更新频率,使得更新频率高的参数学习率自适应降低,而更新频率低的参数自适应学习率增加,则引入了二阶动量,记录到目前为止所有梯度值的平方和
V
t
=
∑
r
=
1
t
g
r
2
V_t=\sum{^t_{r=1}}g^2_r
Vt?=∑r=1t?gr2?
缺点:由于V_t单调递增,学习率不断降低,后面数据无法学习到有用信息,而且二阶向量智能表示整个学习过程全部累积,不能仅表示近期的更新频率。
AdaDelta/RMSProp
将二阶动量计算方式修改为过去一段时间的下降梯度,与SGD一阶动量计算相同,指数移动平均值大约过去一段时间平均值:
V
t
=
β
2
?
V
t
?
1
+
(
1
?
β
2
)
g
t
2
V_t=β_2*V_{t-1}+(1-β_2)g^2_t
Vt?=β2??Vt?1?+(1?β2?)gt2?
Adam
将SGD的一阶动量和AdaDelta中的二阶动量结合,得到Adam,通过一阶动量和二阶动量,有效控制学习率步长和梯度方向,防止梯度振荡和静止。
调整:为了使学习率单调递减,二阶动量需要进行调整
V
t
=
m
a
x
(
β
2
?
V
t
?
1
+
(
1
?
β
2
)
g
t
2
,
V
t
?
1
)
V_t=max(β_2*V_{t-1}+(1-β_2)g^2_t,V_{t-1})
Vt?=max(β2??Vt?1?+(1?β2?)gt2?,Vt?1?)
由于后期学习率还是低,所以可能会影响有效收敛。
Nadam
在Adam的基础上,加入了SGD with Nesterov Acceleration的策略,计算一阶动量时,先求下一步下降方向,然后回过头进行累积动量计算。
AdamW
Adam中的权重衰减weight_decay ,由于自适应学习率改变,导致不正确,AdamW
通过将权重衰减与梯度更新进行解耦,来达到更高效的权重衰减,提高优化器的表现。
Scheduler
制定一个合适的学习率衰减策略**。**可以使用定期衰减策略,比如每过多少个epoch就衰减一次;或者利用精度或者AUC等性能指标来监控,当测试集上的指标不变或者下跌时,就降低学习率。Scheduler,则是根据一定策略,多个steps或epoch后进行学习率调整。
- LambdaLR
? 通过设置自定义函数,进行学习率调整
-
StepLR
n e w l r = i n i t i a l l r ? γ e p o c h / / s i z e new_{lr}=initial_{lr}*γ^{epoch//size} newlr?=initiallr??γepoch//size
γ是超参数(0-1),size为几个epoch数目进行更新学习率 -
MultiStepLR
n e w l r = i n i t i a l l r ? γ b i s e c t ? r i g h t ( m i l e s t o n e , e p o c h ) new_{lr}=initial_{lr}*γ^{bisect-right(milestone,epoch)} newlr?=initiallr??γbisect?right(milestone,epoch)
? 将StepLR中固定的size进行更新学习率,修改为递增list_size,进行调整学习率。
-
ExponentialLR
n e w l r = i n i t i a l l r ? γ e p o c h new_{lr}=initial_{lr}*γ^{epoch} newlr?=initiallr??γepoch
单纯的指数学习率调整,每个epoch一更新 -
LinearLR
线性学习率调整,给定起始和最终的学习率,给定更新总步长,更新步长内线性下降,超出部分保存最低学习率不变。、
-
CyclicLR
呈曲线不断上升和下降,设置谷底和峰值学习率和振幅轮次
-
CosineAnnealingLR
余弦退火学习率,设置T_max 周期的一半,最小学习率eta_min
-
SequentialLR
串联多个学习率schedulers
-
ConstantLR
常数学习率,再total_iters轮内乘以factor,以外恢复原学习率
warmup
由于刚开始训练时,模型的权重(weights)是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epoches或者一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型相对稳定后再选择预先设置的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。
idea
这里优化器都是只根据一次loss,向一个方向走一步,如果加入一些存储空间,让loss在一次下降,向不同方向走几个step之后进行比较两者loss,再选择loss低的点进行重复,可以一个梯度下降,一个随机修改。
由于Adam类的优化器学习率都会递减,那么训练数据输入顺序不同会对模型结果产生一定影响吧,可能这就是随机种子产生影响中的一个因素,为了使高质量,多样性的训练数据靠前,需要进行简单调整,可能最后模型效果会更好些。
总结
Adam和Adamw,在权重衰减哪里的数学公式有点没看明白,以后回顾的时候再努力思考一下。