在11.4节中,我们详述了如何执行随机梯度下降,即在只有嘈杂的梯度可用的情况下执行优化时会发生什么。 对于嘈杂的梯度,我们在选择学习率需要格外谨慎。 如果衰减速度太快,收敛就会停滞。 相反,如果太宽松,我们可能无法收敛到最优解。

基础
在本节中,我们将探讨更有效的优化算法,尤其是针对实验中常见的某些类型的优化问题。

泄漏平均值
上一节中我们讨论了小批量随机梯度下降作为加速计算的手段。 它也有很好的副作用,即平均梯度减小了方差。 小批量随机梯度下降可以通过以下方式计算:

gt,t−1=∂w1∣Bt∣∑i∈Btf(xi,wt−1)=1∣Bt∣∑i∈Bthi,t−1. (11.6.1)\mathbf{g}{t, t-1} = \partial{\mathbf{w}} \frac{1}{|\mathcal{B}t|} \sum{i \in \mathcal{B}t} f(\mathbf{x}{i}, \mathbf{w}_{t-1}) = \frac{1}{|\mathcal{B}t|} \sum{i \in \mathcal{B}t} \mathbf{h}{i, t-1}.~~~~~~~~~~(11.6.1)
g
t,t−1

=∂
w

∣B
t


1

i∈B
t



f(x
i

,w
t−1

)=
∣B
t


1

i∈B
t



h
i,t−1

. (11.6.1)

为了保持记法简单,在这里我们使用hi,t−1=∂wf(xi,wt−1)\mathbf{h}{i, t-1} = \partial{\mathbf{w}} f(\mathbf{x}i, \mathbf{w}{t-1})h
i,t−1

=∂
w

f(x
i

,w
t−1

)作为样本iii的随机梯度下降,使用时间t−1t-1t−1时更新的权重t−1t-1t−1。 如果我们能够从方差减少的影响中受益,甚至超过小批量上的梯度平均值,那很不错。 完成这项任务的一种选择是用泄漏平均值(leaky average)取代梯度计算:

vt=βvt−1+gt,t−1 (11.6.2)\mathbf{v}t = \beta \mathbf{v}{t-1} + \mathbf{g}_{t, t-1}~~~~~~~~~~(11.6.2)
v
t

=βv
t−1

+g
t,t−1

(11.6.2)

其中β∈(0,1)\beta \in (0, 1)β∈(0,1)。 这有效地将瞬时梯度替换为多个“过去”梯度的平均值。 v\mathbf{v}v被称为动量(momentum), 它累加了过去的梯度。 为了更详细地解释,让我们递归地将vt\mathbf{v}_tv
t

扩展到

vt=β2vt−2+βgt−1,t−2+gt,t−1=…,=∑τ=0t−1βτgt−τ,t−τ−1. (11.6.3)\begin{aligned} \mathbf{v}t = \beta^2 \mathbf{v}{t-2} + \beta \mathbf{g}{t-1, t-2} + \mathbf{g}{t, t-1} = \ldots, = \sum_{\tau = 0}^{t-1} \beta^{\tau} \mathbf{g}_{t-\tau, t-\tau-1}. \end{aligned}~~~~~~~~~~(11.6.3)
v
t


2
v
t−2

+βg
t−1,t−2

+g
t,t−1

=…,=
τ=0

t−1

β
τ
g
t−τ,t−τ−1

.

(11.6.3)

其中,较大的β\betaβ相当于长期平均值,而较小的β\betaβ相对于梯度法只是略有修正。 新的梯度替换不再指向特定实例下降最陡的方向,而是指向过去梯度的加权平均值的方向。 这使我们能够实现对单批量计算平均值的大部分好处,而不产生实际计算其梯度的代价。

上述推理构成了"加速"梯度方法的基础,例如具有动量的梯度。 在优化问题条件不佳的情况下(例如,有些方向的进展比其他方向慢得多,类似狭窄的峡谷),"加速"梯度还额外享受更有效的好处。 此外,它们允许我们对随后的梯度计算平均值,以获得更稳定的下降方向。 诚然,即使是对于无噪声凸问题,加速度这方面也是为什么动量如此起效的关键原因之一。

正如人们所期望的,由于其功效,动量是深度学习及其后优化中一个深入研究的主题。 例如,请参阅文章,观看深入分析和互动动画。 动量是由Polyak.1964提出的。 Nesterov.2018在凸优化的背景下进行了详细的理论讨论。 长期以来,深度学习的动量一直被认为是有益的。 有关实例的详细信息,请参阅Sutskever.Martens.Dahl.ea.2013的讨论。

条件不佳的问题
为了更好地了解动量法的几何属性,我们复习一下梯度下降。 回想我们在11.3节中使用了f(x)=x12+2x22f(\mathbf{x}) = x_1^2 + 2 x_2^2f(x)=x
1
2

+2x
2
2

,即中度扭曲的椭球目标。 我们通过向x1x_1x
1

方向伸展它来进一步扭曲这个函数

f(x)=0.1x12+2x22. (11.6.4)f(\mathbf{x}) = 0.1 x_1^2 + 2 x_2^2.~~~~~~~~~~(11.6.4)
f(x)=0.1x
1
2

+2x
2
2

. (11.6.4)

与之前一样,fff在(0,0)(0, 0)(0,0)有最小值, 该函数在x1x_1x
1

的方向上非常*平坦。 让我们看看在这个新函数上执行梯度下降时会发生什么。

In [ ]
%matplotlib inline
from d2l import paddle as d2l
import paddle

eta = 0.4
def f_2d(x1, x2):
return 0.1 * x1 ** 2 + 2 * x2 ** 2
def gd_2d(x1, x2, s1, s2):
return (x1 - eta * 0.2 * x1, x2 - eta * 4 * x2, 0, 0)

d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))
从构造来看,x2x_2x
2

方向的梯度比水平x1x_1x
1

方向的梯度大得多,变化也快得多。 因此,我们陷入两难:如果选择较小的学习率,我们会确保解不会在x2x_2x
2

方向发散,但要承受在x1x_1x
1

方向的缓慢收敛。相反,如果学习率较高,我们在x1x_1x
1

方向上进展很快,但在x2x_2x
2

方向将会发散。 下面的例子说明了即使学习率从0.40.40.4略微提高到0.60.60.6,也会发生变化。 x1x_1x
1

方向上的收敛有所改善,但整体来看解的质量更差了。

In [ ]
eta = 0.6
d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))
动量法
动量法(momentum)使我们能够解决上面描述的梯度下降问题。 观察上面的优化轨迹,我们可能会直觉到计算过去的平均梯度效果会很好。 毕竟,在x1x_1x
1

方向上,这将聚合非常对齐的梯度,从而增加我们在每一步中覆盖的距离。 相反,在梯度振荡的x2x_2x
2

方向,由于相互抵消了对方的振荡,聚合梯度将减小步长大小。 使用vt\mathbf{v}_tv
t

而不是梯度gt\mathbf{g}_tg
t

可以生成以下更新等式:

vt←βvt−1+gt,t−1,xt←xt−1−ηtvt. (11.6.5)\begin{aligned} \mathbf{v}t &\leftarrow \beta \mathbf{v}{t-1} + \mathbf{g}_{t, t-1}, \ \mathbf{x}t &\leftarrow \mathbf{x}{t-1} - \eta_t \mathbf{v}_t. \end{aligned}~~~~~~~~~~(11.6.5)
v
t

x
t

←βv
t−1

+g
t,t−1

,
←x
t−1

−η
t

v
t

.

(11.6.5)

请注意,对于β=0\beta = 0β=0,我们恢复常规的梯度下降。 在深入研究它的数学属性之前,让我们快速看一下算法在实验中的表现如何。

In [ ]
def momentum_2d(x1, x2, v1, v2):
v1 = beta * v1 + 0.2 * x1
v2 = beta * v2 + 4 * x2
return x1 - eta * v1, x2 - eta * v2, v1, v2

eta, beta = 0.6, 0.5
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))
正如所见,尽管学习率与我们以前使用的相同,动量法仍然很好地收敛了。 让我们看看当降低动量参数时会发生什么。 将其减半至β=0.25\beta = 0.25β=0.25会导致一条几乎没有收敛的轨迹。 尽管如此,它比没有动量时解将会发散要好得多。

In [ ]
eta, beta = 0.6, 0.25
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))
请注意,我们可以将动量法与随机梯度下降,特别是小批量随机梯度下降结合起来。 唯一的变化是,在这种情况下,我们将梯度gt,t−1\mathbf{g}_{t, t-1}g
t,t−1

替换为gt\mathbf{g}_tg
t

。 为了方便起见,我们在时间t=0t=0t=0初始化v0=0\mathbf{v}_0 = 0v
0

=0。

有效样本权重
回想一下vt=∑τ=0t−1βτgt−τ,t−τ−1\mathbf{v}t = \sum{\tau = 0}^{t-1} \beta^{\tau} \mathbf{g}{t-\tau, t-\tau-1}v
t

=∑
τ=0
t−1

β
τ
g
t−τ,t−τ−1

。 极限条件下,∑τ=0∞βτ=11−β\sum
{\tau=0}^\infty \beta^\tau = \frac{1}{1-\beta}∑
τ=0


β
τ

1−β
1

。 换句话说,我们测中处理可能潜在表现会更好的下降方向。 为了说明β\betaβ的不同选择的权重效果如何,请参考下面的图表。

In [ ]
d2l.set_figsize()
betas = [0.95, 0.9, 0.6, 0]
for beta in betas:
x = d2l.arange(40).detach().numpy()
d2l.plt.plot(x, beta ** x, label=f’beta = {beta:.2f}')
d2l.plt.xlabel(‘time’)
d2l.plt.legend();
实际实验
让我们来看看动量法在实验中是如何运作的。 为此,我们需要一个更加可扩展的实现。

从零开始实现
相比于小批量随机梯度下降,动量方法需要维护一组辅助变量,即速度。 它与梯度以及优化问题的变量具有相同的形状。 在下面的实现中,我们称这些变量为states。

In [ ]
def init_momentum_states(feature_dim):
v_w = d2l.zeros((feature_dim, 1))
v_b = d2l.zeros((1,))
return (v_w, v_b)
In [ ]
def sgd_momentum(params, states, hyperparams):
a = []
for p, v in zip(params, states):
with paddle.no_grad():
v[:] = hyperparams[‘momentum’] * v + p.grad
p[:] -= hyperparams[‘lr’] * v
p.grad.zero_()
a.append§
return a
让我们看看它在实验中是如何运作的。

In [ ]
def train_momentum(lr, momentum, num_epochs=2):
d2l.train_ch11(sgd_momentum, init_momentum_states(feature_dim),
{‘lr’: lr, ‘momentum’: momentum}, data_iter,
feature_dim, num_epochs)

data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
train_momentum(0.02, 0.5)
当我们将动量超参数momentum增加到0.9时,它相当于有效样本数量增加到11−0.9=10\frac{1}{1 - 0.9} = 10
1−0.9
1

=10。 我们将学习率略微降至0.010.010.01,以确保可控。

In [ ]
train_momentum(0.01, 0.9)
降低学习率进一步解决了任何非平滑优化问题的困难,将其设置为0.0050.0050.005会产生良好的收敛性能。

In [ ]
train_momentum(0.005, 0.9)
简洁实现
由于深度学习框架中的优化求解器早已构建了动量法,设置匹配参数会产生非常类似的轨迹。

In [ ]
trainer = paddle.optimizer.Momentum
d2l.train_concise_ch11(trainer, {‘learning_rate’: 0.005, ‘momentum’: 0.9}, data_iter)
理论分析
f(x)=0.1x12+2x22f(x) = 0.1 x_1^2 + 2 x_2^2f(x)=0.1x
1
2

+2x
2
2

的2D示例似乎相当牵强。 下面我们将看到,它在实际生活中非常具有代表性,至少最小化凸二次目标函数的情况下是如此。

二次凸函数
考虑这个函数

h(x)=12x⊤Qx+x⊤c+b. (11.6.6)h(\mathbf{x}) = \frac{1}{2} \mathbf{x}^\top \mathbf{Q} \mathbf{x} + \mathbf{x}^\top \mathbf{c} + b.~~~~~~~~~~(11.6.6)
h(x)=
2
1

x

Qx+x

c+b. (11.6.6)

这是一个普通的二次函数。 对于正定矩阵Q≻0\mathbf{Q} \succ 0Q≻0,即对于具有正特征值的矩阵,有最小化器为x∗=−Q−1c\mathbf{x}^* = -\mathbf{Q}^{-1} \mathbf{c}x

=−Q
−1
c,最小值为b−12c⊤Q−1cb - \frac{1}{2} \mathbf{c}^\top \mathbf{Q}^{-1} \mathbf{c}b−
2
1

c

Q
−1
c。 因此我们可以将hhh重写为

h(x)=12(x−Q−1c)⊤Q(x−Q−1c)+b−12c⊤Q−1c. (11.6.7)h(\mathbf{x}) = \frac{1}{2} (\mathbf{x} - \mathbf{Q}^{-1} \mathbf{c})^\top \mathbf{Q} (\mathbf{x} - \mathbf{Q}^{-1} \mathbf{c}) + b - \frac{1}{2} \mathbf{c}^\top \mathbf{Q}^{-1} \mathbf{c}.~~~~~~~~~~(11.6.7)
h(x)=
2
1

(x−Q
−1
c)

Q(x−Q
−1
c)+b−
2
1

c

Q
−1
c. (11.6.7)

梯度由∂xf(x)=Q(x−Q−1c)\partial_{\mathbf{x}} f(\mathbf{x}) = \mathbf{Q} (\mathbf{x} - \mathbf{Q}^{-1} \mathbf{c})∂
x

f(x)=Q(x−Q
−1
c)给出。 也就是说,它是由x\mathbf{x}x和最小化器之间的距离乘以Q\mathbf{Q}Q所得出的。 因此,动量法还是Q(xt−Q−1c)\mathbf{Q} (\mathbf{x}_t - \mathbf{Q}^{-1} \mathbf{c})Q(x
t

−Q
−1
c)的线性组合。

由于Q\mathbf{Q}Q是正定的,因此可以通过Q=O⊤ΛO\mathbf{Q} = \mathbf{O}^\top \boldsymbol{\Lambda} \mathbf{O}Q=O

ΛO分解为正交(旋转)矩阵O\mathbf{O}O和正特征值的对角矩阵Λ\boldsymbol{\Lambda}Λ。 这使我们能够将变量从x\mathbf{x}x更改为z:=O(x−Q−1c)\mathbf{z} := \mathbf{O} (\mathbf{x} - \mathbf{Q}^{-1} \mathbf{c})z:=O(x−Q
−1
c),以获得一个非常简化的表达式:

h(z)=12z⊤Λz+b′. (11.6.8)h(\mathbf{z}) = \frac{1}{2} \mathbf{z}^\top \boldsymbol{\Lambda} \mathbf{z} + b’.~~~~~~~~~~(11.6.8)
h(z)=
2
1

z

Λz+b

. (11.6.8)

这里b′=b−12c⊤Q−1cb’ = b - \frac{1}{2} \mathbf{c}^\top \mathbf{Q}^{-1} \mathbf{c}b

=b−
2
1

c

Q
−1
c。 由于O\mathbf{O}O只是一个正交矩阵,因此不会真正意义上扰动梯度。 以z\mathbf{z}z表示的梯度下降变成

zt=zt−1−Λzt−1=(I−Λ)zt−1. (11.6.9)\mathbf{z}t = \mathbf{z}{t-1} - \boldsymbol{\Lambda} \mathbf{z}{t-1} = (\mathbf{I} - \boldsymbol{\Lambda}) \mathbf{z}{t-1}.~~~~~~~~~~(11.6.9)
z
t

=z
t−1

−Λz
t−1

=(I−Λ)z
t−1

. (11.6.9)

这个表达式中的重要事实是梯度下降在不同的特征空间之间不会混合。 也就是说,如果用Q\mathbf{Q}Q的特征系统来表示,优化问题是以逐坐标顺序的方式进行的。 这在动量法中也适用。

vt=βvt−1+Λzt−1zt=zt−1−η(βvt−1+Λzt−1)=(I−ηΛ)zt−1−ηβvt−1. (11.6.10)\begin{aligned} \mathbf{v}t & = \beta \mathbf{v}{t-1} + \boldsymbol{\Lambda} \mathbf{z}{t-1} \ \mathbf{z}t & = \mathbf{z}{t-1} - \eta \left(\beta \mathbf{v}{t-1} + \boldsymbol{\Lambda} \mathbf{z}{t-1}\right) \ & = (\mathbf{I} - \eta \boldsymbol{\Lambda}) \mathbf{z}{t-1} - \eta \beta \mathbf{v}_{t-1}. \end{aligned}~~~~~~~~~~(11.6.10)
v
t

z
t

=βv
t−1

+Λz
t−1

=z
t−1

−η(βv
t−1

+Λz
t−1

)
=(I−ηΛ)z
t−1

−ηβv
t−1

.

(11.6.10)

在这样做的过程中,我们只是证明了以下定理:带有和带有不凸二次函数动量的梯度下降,可以分解为朝二次矩阵特征向量方向坐标顺序的优化。

标量函数
鉴于上述结果,让我们看看当我们最小化函数f(x)=λ2x2f(x) = \frac{\lambda}{2} x^2f(x)=
2
λ

x
2
时会发生什么。 对于梯度下降我们有

xt+1=xt−ηλxt=(1−ηλ)xt. (11.6.11)x_{t+1} = x_t - \eta \lambda x_t = (1 - \eta \lambda) x_t.~~~~~~~~~~(11.6.11)
x
t+1

=x
t

−ηλx
t

=(1−ηλ)x
t

. (11.6.11)

每∣1−ηλ∣<1|1 - \eta \lambda| < 1∣1−ηλ∣<1时,这种优化以指数速度收敛,因为在ttt步之后我们可以得到xt=(1−ηλ)tx0x_t = (1 - \eta \lambda)^t x_0x
t

=(1−ηλ)
t
x
0

。 这显示了在我们将学习率η\etaη提高到ηλ=1\eta \lambda = 1ηλ=1之前,收敛率最初是如何提高的。 超过该数值之后,梯度开始发散,对于ηλ>2\eta \lambda > 2ηλ>2而言,优化问题将会发散。

In [ ]
lambdas = [0.1, 1, 10, 19]
eta = 0.1
d2l.set_figsize((6, 4))
for lam in lambdas:
t = d2l.arange(20).detach().numpy()
d2l.plt.plot(t, (1 - eta * lam) ** t, label=f’lambda = {lam:.2f}')
d2l.plt.xlabel(‘time’)
d2l.plt.legend();
为了分析动量的收敛情况,我们首先用两个标量重写更新方程:一个用于xxx,另一个用于动量vvv。这产生了:

[vt+1xt+1]=[βλ−ηβ(1−ηλ)][vtxt]=R(β,η,λ)[vtxt]. (11.6.12)\begin{bmatrix} v_{t+1} \ x_{t+1} \end{bmatrix} = \begin{bmatrix} \beta & \lambda \ -\eta \beta & (1 - \eta \lambda) \end{bmatrix} \begin{bmatrix} v_{t} \ x_{t} \end{bmatrix} = \mathbf{R}(\beta, \eta, \lambda) \begin{bmatrix} v_{t} \ x_{t} \end{bmatrix}.~~~~~~~~~~(11.6.12)
[
v
t+1

x
t+1


]=[
β
−ηβ

λ
(1−ηλ)

][
v
t

x
t


]=R(β,η,λ)[
v
t

x
t


]. (11.6.12)

我们用R\mathbf{R}R来表示2×22 \times 22×2管理的收敛表现。 在ttt步之后,最初的值[v0,x0][v_0, x_0][v
0

,x
0

]变为R(β,η,λ)t[v0,x0]\mathbf{R}(\beta, \eta, \lambda)^t [v_0, x_0]R(β,η,λ)
t
[v
0

,x
0

]。 因此,收敛速度是由R\mathbf{R}R的特征值决定的。 请参阅文章Goh.2017了解精彩动画。 请参阅Flammarion.Bach.2015了解详细分析。 简而言之,当0<ηλ<2+2β0 < \eta \lambda < 2 + 2 \beta0<ηλ<2+2β时动量收敛。 与梯度下降的0<ηλ<20 < \eta \lambda < 20<ηλ<2相比,这是更大范围的可行参数。 另外,一般而言较大值的β\betaβ是可取的。

小结
动量法用过去梯度的平均值来替换梯度,这大大加快了收敛速度。
对于无噪声梯度下降和嘈杂随机梯度下降,动量法都是可取的。
动量法可以防止在随机梯度下降的优化过程停滞的问题。
由于对过去的数据进行了指数降权,有效梯度数为11−β\frac{1}{1-\beta}
1−β
1


在凸二次问题中,可以对动量法进行明确而详细的分析。
动量法的实现非常简单,但它需要我们存储额外的状态向量(动量v\mathbf{v}v)。
练习
使用动量超参数和学习率的其他组合,观察和分析不同的实验结果。
试试梯度下降和动量法来解决一个二次问题,其中你有多个特征值,即f(x)=12∑iλixi2f(x) = \frac{1}{2} \sum_i \lambda_i x_i^2f(x)=
2
1


i

λ
i

x
i
2

,例如λi=2−i\lambda_i = 2^{-i}λ
i

=2
−i
。绘制出xxx的值在初始化xi=1x_i = 1x
i

=1时如何下降。
推导h(x)=12x⊤Qx+x⊤c+bh(\mathbf{x}) = \frac{1}{2} \mathbf{x}^\top \mathbf{Q} \mathbf{x} + \mathbf{x}^\top \mathbf{c} + bh(x)=
2
1

x

Qx+x

c+b的最小值和最小化器。
当我们执行带动量法的随机梯度下降时会有什么变化?当我们使用带动量法的小批量随机梯度下降时会发生什么?试验参数如何?
如果想系统性学习该项目,可前往“动手学AI”课程(https://aistudio.baidu.com/aistudio/course/introduce/25851)查看完整章节

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐