参数更新

学习率(一阶)

初始值通常设置在1e-3,在学习过程中随着时间降低学习率通常很有用,

降低学习率的方式有:

  • 递减step decay

每几个epoch降低一次,如每5次降低一半,或每20次降低0.1,视情况而定.可以通过尝试不同的固定的学习率对验证集的错误率进行观察来找合适的学习率.

  • 指数下降

\(\alpha = \alpha_0 e^{-k t}\),t是迭代次数,其它是超参数.

  • 1/t下降

\(\alpha = \alpha_0 / (1 + k t )\)

实际中step decay更常用一些,因为参数更容易解释,更直观.无非是设置较小的递减速率,训练更长的时间.

权重更新方法(一阶)

Vanilla update

(vanilla作为形容词,意思是普通的,平凡的) 沿着负梯度方向更新参数以最小化损失.

1
2
# Vanilla update,learning_rate是超参数
x += - learning_rate * dx

Momentum update

比上述的GD方式收敛速度快:

1
2
3
# Momentum update
v = mu * v - learning_rate * dx # integrate velocity
x += v # integrate position

其中变量v初始值为0,mu是一个超参数,称为动量(momentum),常用值是0.9.

对其进行调优可以从0.5作为初始值,再依次尝试[0.9, 0.95, 0.99],(模拟退火的过程). 形象的解释为:重力作用使其震荡的幅度减小,加速下降。 ### Nesterov Momentum

比上面的momentum更新方式表现的更好一些,改进之处在于将计算梯度的位置x转移到了动量更新之后:

1
2
3
4
x_ahead = x + mu * v
# evaluate dx_ahead (the gradient at x_ahead instead of at x)
v = mu * v - learning_rate * dx_ahead
x += v

Nesterov's Accelerated Momentum (NAG)

效果更好,进一步阅读:

AdaGrad

v += dx^2 x += - learning_rate * dx/sqrt(v) 是在学习率上进行调整,相当于由于一次性移动dx太大而加的惩罚,增加对震荡的阻力。

RMSProp

结合了Momentum与AdaGrad: v = mu * v + (1-mu) * dx^2 x += - learning_rate * dx/sqrt(v)

Adam

RMSProp + momentum 在RMSProp中没有完全运用Momentum,继续修改后变为: m = mu1 * m + (1-mu1) * dx v = mu2 * v + (1-mu2) * dx^2 x += - learning_rate * m/sqrt(v)

Eve

Adam的扩展,根据最近的损失的振荡情况,调整学习率.

二阶方法 Second order methods

前面讨论的方法都是一阶方法(first order),更有效的方法是基于牛顿法: \[ x \leftarrow x - [H f(x)]^{-1} \nabla f(x) \] 收敛速度更快,并且不需要超参数.然而计算Hessian矩阵的逆在时间和空间复杂度都非常高,太不切实际.因此出现了许多变种方法(quasi-Newton methods)来计算近似的逆矩阵值.如方法 L-BFGS,(缺点是必须在整个训练集上计算,如何让其在mini-batches上工作是当前比较活跃的研究领域)

额外参考文献:

  • Large Scale Distributed Deep Networks is a paper from the Google Brain team, comparing L-BFGS and SGD variants in large-scale distributed optimization.
  • SFO algorithm strives to combine the advantages of SGD with advantages of L-BFGS.

梯度下降 Gradient Descent

以线性回归为例:

hyposis: \(h_\theta(x)=\sum_{j=0}^n \theta_jx_j\)

m是样本的总数,n是参数\(\theta\)的总数.

Batch gradient descent

总体loss: \(J_{\text{train}}(\theta)={1\over 2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2\)

一次梯度下降所做的操作如下,重复迭代多次: \[ \theta_j:=\theta_j-\alpha{\partial\over\partial\theta_j}J_{\text{train}}(\theta) \tag{for j=1,...,n} \]

Stochastic Gradient Descent (SGD)

单个元素的loss: \(cost(\theta,(x^{(i)},y^{(i)}))={1\over 2}(h_\theta(x^{(i)})-y^{(i)})^2\)

  1. 对训练样本随机打乱顺序

  2. 重复如下的梯度下降:

for i=1,...,m{

\(\theta_j:=\theta_j-\alpha{\partial\over\partial\theta_j}cost(\theta,(x^{(i)},y^{(i)})) \tag{for j=1,...,n}\)

}

由于一次只使用一个样本,因此多了一层循环.但是实践中很少使用,因为优化的向量运算比单个处理快。有时人们把SGD指代Mini-batch Gradient Descent(因为通常mini-batch的选择是随机的)。

与Batch gradient descent相比,其收敛的曲线可能比较振荡.

Mini‐batch Gradient Descent

每次计算梯度只使用训练集的一小部分,常见的mini-batch大小是32/64/128(优化的向量).例如,ILSVRC ConvNet使用256个样例.

设b是mini-batch的样本数,融合Batch gradient descent与Stochastc gradient descent的思想,重复如下的梯度下降:

for i=1,1+b,1+2b,...,~m{

\(\theta_j:=\theta_j-\alpha{1\over b}\sum_{k=i}^{i+b}{\partial\over\partial\theta_j}cost(\theta,(x^{(k)},y^{(k)})) \tag{for j=1,...,n}\)

}

通过向量化的计算方式,其可能比Stochastc gradient descent计算速度更快.

文章目录
  1. 1. 学习率(一阶)
  2. 2. 权重更新方法(一阶)
    1. 2.1. Vanilla update
    2. 2.2. Momentum update
    3. 2.3. Nesterov's Accelerated Momentum (NAG)
    4. 2.4. AdaGrad
    5. 2.5. RMSProp
    6. 2.6. Adam
    7. 2.7. Eve
  3. 3. 二阶方法 Second order methods
  4. 4. 梯度下降 Gradient Descent
    1. 4.1. Batch gradient descent
    2. 4.2. Stochastic Gradient Descent (SGD)
    3. 4.3. Mini‐batch Gradient Descent
,