深度学习中常见的优化算法比较

SGD

Basic SGD

the baisc sgd is:

# Vanilla update
x += - learning_rate * dx

Momentum Update

Momentum update 是一种几乎总会加快收敛速度的方法. 这种方法据说是物理学中某个理论的启发. 类比SGD, 其中loss 可以类比为一座山的高度, 参数的出书画过程类似于在这个山坡上面设置一个初始速度为0的点, 那么优化过程可以看做这个初始点在该山坡上面滚动的过程.

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

这里我们引入一个新的变量 v, 并且该变量的初始值为0, 以及变量mu, mu 在优化中被称为 momentum(也许这个名称不合适, 但是是历史原因了). mu 一般设置为0.9. 从物理的角度讲, mu 更类似于摩擦力的系数. 有时候, 也会使用变化的momentum, 一般是随着优化过程的进行, 逐渐增大mu, 典型的方法是初始momentum设置为0.5, 然后逐渐增加到0.99左右.

With Momentum update, the parameter vector will build up velocity in any direction that has consistent gradient.

Nesterov Momentum

Nesterov Momentum 是最近比较流行的一种与传统的momentum update稍有不同的方法, Nesterov Momentum 在凸优化中有较强的理论保证收敛, 并且,在实践中, Nesterov Momentum也几乎重视比传统的Momentum的效果要好. 其过程为:

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

然而,在实践中, 为了类似于vanilla SGD, 一般会做一步变量转换工作, x_ahead = x + mu * v, 从而, 使用x_ahead描述优化过程. 所以, 优化过程变为:

v_prev = v # back this up
v = mu * v - learning_rate * dx # velocity update stays the same
x += -mu * v_prev + (1 + mu) * v # position update changes form

Annealing the Learning Rate

Step decay 每隔几个epoch减少一次learning rate, 一般是每运行5个epoch左右把learning rate减少一半, 或者是每隔20个epoch减少为原来的1/10. 然而,具体的learning rate 的调整方法还是要看网络的设计和模型. 另外, 还有一种方法是, 在训练的过程中观察training error和validation error, 当validation error不再减小的时候, 减小learning rate.

Exponential decay 的数学描述是 α=α0ektα=α0e−kt, 其中 α0,kα0,k 是超参数, tt 是迭代次数.

1/t decay 的数学描述是α=α01+ktα=α01+kt 其中 (α0,k(α0,k) 是超参数, tt 是迭代次数.

Per-parameter adaptive learning rate methods

上面讨论过的所有的方法都是所有的参数都使用相同的调整策略. 调整learning rate的代价一般比较高, 因此, 有很多探索自动调整learning rate的工作, 另外也有一些工作是分别调整每一个参数的更新方法. 这些方法仍然需要超参数, 但是, 这种方法对于超参数的的设置不像传统的方法那么敏感. 这里我们介绍几种实践中常用的方法.

AdaDelta

pass

AdaGrad

pass

# Assume the gradient dx and parameter vector x
cache += dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

cache 的大小和gradient的大小相同, 记录的是每个参数的梯度的平方和. 之后,cache 用来以element-wise的方式normalize参数的更新. 从上面的代码中可以看出, 梯度较高的权重的有效learning rate会减小, 相应的梯度较低的权重的有效learning rate会增大. 这里, 让人感到比较搞笑的是, sqrt 操作非常重要,如果没有sqrt操作, 该算法的效果非常糟糕. eps 是smooth 操作,一般设置为 10410−4  10810−8 之间,从而可以避免除0错误(这种方法,在CNN中训练中极为常见, 比如在batch normalization中也是通过这种方法避免出现除0的错误). Adagrad的一个缺点是,在深度学习中,the monotonic learning rate usually proves too aggressive, 因此常常过早结束了学习过程.

Adam

Adam 是最近提出的一种算法, 该算法和(下面将要介绍的)带有momentum的RMSprop比较类似, 过程类似于:

m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += - learning_rate * m / (np.sqrt(v) + eps)

该方法和RMSProp唯一的区别是”smooth”过程, 这里使用的是m来做smooth操作, 而不是使用原始的gradient vector dx. 论文中推荐的超参数为eps=1e-6, bata1=0.9, beta2=0.999, 在实践中, 如果没有其他的特殊理由,一般推荐使用Adam方法, 并且, Adam算法通常会比RMSProp算法效果好. 另外,也可以尝试SGD+Nesterov Momentum. 完整的Adam算法中还包括bias的纠正机制, 这事因为,在刚开始的几个steps中,m和v都要初始化, 并且在warm up 之前他们都biased at zero. 更多的细节可以参考论文原文.

RMSProp

RMSProp是一个非常高效的算法,但是目前并没有发表. RMSProp通过一种非常简单的方法更新参数.

cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)

decay_rate 是超参数, 一般可以设置为0.9,0.99,0.9990.9,0.99,0.999. 其中, x+= 操作和Adagrad完全相同, 但是, 变量cache是leaky的,所以, RMSProp 仍然根据每个权重的gradient来调整learning rate.

本文链接 http://ask.5lulu.com/viewblog/p2n2e6jpip825d.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值