深度学习优化器对比--BGD/SGD/MBGD/MSGD/NAG/Adagrad/Adam

指数加权平均 (exponentially weighted averges)

先说一下指数加权平均, 公式如下:

v t = β v t − 1 + ( 1 − β ) θ t v_{t}=\beta v_{t-1}+(1-\beta) \theta_{t} vt=βvt1+(1β)θt

  • θ t \theta_t θt 是第t天的观测值
  • v t v_t vt 是用来替代 θ t \theta_t θt的估计值,也就是加权平均值
  • β \beta β 超参数

β = 0.9 \beta = 0.9 β=0.9 , 那么公式可以化简为:

v 100 = 0.1 ∗ θ t + 0.1 ∗ 0.9 ∗ θ 99 + 0.1 ∗ 0. 9 2 θ 98 + … + 0.1 ∗ 0. 9 99 θ 1 v_{100} = 0.1 * \theta_t + 0.1 * 0.9 * \theta_{99} + 0.1 * 0.9^{2} \theta_{98}+\ldots+0.1 * 0.9^{99} \theta_{1} v100=0.1θt+0.10.9θ99+0.10.92θ98++0.10.999θ1

它考虑到了之前所有观测值,但是事件越靠近的观测值权重越大,时间越久远的观测值权重就很小了。

β = 0.9 \beta = 0.9 β=0.9时,很多资料认为 0. 9 10 ≈ 0.35 ≈ 1 / e 0.9^{10} \approx 0.35 \approx 1 / e 0.9100.351/e, 把这个数当成一个分界点,权重降低到这个分界点之下就可以忽略不计,而 β 1 1 − β ≈ 1 / e \beta^{\frac{1}{1-\beta}} \approx 1 / e β1β11/e , 所以把上面两个公式合到一起就可以认为指数加权平均就是最近 N = 1 1 − β N=\frac{1}{1-\beta} N=1β1天的加权平均值

所以

  • β \beta β 越小, 加权平均的数据越少,就容易出现震荡
  • β \beta β 越大, 加权平均考虑的数据就越多,当出现震荡的时候会由于历史数据的权重导致震荡的幅度减小

Batch Gradient Descent (BGD)

BGD使用整个数据集来计算梯度,这里的损失函数是所有输入的样本数据的loss的和,单个样本的loss可以用交叉熵或者均方误差来计算。
θ = θ − η ⋅ ∇ θ J ( θ ) \theta=\theta-\eta \cdot \nabla_{\theta} J(\theta) θ=θηθJ(θ)
缺点是每次更新数据都需要计算整个数据集,速度很慢,不能实时的投入数据更新模型。对于凸函数可以收敛到全局最小值,对于非凸函数只能收敛到局部最小值。这是最朴素的优化器了

Stochastic Gradient Descent(SGD)

由于BGD计算梯度太过费时,SGD每次只计算一个样本的loss,然后更新参数。计算时可以先打乱数据,然后一条一条的将数据输入到模型中
θ = θ − η ⋅ ∇ θ J ( θ ; x ( i ) ; y ( i ) ) \theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i)} ; y^{(i)}\right) θ=θηθJ(θ;x(i);y(i))
他的缺点是更新比较频繁,会有严重的震荡。

当我们稍微减小learning rate, SGD和BGD的收敛性是一样的

Mini-Batch Gradient Descent (MBGD)

每次接收batch个样本,然后计算它们的loss的和。
θ = θ − η ⋅ ∇ θ J ( θ ; x ( i : i + n ) ; y ( i : i + n ) ) \theta=\theta-\eta \cdot \nabla_{\theta} J\left(\theta ; x^{(i: i+n)} ; y^{(i: i+n)}\right) θ=θηθJ(θ;x(i:i+n);y(i:i+n))

对于鞍点, BGD会在鞍点附近停止更新,而MSGD会在鞍点周围来回震荡。

Monentum SGD

加入了v的概念,起到一个类似惯性的作用。在更新梯度的时候会照顾到之前已有的梯度。这里的 v t v_t vt就是梯度的加权平均
v t = γ v t − 1 + η ∇ θ J ( θ ) θ = θ − v t \begin{array}{l} v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J(\theta) \\ \theta=\theta-v_{t} \end{array} vt=γvt1+ηθJ(θ)θ=θvt

它可以在梯度方向不变的维度上使速度变快,在梯度方向有所改变的维度上更新速度更慢,可以抵消某些维度的摆动,加快收敛并减小震荡。 γ \gamma γ一般取值为0.9

Nesterov Accelerated Gradient

它用 θ − γ v t − 1 \theta-\gamma v_{t-1} θγvt1来近似估计下一步 θ \theta θ会到达的位置
v t = γ v t − 1 + η ∇ θ J ( θ − γ v t − 1 ) θ = θ − v t \begin{array}{l} v_{t}=\gamma v_{t-1}+\eta \nabla_{\theta} J\left(\theta-\gamma v_{t-1}\right) \\ \theta=\theta-v_{t} \end{array} vt=γvt1+ηθJ(θγvt1)θ=θvt

能够让算法提前看到前方的地形梯度,如果前面的梯度比当前位置的梯度大,那我就可以把步子迈得比原来大一些,如果前面的梯度比现在的梯度小,那我就可以把步子迈得小一些

这个算法的公式竟然可以转化为下面的等价的公式:
d i = β d i − 1 + g ( θ i − 1 ) + β [ g ( θ i − 1 ) − g ( θ i − 2 ) ] θ i = θ i − 1 − α d i \begin{array}{l} d_{i}=\beta d_{i-1}+g\left(\theta_{i-1}\right)+\beta\left[g\left(\theta_{i-1}\right)-g\left(\theta_{i-2}\right)\right] \\ \theta_{i}=\theta_{i-1}-\alpha d_{i} \end{array} di=βdi1+g(θi1)+β[g(θi1)g(θi2)]θi=θi1αdi

后面的梯度相减可以认为是梯度的导数,也就是loss的二阶导数。也就是用二阶导数判断了一下曲线的趋势。其中 γ \gamma γ一般取值为0.9

Adagrad (Adaptive gradient algorithm)

可以对低频的参数做较大的更新,对高频的参数做较小的更新。

θ t + 1 , i = θ t , i − η G t , i i + ϵ ⋅ g t , i \theta_{t+1, i}=\theta_{t, i}-\frac{\eta}{\sqrt{G_{t, i i}+\epsilon}} \cdot g_{t, i} θt+1,i=θt,iGt,ii+ϵ ηgt,i

这个算法很有意思,G是在某个维度上,t从0开始到现在的所有梯度的平方和。所以对于经常更新的参数,学习率会越来越小,而对于不怎么更新的参数,他的学习率会变得相对更高。

θ \theta θ一般设置为0.01,他的缺点是分母会不断累计,最终学习率会变得非常小。如果初始梯度很大,会导致学习率变得很小。它适合用于稀疏数据。

Adadelta

对Adagrad的改进,对某个维度的历史维度进行平方、相加、开方

E [ g 2 ] t = ρ ∗ E [ g 2 ] t − 1 + ( 1 − ρ ) ∗ g t 2 E\left[g^{2}\right]_{t}=\rho * E\left[g^{2}\right]_{t-1}+(1-\rho) * g_{t}^{2} E[g2]t=ρE[g2]t1+(1ρ)gt2

x t + 1 = x t − η E [ g 2 ] t + ϵ ∗ g t x_{t+1}=x_{t}-\frac{\eta}{\sqrt{E\left[g^{2}\right]_{t}+\epsilon}} * g_{t} xt+1=xtE[g2]t+ϵ ηgt

R M S ( g t ) = E [ g 2 ] t + ϵ R M S\left(g_{t}\right)=\sqrt{E\left[g^{2}\right]_{t}+\epsilon} RMS(gt)=E[g2]t+ϵ

解决了历史梯度一直累加导致的学习率下降问题, ϵ \epsilon ϵ 是为了方式分母为0加上的极小值, r h o rho rho一般取值为0.9

Adaptive Moment Estimation (Adam)

同时考虑了梯度的平方和梯度的指数衰减。建议 β 1 \beta_1 β1=0.9, β 2 \beta_2 β2=0.999, η \eta η=10e-8

m t = β 1 m t − 1 + ( 1 − β 1 ) g t m_{t}=\beta_{1} m_{t-1}+\left(1-\beta_{1}\right) g_{t} mt=β1mt1+(1β1)gt

v t = β 2 v t − 1 + ( 1 − β 2 ) g t 2 v_{t}=\beta_{2} v_{t-1}+\left(1-\beta_{2}\right) g_{t}^{2} vt=β2vt1+(1β2)gt2

m ^ t = m t 1 − β 1 t , v ^ t = v t 1 − β 2 t \begin{array}{l} \hat{m}{t}=\frac{m{t}}{1-\beta_{1}^{t}}, \hat{v}{t}=\frac{v{t}}{1-\beta_{2}^{t}} \end{array} m^t=1β1tmt,v^t=1β2tvt

θ t + 1 = θ t − η v ^ t + ϵ m ^ t \theta_{t+1}=\theta_{t}-\frac{\eta}{\sqrt{\hat{v}_{t}}+\epsilon} \hat{m}_{t} θt+1=θtv^t +ϵηm^t

Adam取得了比其他方法更好的效果

总结

如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam。

参考资料:
https://www.cnblogs.com/guoyaohua/p/8542554.html
https://arxiv.org/pdf/1609.04747.pdf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值