Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
d2l-zh
提交
978e98d4
D
d2l-zh
项目概览
OpenDocCN
/
d2l-zh
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
d2l-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
978e98d4
编写于
8月 08, 2018
作者:
M
muli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update momuntom
上级
e84dac4c
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
83 addition
and
36 deletion
+83
-36
chapter_optimization/momentum.md
chapter_optimization/momentum.md
+83
-36
未找到文件。
chapter_optimization/momentum.md
浏览文件 @
978e98d4
...
...
@@ -6,18 +6,59 @@
## 梯度下降的问题
给定目标函数,在梯度下降中,自变量的迭代方向仅仅取决于自变量当前位置。这可能会带来一些问题。
给定目标函数,在梯度下降中,自变量的迭代方向仅仅取决于自变量当前位置。这可能会带来一些问题。
考虑一个输入和输出分别为二维向量$
\b
oldsymbol{x} = [x_1, x_2]^
\t
op$和标量的目标函数$f(
\b
oldsymbol{x})=0.1x_1^2+2x_2$。下面我们观察梯度下降是如何执行的。首先,导入本节中实验所需的包或模块。
考虑一个输入和输出分别为二维向量$
\b
oldsymbol{x} = [x_1, x_2]^
\t
op$和标量的目标函数$f:
\m
athbb{R}^2
\r
ightarrow
\m
athbb{R}$。图7.2展示了该函数的等高线示意图。
```
{.python .input}
import sys
sys.path.insert(0, '..')
![
目标函数$f$的等高线图和自变量$[x_1, x_2]$在梯度下降中的迭代。每条等高线(椭圆实线)代表所有函数值相同的自变量的坐标。实心圆代表自变量初始坐标。每个箭头头部代表自变量在每次迭代后的坐标。
](
../img/gd-move.svg
)
%matplotlib inline
import gluonbook as gb
from mxnet import autograd, nd
import numpy as np
```
接下来我们实现梯度下降和图示函数。跟上一小节不同在于输入有两个维度,在作图中我们不是换出函数曲线而是等高线。然后我们演示了使用学习率$
\e
ta=0.9$时的更新轨迹。
```
{.python .input}
f = lambda x1, x2: 0.1*x1**2 + 2*x2**2
f_grad = lambda x1, x2: (0.2*x1, 2*x2)
def gd(eta):
x1, x2 = -5, -2
res = []
for i in range(15):
gx1, gx2 = f_grad(x1, x2)
x1 = x1 - eta * gx1
x2 = x2 - eta * gx2
res.append((x1, x2))
return res
def show(res):
x1, x2 = zip(*res)
gb.set_figsize((3.5, 2.5))
gb.plt.plot(x1, x2, '-o')
x1 = np.arange(-5.0, 1.0, .1)
x2 = np.arange(min(-3.0, min(x2)-1), max(3.0, max(x2)+1), .1)
x1, x2 = np.meshgrid(x1, x2)
gb.plt.contour(x1, x2, f(x1, x2), colors='g')
gb.plt.xlabel('x1')
gb.plt.ylabel('x2')
show(gd(.9))
```
由于目标函数在竖直方向(
$x_2$轴方向)比在水平方向($x_1$轴方向)更弯曲,给定学习率,梯度下降迭代自变量时会使自变量在竖直方向比在水平方向移动幅度更大。因此,我们需要一个较小的学习率从而避免自变量在竖直方向上越过目标函数最优解。然而,这造成了图7.2中自变量向最优解移动较慢
。
由于目标函数在竖直方向(
x2轴)比在水平方向(x1轴)更弯曲,可以看到在竖直方向比在水平方向移动幅度更大。因此,我们需要一个较小的学习率从而避免自变量在竖直方向上越过目标函数最优解。然而,这造成自变量向最优解移动较慢。如果使用稍微大一点的学习率$
\e
ta=1.1$,可以看到在竖直上发散了
。
```
{.python .input}
show(gd(1.1))
```
## 动量法
动量法的提出是为了应对梯度下降的上述问题。
广义上,以小批量随机梯度下降为例(当批量大小等于训练集样本数时,该算法即为梯度下降;批量大小为1时即为随机梯度下降),我们对小批量随机梯度算法在
每次迭代的步骤做如下修改:
动量法的提出是为了应对梯度下降的上述问题。
以小批量随机梯度下降为例,动量法对
每次迭代的步骤做如下修改:
$$
...
...
@@ -27,13 +68,36 @@ $$
\e
nd{aligned}
$$
其中$
\b
oldsymbol{v}$是速度变量,动量超参数$
\g
amma$满足$0
\l
eq
\g
amma
\l
eq 1$。动量法中的学习率$
\e
ta$和有关小批量$
\m
athcal{B}$的随机梯度$
\n
abla f_
\m
athcal{B}(
\b
oldsymbol{x})$已在
[
“梯度下降和随机梯度下降”
](
gd-sgd.md
)
一节中描述。
在解释其原理前让我们从实验中观察是否动量法解决了之前的问题。
```
{.python .input n=77}
def momentum(eta, mom):
x, y = -5, -2
res = []
v_x, v_y = 0, 0
for i in range(15):
gx, gy = f_grad(x, y)
v_x = mom * v_x + eta * gx
v_y = mom * v_y + eta * gy
x = x - v_x
y = y - v_y
res.append((x, y))
return res
show(momentum(0.9, .2))
```
可以看到使用$
\e
ta=0.9$和动量参数$
\g
amma=0.2$,动量法在垂直方向上更加平滑,且加速了水平方向的进度。使用更大的$
\e
ta=1.1$也不会使得收敛发散。
```
{.python .input}
show(momentum(1.1, .2))
```
### 指数加权移动平均
为了
更清晰地
理解动量法,让我们先解释指数加权移动平均(exponentially weighted moving average)。给定超参数$
\g
amma$且$0
\l
eq
\g
amma < 1$,当前时刻$t$的变量$y^{(t)}$是上一时刻$t-1$的变量$y^{(t-1)}$和当前时刻另一变量$x^{(t)}$的线性组合:
为了
数学上
理解动量法,让我们先解释指数加权移动平均(exponentially weighted moving average)。给定超参数$
\g
amma$且$0
\l
eq
\g
amma < 1$,当前时刻$t$的变量$y^{(t)}$是上一时刻$t-1$的变量$y^{(t-1)}$和当前时刻另一变量$x^{(t)}$的线性组合:
$$y^{(t)} =
\g
amma y^{(t-1)} + (1-
\g
amma) x^{(t)}.$$
...
...
@@ -68,39 +132,13 @@ $$\boldsymbol{v} \leftarrow \gamma \boldsymbol{v} + (1 - \gamma) \frac{\eta \nab
由指数加权移动平均的形式可得,速度变量$
\b
oldsymbol{v}$实际上对$(
\e
ta
\n
abla f_
\m
athcal{B}(
\b
oldsymbol{x})) /(1-
\g
amma)$做了指数加权移动平均。给定动量超参数$
\g
amma$和学习率$
\e
ta$,含动量法的小批量随机梯度下降可被看作使用了特殊梯度来迭代目标函数的自变量。这个特殊梯度是最近$1/(1-
\g
amma)$个时刻的$
\n
abla f_
\m
athcal{B}(
\b
oldsymbol{x})/(1-
\g
amma)$的加权平均。
给定目标函数,在动量法的每次迭代中,自变量在各个方向上的移动幅度不仅取决当前梯度,还取决过去各个梯度在各个方向上是否一致。图7.3展示了使用动量法的梯度下降迭代图7.2中目标函数自变量的情景。我们将每个梯度代表的箭头方向在水平方向和竖直方向做分解。由于所有梯度的水平方向为正(向右)、在竖直上时正(向上)时负(向下),自变量在水平方向移动幅度逐渐增大,而在竖直方向移动幅度逐渐减小。这样,我们就可以使用较大的学习率,从而使自变量向最优解更快移动。
![
目标函数$f$的等高线图和自变量$[x_1, x_2]$在使用动量法的梯度下降中的迭代。每条等高线(椭圆实线)代表所有函数值相同的自变量的坐标。实心圆代表自变量初始坐标。每个箭头头部代表自变量在每次迭代后的坐标。
](
../img/momentum-move.svg
)
## 动量法的实现
动量法的实现也很简单。我们在小批量随机梯度下降的基础上添加速度变量。
```
{.python .input n=1}
def sgd_momentum(params, vs, lr, mom, batch_size):
for param, v in zip(params, vs):
v[:] = mom * v + lr * param.grad / batch_size
param[:] -= v
```
给定目标函数,在动量法的每次迭代中,自变量在各个方向上的移动幅度不仅取决当前梯度,还取决过去各个梯度在各个方向上是否一致。在上面示例中,由于所有梯度的水平方向为正(向右)、在竖直上时正(向上)时负(向下),自变量在水平方向移动幅度逐渐增大,而在竖直方向移动幅度逐渐减小。这样,我们就可以使用较大的学习率,从而使自变量向最优解更快移动。
## 实验
首先,导入本节中实验所需的包或模块
。
实验中,我们以之前介绍过的线性回归为例。设数据集的样本数为1000,我们使用权重
`w`
为[2, -3.4],偏差
`b`
为4.2的线性回归模型来生成数据集。模型的平方损失函数即所需优化的目标函数,模型参数即目标函数自变量
。
```
{.python .input}
import sys
sys.path.insert(0, '..')
%matplotlib inline
import gluonbook as gb
from mxnet import autograd, nd
import numpy as np
```
实验中,我们以之前介绍过的线性回归为例。设数据集的样本数为1000,我们使用权重
`w`
为[2, -3.4],偏差
`b`
为4.2的线性回归模型来生成数据集。该模型的平方损失函数即所需优化的目标函数,模型参数即目标函数自变量。
```
{.python .input n=2}
```
{.python .input n=69}
# 生成数据集。
num_inputs = 2
num_examples = 1000
...
...
@@ -123,6 +161,15 @@ def init_params():
return params, vs
```
动量法的实现也很简单。我们在小批量随机梯度下降的基础上添加速度变量。
```
{.python .input}
def sgd_momentum(params, vs, lr, mom, batch_size):
for param, v in zip(params, vs):
v[:] = mom * v + lr * param.grad / batch_size
param[:] -= v
```
优化函数
`optimize`
与
[
“梯度下降和随机梯度下降”
](
gd-sgd.md
)
一节中的类似。
```
{.python .input n=3}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录