优化器简述

以常用的PyTorch实现的为主,近两年的未考虑;理解均为个人口述,不保证合理性,建议参考原始paper。

顺序:SGD->momentum->nesterov->AdaGrad->RMSProp->RMSProp with nesterov->Adam

SGD

基本的SGD

param = param + (-lr * grad)

特点: lr不好选择; 不容易收敛,可能受困于鞍点

momentum

加了动量,记录了一阶梯度的历史信息

v = momentum * v + (-grad)
param = param + lr * v

特点: 初期方向一致,加速优化,中期振荡容易跳出陷阱,同时抑制振荡

nesterov

另一版本的动量,应当使用预测后的参数的梯度进行计算

new_param = param + momentum * v
grad = grad_of(new_param)
v = momentum * v + (-grad)
param = param + lr * v

特点: 梯度在进行大的跳跃后进行校正;考虑v字形状,能够稳定振荡次数; 一种合理的解释是其引入了二阶导信息,参考这里

AdaGrad

出现自适应学习率,记录二阶梯度历史信息,其越大就应当使其学习率更低

r = r + grad @ grad (@ = element-wise dot)
v = -1 / (sqrt(r) + eps) @ grad
param = param + lr * v

特点: 能够自动约束梯度更新速率,但是累加会越来越大使得grad->0,从而提前结束训练;善于处理稀疏梯度

RMSProp

不应当无脑引入历史二阶信息,应当添加系数使得更加关注当前信息; 由Adam可知这里是有偏的

r = ro * r + (1 - ro) * (grad @ grad)
v = -1 / (sqrt(r + eps)) @ grad
param = param + lr * v

特点:善于处理非平稳目标

RMSProp with nesterov

RMSProp直接使用梯度,实际我们使用动量作为其替代品也是ok的

new_param = param + momentum * v
grad = grad_of(new_param)
r = ro * r + (1 - ro) * (grad @ grad)
v = momentum * v + (-1) / (sqrt(r + eps)) @ grad
param = param + lr * v

Adam

RMSProp引入momentum动量的版本, 同时加了参数约束使得其无偏

v = momentum(alias: ro1) * v + (1 - ro1) * grad
r = ro2 * r + (1 - ro2) * grad @ grad
new_v = v / (1 - ro1^step) | WHY? | -> E(v_t) = ro1*E(v_(t-1)) + (1-ro1)*E(grad) -> E(v_t) = (1-ro1^t)*E(grad) 
new_r = r / (1 - ro2^step) | WHY? | -> Refer: https://www.zhihu.com/question/325651810
param = param + (-lr) * new_v / (sqrt(new_r) + eps)

特点:经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。

posted @ 2020-04-23 15:34  暗影卫队  阅读(309)  评论(1)    收藏  举报