几种常见的参数更新方式
1) SGD
x += - learning_rate * dx
2) Momentum update
# Momentum update
v = mu * v - learning_rate * dx # integrate velocity
x += v # integrate position
3) Nesterov Momentum
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
推理比较麻烦,需要查看详细记录。
4) Adagrad(adaptive gradient)自适应
通常,我们在每一次更新参数时,对于所有的参数使用相同的学习率。而AdaGrad算法的思想是:每一次更新参数时(一次迭代),不同的参数使用不同的学习率。AdaGrad 的公式为:
G
t
=
G
t
−
1
+
g
t
2
θ
t
+
1
=
θ
t
−
α
G
t
+
ε
∗
g
t
G_t = G_{t-1}+g_t^2\\ \theta_{t+1}=\theta_t-\frac{\alpha}{\sqrt{G_t}+\varepsilon}*g_t
Gt=Gt−1+gt2θt+1=θt−Gt+εα∗gt
# Assume the gradient dx and parameter vector x
cache += dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)
由于是累积梯度的平方,到后面 G t G_t Gt累积的比较大,会导致学习率 α G t + ε \frac{\alpha}{\sqrt{G_t+\varepsilon}} Gt+εα→0,导致梯度消失。
5) RMSprop
改进了Adagrad的缺点。不会让学习率降为零。
RMSprop使用指数加权平均(指数衰减平均)只保留过去给定窗口大小的梯度,使其能够在找到凸碗状结构后快速收敛。
cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)
6) Adam
RMSProp with momentum
下面是一般形式
m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += - learning_rate * m / (np.sqrt(v) + eps)
由于刚开始m值不准确,需要校正,于是使用下面的式子。
# t is your iteration counter going from 1 to infinity
m = beta1*m + (1-beta1)*dx
mt = m / (1-beta1**t)
v = beta2*v + (1-beta2)*(dx**2)
vt = v / (1-beta2**t)
x += - learning_rate * mt / (np.sqrt(vt) + eps)
总结
本文只简单的写出了更新的相关代码,以备遗忘时快速查找。
相关的公式和推理参考:
另一位博主的详细记录