1 梯度下降方向
- 若使用整个样本集进行求解,损失梯度会指向全局最优方向
2. 若使用分批次样本进行求解,损失梯度会指向当前批次最优方向
如ImageNet大型图像数据集,在实际应用中往往不可能一次性将所有数据载入内存(算力也不够),所以只能分批次(batch)训练
2 优化器
目的:为了使网络更快的收敛
优化器(Optimizer)(SGD、Momentum、AdaGrad、RMSProp、Adam)
许多优化算法的设计从梯度方向和学习率两个方面入手
- 梯度方向入手:动量更新策略
- 学习率入手:涉及调参问题
- 两方面同时入手:自适应更新策略
2.1 SGD(随机梯度下降)
BGD、SGD、MBGD分别为批量梯度下降算法、随机梯度下降算法、小批量梯度下降算法
BGD在训练的时候选用所有的训练集进行计算,SGD在训练的时候只选择一个数据进行训练,而MBGD在训练的时候只选择小部分数据进行训练
这三个优化算法在训练的时候虽然所采用的的数据量不同,但是他们在进行参数优化的时候是相同的
w t + 1 = w t − α ⋅ g ( w t ) w_{t+1}=w_t-\alpha \cdot g(w_t) wt+1=wt−α⋅g(wt)
其中, α \alpha α为学习率, g ( w t ) g(w_t) g(wt)为 t t t时刻对参数 w t w_t wt的损失梯度
缺点:
- 易受样本噪声影响,进而影响梯度下降方向
- 可能陷入局部最优解
PyTorch中SGD的使用格式为:
# 使用SGD算法,则momentum参数和nesterov参数默认即可不需要设置
torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False, *, maximize=False)
用法:
import torch
# 创建SGD优化器
optimizer = torch.optim.SGD(model.parameters(),lr=0.1)
# 梯度清零
optimizer.zero_grad()
loss_fn(model(input), target).backward()
# 参数更新
optimizer.step()
2.2 Momentum(动量)
Momentum
是在随机梯度下降法中增加了惯性项,可以增加算法的收敛速度和稳定性,有效地防止更新量的急剧变化动量算法每下降一步都是由前面下降方向的一个累积和当前点梯度方向组合而成
v t = β ⋅ v t − 1 + g ( w t ) v_t=\beta\cdot v_{t-1}+g(w_t) vt=β⋅vt−1+g(wt)
w t + 1 = w t − α ⋅ v t w_{t+1}=w_t-\alpha \cdot v_t wt+1=wt−α⋅vt
其中, β ( 0.9 ) \beta(0.9) β(0.9)为动量系数, α \alpha α为学习率, g ( w t ) g(w_t) g(wt)为 t t t时刻对参数 w t w_t wt的损失梯度
NAG算法
(Nesterov Accelerated Gradient),是对Momentum(动量)算法的一种改进算法,能够防止大幅振荡,不会错过最小值,并会对参数更加敏感既然每一步都要将两个梯度方向(历史梯度、当前梯度)做一个合并再下降,因此可以按照前面一小步位置的“超前梯度”来做梯度合并。这样就可以先往前走一小步,在靠前一点的位置看到梯度,然后按照那个位置再来修正这一步的梯度方向
PyTorch中Momentum或NAG的使用格式为:
# momentum:动量参数,设定数值
# nesterov设置为True时,将会使用NAG算法,它是动量算法的一种优化
torch.optim.SGD(params, lr=<required parameter>, momentum=0.9, dampening=0, weight_decay=0, nesterov=False, *, maximize=False)
2.3 AdaGrad(自适应学习率)
AdaGrad
是通过参数来调整合适的学习率,是能独立自动调整模型参数的学习率,对稀疏参数进行大幅更新和对频繁参数进行小幅更新
s t = s t − 1 + g ( w t ) ⋅ g ( w t ) s_t=s_{t-1}+g(w_t)\cdot g(w_t) st=st−1+g(wt)⋅g(wt)
w t + 1 = w t − α s t + ε ⋅ g ( w t ) w_{t+1}=w_t-\frac{\alpha}{\sqrt{s_t+\varepsilon}}\cdot g(w_t) wt+1=wt−st+εα⋅g(wt)
其中, α \alpha α为学习率, g ( w t ) g(w_t) g(wt)为 t t t时刻对参数 w t w_t wt的损失梯度, ε ( 1 0 − 10 ) \varepsilon(10^{-10}) ε(10−10)为防止分母为零的小数
缺点:分母会不断积累,这样学习率急剧下降,最终会收缩变得非常小
PyTorch中AdaGrad的使用格式为:
torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0,initial_accumulator_value=0, eps=1e-10)
2.4 RMSProp(自适应学习率)
RMSProp
是对AdaGrad的改进,引入衰减系数,克服了AdaGrad算法中由于更新量变小而导致的学习进度停滞不前的问题
s t = ρ s t − 1 + ( 1 − ρ ) ⋅ g ( w t ) ⋅ g ( w t ) s_t=\rho s_{t-1}+(1-\rho)\cdot g(w_t)\cdot g(w_t) st=ρst−1+(1−ρ)⋅g(wt)⋅g(wt)
w t + 1 = w t − α s t + ε ⋅ g ( w t ) w_{t+1}=w_t-\frac{\alpha}{\sqrt{s_t+\varepsilon}}\cdot g(w_t) wt+1=wt−st+εα⋅g(wt)
其中, ρ ( 0.9 ) \rho(0.9) ρ(0.9)控制衰减速度, α \alpha α为学习率, g ( w t ) g(w_t) g(wt)为 t t t时刻对参数 w t w_t wt的损失梯度, ε ( 1 0 − 8 ) \varepsilon(10^{-8}) ε(10−8)为防止分母为零的小数
PyTorch中RMSProp的使用格式为:
torch.optim.RMSprop(params, lr=0.01, alpha=0.9, eps=1e-08, weight_decay=0, momentum=0, centered=False)
2.5 Adam(自适应学习率)
Adam
是一种学习速率自适应的深度神经网络方法,本质上是带有动量项的RMSProp,它利用梯度的一阶矩估计(一阶动量)和二阶矩估计(二阶动量)来动态调整每个参数的学习率除了像RMSProp一样存储了过去梯度的平方vt的指数衰减平均值,也像Momentum一样保持了过去梯度mt的指数衰减平均值
Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳
m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g ( w t ) m_t=\beta_1 \cdot m_{t-1}+(1-\beta_1) \cdot g(w_t) mt=β1⋅mt−1+(1−β1)⋅g(wt)
v t = β 2 ⋅ v t − 1 + ( 1 − β 2 ) ⋅ g ( w t ) ⋅ g ( w t ) v_t=\beta_2 \cdot v_{t-1}+(1-\beta_2) \cdot g(w_t) \cdot g(w_t) vt=β2⋅vt−1+(1−β2)⋅g(wt)⋅g(wt)
m ^ t = m t 1 − β 1 t \hat m_t=\frac{m_t}{1-\beta_1^t} m^t=1−β1tmt
v ^ t = v t 1 − β 2 t \hat v_t=\frac{v_t}{1-\beta_2^t} v^t=1−β2tvt
w t + 1 = w t − α v ^ t + ε m ^ t w_{t+1}=w_t-\frac{\alpha}{\sqrt {{\hat v_t}+\varepsilon}} \hat m_t wt+1=wt−v^t+εαm^t
其中, β 1 ( 0.9 ) \beta_1(0.9) β1(0.9)与 β 2 ( 0.999 ) \beta_2(0.999) β2(0.999)控制衰减速度, α \alpha α为学习率, g ( w t ) g(w_t) g(wt)为 t t t时刻对参数 w t w_t wt的损失梯度, ε ( 1 0 − 8 ) \varepsilon(10^{-8}) ε(10−8)为防止分母为零的小数
PyTorch中Adam的使用格式为:
torch.optim.Adam(params, lr=0.001, betas=(0.9,0.999), eps=1e-08, weight_decay=0, amsgrad=False, *, maximize=False)
2.6 对比
- AdaGrad相比SGD和Momentum更稳定,即不需要怎么调参
- 而精调的SGD和Momentum无论是收敛速度还是precision都比AdaGrad要好一些,其中Momentum又优于SGD
AdaGrad, RMSProp几乎很快就找到了正确的方向并前进,收敛速度也相当快,而其它方法要么很慢,要么走了很多弯路才找到