原文链接《Adam:A Method for Stochastic Optimization》
前沿知识
普通更新
最简单的沿着负梯度方向改变参数(梯度指向的是上升方向,但要最小化损失函数)。假设有一个参数向量x及其梯度dx,那么最简单的更新的形式是:
x += - learning_rate * dx
其中,learning_rate是一个超参数,它是一个固定常量。当在整个数据集上进行计算时,只要学习率足够低,总是能在损失函数上得到非负的进展。
动量(Momentum)更新
v = mu * v - learning_rate * dx # 与速度融合
x += v # 与位置融合
在这里引入了一个初始=0的 变量v 和一个超参数mu。
变量 mu 在最优化的过程中被看做动量(一般值设为0.9),但其物理意义与摩擦系数更一致。这个变量有效地抑制了速度,降低了系统的动能,不然质点在山底永远不会停下来。
通过交叉验证,mu通常设为[0.5,0.9,0.95,0.99]中的一个。和学习率随着时间退火(下文有讨论)类似,动量随时间变化能略微效果,其中动量在学习过程的后阶段会上升。一个典型的设置是刚开始0.5,多个周期(epoch)中慢慢提升到0.99。
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.999]。
x+=和Adagrad中是一样的,但是cache变量是不同的。因此,RMSProp仍然是基于梯度的大小来对每个权重的学习率进行修改,这同样效果不错。但其更新不会让学习率单调变小。
Adam
原文算法为: