梯度下降优化算法总结
WARNING
UNDER CONSTRUCTION
背景
回顾一下,现实中我们有了数据集 D={(x(1),y(1)),⋯,(x(m),y(m))},也定义了损失函数 ℓ:Y×Y→R,我们想要寻找一个假设函数 h(其所有参数由 θ 表示),which 能最小化经验误差:
θminE(θ;D),where E(θ;D)=m1i=1∑mℓ(h(x(i);θ),y(i)).
这个优化问题就可以用梯度下降来解决
θ′=θ−η⋅g
其中 η 为学习率 (learning rate),g=∇θE(θ) 为梯度(方便起见,下文将经验误差 E 简记为 f)
假设当前时刻的神经网络权值为 θt,经过梯度下降更新后为 θt+1,引入如下标记
- 原始梯度 gt=∇θf(θt)
- 权值更新量 ut(与学习率无关),满足 θt+1=θt−η⋅ut
很显然,对于随机梯度下降 (SGD) 来说,ut=gt,即 θt+1=θt−η⋅gt
TODO
- 一阶动量 mt
- 二阶动量 vt
full GD vs. mini-batch GD
朴素
挑战
- 选择学习率
- 选择学习率 scheduler
- 如果数据稀疏或特征频率不同(?),我们想给不常出现的特征更大的 update
- 局部极小值
SGD
utθt+1=gt=θt−η⋅ut.
SGD with momentum
——引入一阶动量
gtm0mtutθt+1=∇θf(θt)=g0=γ⋅mt−1+gt=mt=θt−η⋅ut.
可见一阶动量 mt 即为历史梯度的指数移动平均 (exponential moving average),其权重 γ 常取 0.9
- 优点:有助于加速优化过程(跨过平坦区域,平滑震荡的梯度)
- 缺点:可能冲出最小值区域,「停不下来」(TODO)
NOTE
上述 SGD with Momentum 的公式为 PyTorch 中的实现方式 (opens new window),与论文略有不同,其学习率 η 是乘在梯度 g 上而不是动量 mt 上,即
mtθt+1=γ⋅mt−1+η⋅gt=θt−mt.
对于固定的学习率 η 两者是等价的(对动量权重 γ 进行缩放即可),而考虑到网络实际训练时往往需要动态调节学习率 (lr schedule),前者在改变学习率的时候不会影响动量 mt 的计算。
下文统一采用与 PyTorch 一致的写法。
SGD with Nesterov accelerated gradient (NAG)
gtm0g~tmtutθt+1=∇θf(θt)=g0=∇θf(θt−γ⋅mt−1)=γ⋅mt−1+g~t=mt=θt−η⋅ut.
PyTorch
gtm0mtutθt+1=∇θf(θt)=g0=γ⋅mt−1+gt=γ⋅mt+ut−1=θt−η⋅ut.
Adagrad
——引入二阶动量。自适应学习率 优化算法的到来
gt,i=∇f(θt,i).
(θt+1,i=θt,i−η⋅gt,i)
θt+1,i=θt,i−Gt,ii+ϵη⋅gt,i
Gt
Adadelta
RMSprop
Adam
——Adaptive Moment Estimation 同时使用一阶动量与二阶动量
(AdaMax, Nadam, AMSGrad)
阅读材料
总览:
Momentum/NAG:
- https://towardsdatascience.com/adam-latest-trends-in-deep-learning-optimization-6be9a291375c
- https://blog.christianperone.com/2020/11/optimization-deep-learning/