ADADELTA

1. 现状:

大多数的梯度下降算法都需要选择学习率的超参数。设置学习率通常要不断调整,而较好的学习率一般是手动设置的。 学习率设置的过高会使得系统发散,但选择的过小又会使学习过程变慢。对于很多问题而言,选择一个好的学习率更像是艺术而不是科学。 

2. 解决问题:

引入新的“动态学习率”来减轻原先需要反复选择学习率的重复任务。这种方法在每个维度上计算时只需要一阶导数信息,并且在每次在梯度下降的迭代计算时只增加额外少量计算量。另外,这种方法用到了一些超参数,但是我们发现这些超参数的选择对结果影响不大。这种方法的优点如下:

  • 不需要人工设置学习率。
  • 对超参数不敏感。
  • 每维有单独的动态学习率。
  • 能减小梯度下降算法的计算量。
  • 对于大梯度、噪声和不同结构有较好的鲁棒性。

3. 相关工作ADAGRAD

优点

它有一个非常好的特性,就像一个二阶方法一样,它随着时间的推移在各个维度上的速度会趋于一致。这使得它非常适合训练深度网络,因为深度网络的不同层的梯度的尺度通常是不同数量级。因此,对于最优学习率应该考虑到这一点。此外,分母中的梯度和与退火算法有相同的效果,都会随着时间的推移减少学习率。

缺点

由于ADAGRAD没有考虑梯度的幅值,所以这种方法会对参数的初值和相对应的梯度敏感。如果初始梯度很大,在剩余的学习率将会变得很小。当然,可以通过增大全局学习率来解决这个问题,所以这使得ADAGRAD的学习率的选择变得很难。因为随着分母上梯度的平方不断积累,学习率会随着训练持续减小,最终会减小到零而导致训练停止。我们的ADADELTA方法有助于克服这种对超参数的选择的敏感性,同时能够避免学习率的持续下降。

4. ADADELTA 方法

该方法是基于ADAGRAD, 而且用于解决ADAGRAD的两个缺点,1) 随着训练学习率逐渐减小。2)需要人工选择全局学习率。 区别是在ADAGRAD方法中,分母从开始训练就对每一次迭代进行累加。每一个表达式都是正的,随着不断的累加,其和也不断的变大,使得每个维度上的学习率不断减小。多次迭代后,学习率会变得非常小。

不直接累加所有的梯度的平方,而是用一个宽度为w的窗口限制累加的历史梯度(即用w代替t,其中t指的是ADAGRAD中当前第t次迭代)。在窗口限制累加情况下,ADAGRAD中的分母就不会被累加到无穷大,这就变成了用最近几个的梯度来做局部预估。这就保证了若干次迭代之后学习能继续进行。 
因为直接存储w个梯度的平方率有些低,因此把求和换成梯度平方的均值,我们的方法与直接计算相比计算量指数下降。

假设在t时刻的平均值为E[g^2]_t ,然后我们计算: 

                                                                                             E[g^2]_t=\rho E[g^2]_{t-1}+(1-\rho)g^2 _t \tag{8}

其中ρ是下降常数,E[g^2]_t是同样宽为w的窗口下的梯度平方的期望值,和我们在动量方法中用的很像。在参数更新的时候我们需要计算出它的平方根,所以这就变成了求直到时间t前的梯度平方的均方根(RMS,root mean square): 

  

                                                                                              RMS[g]_t=\sqrt{E[g^2]_t+\epsilon} \tag{9}


至此,我们可以得出更新规则为: 

\Delta x_t =-\frac{\eta }{RMS\left [ g \right ]_{t}}

算法:

算法 1 计算ADADELTA在t+1时刻的值
需要:下降率ρ ,常数ϵ
需要:初始参数x1
  • 初始化求和变量E[g^2]_0=0,E[\Delta x^2]_0=0
for t=1:T
  • 计算梯度:g_t
  • 累加梯度:E[g^2]_t=\rho E[g^2]_{t-1}+(1-\rho)g^2_t
  • 计算更新值:\Delta x_t =-\frac{RMS[\Delta x]_{t-1}}{RMS[g]_t}g_t
  • 累加更新值:E[\Delta x^2]_t=\rho E[\Delta x^2]_{t-1}+(1-\rho)\Delta x^2_t
  • 应用更新:x_{t+1}=x_t +\Delta x_t
end for

Code:

%matplotlib inline
import gluonbook as gb
from mxnet import nd

features, labels = gb.get_data_ch7()

def init_adadelta_states():
    s_w, s_b = nd.zeros((features.shape[1], 1)), nd.zeros(1)
    delta_w, delta_b = nd.zeros((features.shape[1], 1)), nd.zeros(1)
    return ((s_w, delta_w), (s_b, delta_b))

def adadelta(params, states, hyperparams):
    rho, eps = hyperparams['rho'], 1e-5
    for p, (s, delta) in zip(params, states):
        s[:] = rho * s + (1 - rho) * p.grad.square()
        g = ((delta + eps).sqrt() / (s + eps).sqrt()) * p.grad
        p[:] -= g
        delta[:] = rho * delta + (1 - rho) * g * g

引用:

https://blog.csdn.net/cheny9505/article/details/54894728

动手学深度学习

原文:ADADELTA: AN ADAPTIVE LEARNING RATE METHOD

猜你喜欢

转载自blog.csdn.net/lovehello/article/details/84580273