1. Weakness of Gradient Descent
如果使用交叉熵来作为LOSS的话,GD可以表述为:
−
∑
i
=
1
n
y
i
⋅
(
l
o
g
2
y
^
)
+
(
1
−
y
i
)
l
o
g
2
(
1
−
y
^
)
n
\frac{-\sum_{i=1}^{n}{y_i\cdot(log_2\,\hat{y})+(1-y_i)log_2\,(1-\hat{y})}}{n}
n−∑i=1nyi⋅(log2y^)+(1−yi)log2(1−y^)
显而易见,GD需要对样本的所有数据进行求和,在深度学习中数据总量是很大的,并且每个样本的维度也是极大的,何况我们不止进行一次优化,往往需要多次优化而逼近最优化,这样的计算在实践上是无法进行的。
这也是为什么反向传播和GD在上世纪七八十年代被提出来,而并未在工程上有很大成就的原因。
2. Optimization ideas
- 每次优化的计算量太大,能不能减少每次优化的训练量?
- 需要很多次的计算才能慢慢逼近最优化,能不能减少逼近的次数?
2.1 Reduce calculated amount
2.1.1 SGD
注意到我们求的LOSS,其实本质上和样本是无关的,这样说可能有点抽象。在(1)式中,我们其实求的是样本的交叉熵的期望,期望往往是反映总体的某个attribution,与样本是无关的,取一个样本求期望也能得到这个attribution,取N个样本求期望也能得到,二者之间的区别不过是精度。
举个例子,我想知道全国人的收入平均水平(期望),我其实并不需要把全国每个人的收入统计,我只需要抽取一部分即可,这一部分人的平均值(期望)其实能大差不差反映出总体的期望。
而如果若我仅仅抽取一个人,在数学上其实并没有什么问题,但是精度差的很远很远。
由此,SGD(stochastic gradient descent,随机梯度下降)被提出。并且已经过数学证明,其精度不会太低于GD。
2.2 Optimize descent path
既然梯度已经是LOSS下降最快的方向了,那下降路径还有优化空间吗?
我们知道每一次GD都是计算一个点的梯度,如果我们要将整个最优的下降路径描述出来,那么每一次迭代的步长需要无限小,而无限小很显然是无法实现的,那么我们在工程上也就无法找到最优的下降路径,因此也就出现了优化空间。
2.2.1 NewTon method
上述情况下,蓝色代表的是最优下降路径,显然,在步长比较小的时候,切线还是和最优化路径逼近的(在步长等于无穷小的时候,是与最优化路径相同的);但当步长比较长的时候,差距就很大了。
发现如果使用二次曲线来逼近的话,当步长为 △ x \triangle{x} △x的时候,逼近的效果是最好的。
而这种方法便是Newton Method的直观解释。
Newton Method的思路是运用迭代点的梯度信息和二阶导数对目标函数进行二次函数逼近。
J
(
x
)
≈
J
(
a
0
)
+
J
′
(
a
0
)
+
1
2
J
′
′
(
a
0
)
(
x
−
a
0
)
2
J(x)\approx J(a_0)+J'(a_0)+\frac{1}{2}J''(a_0)(x-a_0)^2
J(x)≈J(a0)+J′(a0)+21J′′(a0)(x−a0)2
其中
a
0
a_0
a0为迭代点。
由于抛物线在顶点的时候,他的学习效果是最优的。因此
f
′
(
x
)
f'(x)
f′(x)求极值,令
f
′
(
x
)
=
0
f'(x)=0
f′(x)=0
f
′
(
x
)
=
J
′
(
a
0
)
+
J
′
′
(
a
0
)
(
x
−
a
0
)
f'(x) = J'(a_0)+J''(a_0)(x-a_0)
f′(x)=J′(a0)+J′′(a0)(x−a0)
x
=
a
0
−
J
′
(
a
0
)
J
′
′
(
a
0
)
x = a_0-\frac{J'(a_0)}{J''(a_0)}
x=a0−J′′(a0)J′(a0)
通过(4)式,我们可以带入迭代式
W
=
W
−
J
′
(
W
)
J
′
′
(
W
)
W = W - \frac{J'(W)}{J''(W)}
W=W−J′′(W)J′(W)
我们注意到这里是没有学习率的,因为牛顿法只有在步长为 △ x \triangle{x} △x的时候学习效果才是最好的。
上图中,橙色线是GD的结果,绿色线是Newton Method的结果,很显然,牛顿法更趋向于最优化路径。
在拓展到高维度,牛顿法可以写成:
W
=
W
−
∇
2
J
(
W
)
−
1
⋅
∇
J
(
W
)
W = W - \nabla^2J(W)^{-1}\cdot \nabla J(W)
W=W−∇2J(W)−1⋅∇J(W)
其中
∇
2
J
(
W
)
\nabla^2J(W)
∇2J(W)是Hessian矩阵,计算量非常大。因此可以看出Newton Method确实可以逼近更好的逼近最优化路径,但是其计算代价太大了。
2.2.2 Momentum Method
考虑一个二维输入,输出的损失函数 L : R 2 → R L:\mathbb{R}^2\rightarrow \mathbb{R} L:R2→R,下面为损失函数的等高线。
对于GD来说,更新的速度取决于gradient和learningRate。
我们将二维的梯度分解成水平和垂直两个分量,很显然对于GD来说,在两个维度上的learningRate是相同的,对于这种情况来说,由于垂直分量的gradient变化非常大,在总体上就会出现震荡的情况。
如何去避免’震荡‘这种情况,而使其更快的达到极值点呢?
很显然,我们希望加速水平分量,减速垂直分量。
动量法的提出就是为了应对这个问题,我们对GD做一个修改:
V
t
=
β
V
t
−
1
+
(
1
−
β
)
∇
W
(
t
)
i
,
其中
∇
W
(
t
)
i
=
∂
J
(
W
(
t
−
1
)
i
)
∂
W
i
W
t
=
W
t
−
1
−
η
⋅
V
t
V_t = β\,V_{t-1}+(1-β)\nabla W_{(t)i}\,\,\,,其中\nabla W_{(t)i} = \frac{\partial J(W_{(t-1)i})}{\partial W_i} \\ W_t = W_{t-1}-η\cdot V_t
Vt=βVt−1+(1−β)∇W(t)i,其中∇W(t)i=∂Wi∂J(W(t−1)i)Wt=Wt−1−η⋅Vt
我们将GD中的gradient改变为带有历史条件的V,这里的V是一个递归的定义,当训练到t次的时候,这里的V是前面t-1次训练的加权和。
这里β的加入运用了数学上的一个方法——指数加权移动平均法。如果加入β,在步数很多的时候,前面的所有历史数据都会被加入,这样明显是不合适的。这样越在前面离得越远的数据,其对 V t V_t Vt的影响越小。
这种方法类似于物理学上的动量——以前的改变是有惯性的,要想发生改变,必须先将其抵消。因此这种方法被称为是动量法。
动量梯度下降能加快收敛,但是也存在问题,在很接近optimum的时候,很容易刹不住车而过头。
2.2.3 Nesterov
Nesterov相当于在动量法的基础上添加了一个校正因子,可以利用未来的信息来调整当前的方向,从而加速收敛并减少振荡。
其相对于Momentum Method的修改是在
∇
W
(
t
)
i
\nabla W_{(t)i}
∇W(t)i上进行的。
∇
W
(
t
)
i
=
∂
J
(
W
(
t
−
1
)
i
+
γ
V
(
t
−
1
)
)
∂
W
i
\nabla W_{(t)i} = \frac{\partial J(W_{(t-1)i}+\gamma V_{(t-1)})}{\partial W_i}
∇W(t)i=∂Wi∂J(W(t−1)i+γV(t−1))
用通俗一点的话来说,其实就是用下一跳跃点(当前点加上速度的点)的梯度和当前点的速度来更新这个点的参数。
直观分析可知,这种方法会比Momentum Method更快收敛;同时在另一方面,当其接近optimum的时候,当前点的速度是向前的,而下一跳跃点的梯度是向后的,有助于减缓速度从而使其不容易冲过头。
但是Nesterov方法,需要先根据当前速度项(动量项,V)预测下一位置,然后再在这个位置计算梯度,再根据这个梯度更新参数。这就导致两次梯度计算而增加计算代价。
2.2.1-3 Summary
在此我们可以小结一下。
上述三种方法,他们的思路其实都是改进梯度的方向从而使其更”实用“。
Newton Method是将各个维度整体考虑,直接给出一个对于在宏观上更合理的方向。
Momentum Method是将各个维度分开。引入“惯性”的思想,利用历史条件——”速度“来改进梯度的方向。
而Nesterov则是在Momentum Method基础之上增加一次梯度的计算,增加对未来的考量。
上述我们的方法都是通过“改进梯度的方向”而实现的,回到GD最根本的公式。
W
=
W
−
μ
∇
L
W = W - μ\nabla L
W=W−μ∇L
在公式中,μ作为学习率在之前的算法中都是一个恒定值。
我们试想一个情景,在逼近一个目标的过程中,我们是不是都会采用先跨大步,再迈小步的方法。而在这里,学习率是一个常数是反直觉的,我们想,学习率μ能不能随着逼近的过程逐步变化呢?
2.2.4 AdaGrad
AdaGrad 的也是引入历史的思想,将每一个参数的每一次迭代的梯度取平方累加后在开方,用全局学习率除以这个数,作为学习率的动态更新。对于不同的参数动态的采取不同的学习率,让目标函数更快的收敛。
W
(
t
)
i
=
W
(
t
−
1
)
i
−
μ
S
(
t
)
+
ε
⋅
∇
W
(
t
−
1
)
i
其中
,
S
(
t
)
=
S
(
t
−
1
)
+
∇
W
(
t
−
1
)
i
⋅
∇
W
(
t
−
1
)
i
,
ε
是极小数保证分母不为
0
W_{(t)i}=W_{(t-1)i}-\frac{μ}{\sqrt{S_{(t)}+\varepsilon}}\cdot \nabla W_{(t-1)i}\\ 其中,S_{(t)} = S_{(t-1)}+ \nabla W_{(t-1)i}\cdot \nabla W_{(t-1)i}, \varepsilon是极小数保证分母不为0
W(t)i=W(t−1)i−S(t)+εμ⋅∇W(t−1)i其中,S(t)=S(t−1)+∇W(t−1)i⋅∇W(t−1)i,ε是极小数保证分母不为0
其中注意到一点,其也是和Momentum Method和Nesterov一样采用将维度分开的方法,他对每个分量(参数)进行修正,梯度大的则学习率大(修正的也多),而梯度小的则对应小的学习率(修正的也少)。
对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。因此,Adagrad 非常适用于稀疏数据。
优点:
-
在稀疏数据场景表现的特别好
由于维度灾难的存在,稀疏数据在实际应用场景下出现的频率非常大!
-
自适应学习率算法
缺点:
- S ( t ) + ε \sqrt{S_{(t)}+\varepsilon} S(t)+ε是不断累加、单调递增的,会使得学习率很快递减至0。
2.2.5 RMSProp
由于AdaGrad单调递减的学习率变化过于激进,我们考虑一种与之前动量法类似的策略:不积累全部的历史梯度,只关心过去一段时间窗口的下降梯度。
而RMSProp正是使用了此策略,改变梯度积累为指数加权的移动平均值,以此丢弃距离较远的历史梯度信息。
S
(
t
)
=
β
S
(
t
−
1
)
+
(
1
−
β
)
∇
W
(
t
−
1
)
i
⋅
∇
W
(
t
−
1
)
i
W
(
t
)
i
=
W
(
t
−
1
)
i
−
μ
S
(
t
)
+
ε
⋅
∇
W
(
t
−
1
)
i
S_{(t)} = \beta S_{(t-1)}+(1-\beta)\nabla W_{(t-1)i}\cdot \nabla W_{(t-1)i}\\ W_{(t)i}=W_{(t-1)i}-\frac{μ}{\sqrt{S_{(t)}+\varepsilon}}\cdot \nabla W_{(t-1)i}
S(t)=βS(t−1)+(1−β)∇W(t−1)i⋅∇W(t−1)iW(t)i=W(t−1)i−S(t)+εμ⋅∇W(t−1)i
2.2.1-5 Summary
在此我们再次小结一下。
1-3 优化的是梯度的方向。
4-5 优化的是学习率。
两者的优化策略是不同的,因此我们可以将其结合在一起使用。
2.6 Adam
Adam = Adaptive + Momentum
顾名思义,adam是在SGD的基础上将动量和自适应学习率结合在一起来加快收敛速度,优化descent path。
具体就不多解释了,其在很多情况下算作默认工作性能比较优秀的优化器。