数值计算梯度
问题是慢,每个都要注意做步长,求除法。
应该用求导方法解决。
SGD通过每次抽取一部分(mini-batch)来计算梯度,而不是遍历整个数据集来求梯度,大大增大了求梯度速度,并且性能不怎么受影响。
在GPU内存范围内,应尽可能扩大mini-batch大小。
概率视角:通过随机抽样mini-batch求出的梯度,在期望上等于用全部样本计算的梯度。
todo:
Multiclass SVM optimization demo (stanford.edu) 看明白这里面其中一步的计算:
下面这个图从上到下正视图、等高线图,也就是垂直方向梯度变化大,水平方向梯度变换缓
二维梯度计算代价大,实际上不怎么用(二维海参矩阵是
n
∗
n
n*n
n∗n的,并且求逆(invert)
O
(
n
3
)
O(n^3)
O(n3))
可能不太精准、形象的理解:
动量下降让下降不那么摇摆,但是容易冲过头然后回来;
Nesterov看下一步的走向,动量下降看当前走向,区别不大;
AdaGrad在梯度大时步子变小,梯度小时步子变大。问题是一直训练除的系数grad_squared变得很大,走到一半就停了;
RMSProp是加权的AdaGrad,限制了grad_squared的大小;
Adam结合了上述方法,并抑制了一开始的巨大变化。
提示:
Adam with beta1 = 0.9,
beta2 = 0.999, and learning_rate = 1e-3, 5e-4, 1e-4
is a great starting point for many models!
证明下图两个式子相等:
我们首先考虑第一个更新式子(取负梯度):
- v t + 1 = ρ v t − α g t v_{t+1} = \rho v_t - \alpha g_t vt+1=ρvt−αgt
- x t + 1 = x t + v t + 1 x_{t+1} = x_t + v_{t+1} xt+1=xt+vt+1
我们需要递归地展开 v t + 1 v_{t+1} vt+1 项。为了方便表示,我们将梯度项 g t g_t gt 表示为 g 1 , g 2 , … , g t g_1, g_2, \dots, g_t g1,g2,…,gt。现在我们来展开 v t + 1 v_{t+1} vt+1:
v
2
=
−
α
g
1
v_2 = -\alpha g_1
v2=−αg1
v
3
=
ρ
(
−
α
g
1
)
−
α
g
2
=
−
α
(
ρ
g
1
+
g
2
)
v_3 = \rho (-\alpha g_1) - \alpha g_2 = -\alpha (\rho g_1 + g_2)
v3=ρ(−αg1)−αg2=−α(ρg1+g2)
v
4
=
ρ
(
−
α
(
ρ
g
1
+
g
2
)
)
−
α
g
3
=
−
α
(
ρ
2
g
1
+
ρ
g
2
+
g
3
)
v_4 = \rho(-\alpha (\rho g_1 + g_2)) - \alpha g_3 = -\alpha (\rho^2 g_1 + \rho g_2 + g_3)
v4=ρ(−α(ρg1+g2))−αg3=−α(ρ2g1+ρg2+g3)
以此类推,我们可以得到:
v t + 1 = − α ( ρ t − 1 g 1 + ρ t − 2 g 2 + ⋯ + ρ g t − 1 + g t ) v_{t+1} = -\alpha (\rho^{t-1} g_1 + \rho^{t-2} g_2 + \dots + \rho g_{t-1} + g_t) vt+1=−α(ρt−1g1+ρt−2g2+⋯+ρgt−1+gt)
接下来,我们将 v t + 1 v_{t+1} vt+1 代入第二个更新式子:
x t + 1 = x t + v t + 1 = x t − α ( ρ t − 1 g 1 + ρ t − 2 g 2 + ⋯ + ρ g t − 1 + g t ) x_{t+1} = x_t + v_{t+1} = x_t - \alpha (\rho^{t-1} g_1 + \rho^{t-2} g_2 + \dots + \rho g_{t-1} + g_t) xt+1=xt+vt+1=xt−α(ρt−1g1+ρt−2g2+⋯+ρgt−1+gt)
现在我们考虑第二个更新式子(取正梯度):
- v t + 1 = ρ v t + g t v_{t+1} = \rho v_t + g_t vt+1=ρvt+gt
- x t + 1 = x t − α v t + 1 x_{t+1} = x_t - \alpha v_{t+1} xt+1=xt−αvt+1
我们同样需要递归地展开 v t + 1 v_{t+1} vt+1 项:
v
2
=
g
1
v_2 = g_1
v2=g1
v
3
=
ρ
g
1
+
g
2
v_3 = \rho g_1 + g_2
v3=ρg1+g2
v
4
=
ρ
(
ρ
g
1
+
g
2
)
+
g
3
=
ρ
2
g
1
+
ρ
g
2
+
g
3
v_4 = \rho (\rho g_1 + g_2) + g_3 = \rho^2 g_1 + \rho g_2 + g_3
v4=ρ(ρg1+g2)+g3=ρ2g1+ρg2+g3
以此类推,我们可以得到:
v t + 1 = ρ t − 1 g 1 + ρ t − 2 g 2 + ⋯ + ρ g t − 1 + g t v_{t+1} = \rho^{t-1} g_1 + \rho^{t-2} g_2 + \dots + \rho g_{t-1} + g_t vt+1=ρt−1g1+ρt−2g2+⋯+ρgt−1+gt
接下来,我们将 v t + 1 v_{t+1} vt+1 代入第二个更新式子:
x t + 1 = x t − α v t + 1 = x t − α ( ρ t − 1 g 1 + ρ t − 2 g 2 + ⋯ + ρ g t − 1 + g t ) x_{t+1} = x_t - \alpha v_{t+1} = x_t - \alpha (\rho^{t-1} g_1 + \rho^{t-2} g_2 + \dots + \rho g_{t-1} + g_t) xt+1=xt−αvt+1=xt−α(ρt−1g1+ρt−2g2+⋯+ρgt−1+gt)
现在我们可以看到,两个更新式子在数学上是等价的。
注意这个等价是全过程等价,如果只挑选其中一步是不同的。例如不能直接把这两个式子代换得到相同结果。