指数加权平均 (exponentially weighted averges)

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

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

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

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

v100=0.1∗θt+0.1∗0.9∗θ99+0.1∗0.92θ98+…+0.1∗0.999θ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.910≈0.35≈1/e0.9^{10} \approx 0.35 \approx 1 / e0.9100.351/e, 把这个数当成一个分界点,权重降低到这个分界点之下就可以忽略不计,而 β11−β≈1/e\beta^{\frac{1}{1-\beta}} \approx 1 / eβ1β11/e , 所以把上面两个公式合到一起就可以认为指数加权平均就是最近 N=11−β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的概念,起到一个类似惯性的作用。在更新梯度的时候会照顾到之前已有的梯度。这里的vtv_tvt就是梯度的加权平均
vt=γvt−1+η∇θJ(θ)θ=θ−vt \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

它用 θ−γvt−1\theta-\gamma v_{t-1}θγvt1来近似估计下一步 θ\thetaθ会到达的位置
vt=γvt−1+η∇θJ(θ−γvt−1)θ=θ−vt \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

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

这个算法的公式竟然可以转化为下面的等价的公式:
di=βdi−1+g(θi−1)+β[g(θi−1)−g(θi−2)]θi=θi−1−αdi \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−ηGt,ii+ϵ⋅gt,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[g2]t=ρ∗E[g2]t−1+(1−ρ)∗gt2 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

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

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

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

Adaptive Moment Estimation (Adam)

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

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

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

m^t=mt1−β1t,v^t=vt1−β2t \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

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐