Skip to content

Commit

Permalink
add numerical stability and init
Browse files Browse the repository at this point in the history
  • Loading branch information
astonzhang committed Sep 10, 2018
1 parent 61d6551 commit 5618b8d
Show file tree
Hide file tree
Showing 7 changed files with 488 additions and 8 deletions.
2 changes: 1 addition & 1 deletion chapter_convolutional-neural-networks/resnet.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 残差网络(ResNet)

让我们先思考一个问题:对神经网络模型添加新的层,充分训练后的模型是否只可能更有效地降低训练误差?理论上,原模型解的空间只是新模型解的空间的子空间。也就是说,如果我们能将新添加的层训练成恒等映射(identity mapping)$f(x) = x$,新模型和原模型将同样有效。由于新模型可能得出更优的解来拟合训练数据集,添加层似乎有益而无害。然而在实践中,添加过多的层后训练误差不降反升,即使使用了批量归一化提供数值稳定性使得训练深层模型更加容易,但这个问题仍然存在。针对这一问题,何恺明等人提出了残差网络(ResNet) [1]。它在2015年的ImageNet图像识别挑战赛夺魁,并深刻影响了后来的深度神经网络的设计。
让我们先思考一个问题:对神经网络模型添加新的层,充分训练后的模型是否只可能更有效地降低训练误差?理论上,原模型解的空间只是新模型解的空间的子空间。也就是说,如果我们能将新添加的层训练成恒等映射$f(x) = x$,新模型和原模型将同样有效。由于新模型可能得出更优的解来拟合训练数据集,添加层似乎有益而无害。然而在实践中,添加过多的层后训练误差不降反升,即使使用了批量归一化提供数值稳定性使得训练深层模型更加容易,但这个问题仍然存在。针对这一问题,何恺明等人提出了残差网络(ResNet) [1]。它在2015年的ImageNet图像识别挑战赛夺魁,并深刻影响了后来的深度神经网络的设计。


## 残差块
Expand Down
2 changes: 1 addition & 1 deletion chapter_deep-learning-basics/backprop.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ $$L = \ell(\boldsymbol{o}, y).$$

$$s = \frac{\lambda}{2} \left(\|\boldsymbol{W}^{(1)}\|_F^2 + \|\boldsymbol{W}^{(2)}\|_F^2\right),$$

其中矩阵的Frobenius范数等价于将矩阵压成向量后计算$L_2$范数。最终,模型在给定的数据样本上带正则化的损失为
其中矩阵的Frobenius范数等价于将矩阵变平为向量后计算$L_2$范数。最终,模型在给定的数据样本上带正则化的损失为

$$J = L + s.$$

Expand Down
4 changes: 2 additions & 2 deletions chapter_deep-learning-basics/dropout.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
$$h_i = \phi\left(x_1 w_{1i} + x_2 w_{2i} + x_3 w_{3i} + x_4 w_{4i} + b_i\right),$$

这里$\phi$是激活函数,$x_1, \ldots, x_4$是输入,隐藏单元$i$的权重参数为$w_{1i}, \ldots, w_{4i}$,偏差参数为$b_i$。当我们对该隐藏层使用丢弃法时,该层的隐藏单元将有一定概率被丢弃掉。设丢弃概率为$p$,
那么有$p$的概率$h_i$会被置为0,有$1-p$的概率$h_i$会除以$1-p$做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量$\xi_i$为0和1的概率分别为$p$和$1-p$。使用丢弃法时我们计算新的隐藏单元$h_i'$
那么有$p$的概率$h_i$会被清零,有$1-p$的概率$h_i$会除以$1-p$做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量$\xi_i$为0和1的概率分别为$p$和$1-p$。使用丢弃法时我们计算新的隐藏单元$h_i'$

$$h_i' = \frac{\xi_i}{1-p} h_i.$$

由于$\mathbb{E}(\xi_i) = 1-p$,因此

$$\mathbb{E}(h_i') = \frac{\mathbb{E}(\xi_i)}{1-p}h_i = h_i.$$

即丢弃法不改变其输入的期望值。让我们对图3.3中的隐藏层使用丢弃法,一种可能的结果如图3.5所示,其中$h_2$和$h_5$被置为了0。这时输出值的计算不再依赖$h_2$和$h_5$,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即$h_1, \ldots, h_5$都有可能被置为0。这样输出层的计算都无法过度依赖$h_1, \ldots, h_5$中的任一个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,一般不使用丢弃法。
即丢弃法不改变其输入的期望值。让我们对图3.3中的隐藏层使用丢弃法,一种可能的结果如图3.5所示,其中$h_2$和$h_5$被清零。这时输出值的计算不再依赖$h_2$和$h_5$,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即$h_1, \ldots, h_5$都有可能被清零。这样输出层的计算都无法过度依赖$h_1, \ldots, h_5$中的任一个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,一般不使用丢弃法。

![隐藏层使用了丢弃法的多层感知机。](../img/dropout.svg)

Expand Down
1 change: 1 addition & 0 deletions chapter_deep-learning-basics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
weight-decay
dropout
backprop
numerical-stability-and-init
kaggle-house-price
```
8 changes: 4 additions & 4 deletions chapter_deep-learning-basics/kaggle-house-price.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Kaggle比赛

Kaggle(网站地址:https://www.kaggle.com )是一个著名的供机器学习爱好者交流的平台。图3.8展示了Kaggle网站首页。为了便于提交结果,请大家注册Kaggle账号。
Kaggle(网站地址:https://www.kaggle.com )是一个著名的供机器学习爱好者交流的平台。图3.7展示了Kaggle网站首页。为了便于提交结果,请大家注册Kaggle账号。

![Kaggle网站首页。](../img/kaggle.png)

Expand All @@ -13,13 +13,13 @@ Kaggle(网站地址:https://www.kaggle.com )是一个著名的供机器学
> https://www.kaggle.com/c/house-prices-advanced-regression-techniques

图3.9展示了房价预测比赛的网页信息
图3.8展示了房价预测比赛的网页信息

![房价预测比赛的网页信息。比赛数据集可通过点击“Data”标签获取。](../img/house_pricing.png)

## 获取和读取数据集

比赛数据分为训练数据集和测试数据集。两个数据集都包括每栋房子的特征,例如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚至是缺失值“na”。只有训练数据集包括了每栋房子的价格。我们可以访问比赛网页,点击图3.9中的“Data”标签,并下载这些数据集。
比赛数据分为训练数据集和测试数据集。两个数据集都包括每栋房子的特征,例如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚至是缺失值“na”。只有训练数据集包括了每栋房子的价格。我们可以访问比赛网页,点击图3.8中的“Data”标签,并下载这些数据集。

下面,我们通过使用`pandas`读入数据,请简单介绍如何处理离散数据、处理丢失的数据特征和对数据进行标准化。在导入本节需要的包前请确保已安装`pandas`,否则请参考下面代码注释。

Expand Down Expand Up @@ -231,7 +231,7 @@ train_and_pred(train_features, test_features, train_labels, test_data,
num_epochs, lr, weight_decay, batch_size)
```

上述代码执行完之后会生成一个“submission.csv”文件。这个文件是符合Kaggle比赛要求的提交格式的。这时,我们可以在Kaggle上把我们预测得出的结果进行提交,并且查看与测试数据集上真实房价(标签)的误差。具体来说有以下几个步骤:你需要登录Kaggle网站,访问房价预测比赛网页,并点击右侧“Submit Predictions”或“Late Submission”按钮。然后,点击页面下方“Upload Submission File”选择需要提交的预测结果文件。最后,点击页面最下方的“Make Submission”按钮就可以查看结果了。如图3.11所示
上述代码执行完之后会生成一个“submission.csv”文件。这个文件是符合Kaggle比赛要求的提交格式的。这时,我们可以在Kaggle上把我们预测得出的结果进行提交,并且查看与测试数据集上真实房价(标签)的误差。具体来说有以下几个步骤:你需要登录Kaggle网站,访问房价预测比赛网页,并点击右侧“Submit Predictions”或“Late Submission”按钮。然后,点击页面下方“Upload Submission File”选择需要提交的预测结果文件。最后,点击页面最下方的“Make Submission”按钮就可以查看结果了。如图3.9所示

![Kaggle预测房价比赛的预测结果提交页面。](../img/kaggle_submit2.png)

Expand Down
51 changes: 51 additions & 0 deletions chapter_deep-learning-basics/numerical-stability-and-init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 数值稳定性和模型初始化

理解了正向传播与反向传播以后,我们来讨论一下深度学习模型的数值稳定性问题以及模型参数的初始化方法。深度模型有关数值稳定性的典型问题是衰减(vanishing)和爆炸(explosion)。


## 衰减和爆炸

当神经网络的层数较多时,模型的数值稳定性容易变差。假设一个层数为$L$的多层感知机的第$l$层$\boldsymbol{H}^{(l)}$的权重参数为$\boldsymbol{W}^{(l)}$,输出层$\boldsymbol{H}^{(L)}$的权重参数为$\boldsymbol{W}^{(L)}$。为了便于讨论,不考虑偏差参数,且设所有隐藏层的激活函数为恒等映射(identity mapping)$\phi(x) = x$。给定输入$\boldsymbol{X}$,多层感知机的第$l$层的输出$\boldsymbol{H}^{(l)} = \boldsymbol{X} \boldsymbol{W}^{(1)} \boldsymbol{W}^{(2)} \ldots \boldsymbol{W}^{(l)}$。此时,如果层数$l$较大,$\boldsymbol{H}^{(l)}$的计算可能会出现衰减或爆炸。举个例子,假设输入和所有层的权重参数都是标量,比如权重参数为0.2和5,多层感知机的第30层输出为输入$\boldsymbol{X}$分别与$0.2^{30} \approx 1 \times 10^{-21}$(衰减)和$5^{30} \approx 9 \times 10^{20}$(爆炸)的乘积。类似地,当层数较多时,梯度的计算也更容易出现衰减或爆炸。

随着内容的不断深入,我们会在后面的章节进一步介绍深度学习的数值稳定性问题以及解决方法。


## 随机初始化模型参数

在神经网络中,我们通常需要随机初始化模型参数。下面我们来解释这样做的原因。

回顾[“多层感知机”](mlp.md)一节图3.3描述的多层感知机。为了方便解释,假设输出层只保留一个输出单元$o_1$(删去$o_2, o_3$和指向它们的箭头),且隐藏层使用相同的激活函数。如果将每个隐藏单元的参数都初始化为相等的值,那么在正向传播时每个隐藏单元将根据相同的输入计算出相同的值,并传递至输出层。在反向传播中,每个隐藏单元的参数梯度值相等。因此,这些参数在使用基于梯度的优化算法迭代后值依然相等。之后的迭代也是如此。这种情况下,无论隐藏单元有多少,隐藏层本质上只有1个隐藏单元在发挥作用。因此,正如我们在前面的实验中所做的那样,我们通常将神经网络的模型参数,特别是权重参数,进行随机初始化。


### MXNet的默认随机初始化

随机初始化模型参数的方法有很多。在[“线性回归的Gluon实现”](linear-regression-gluon.md)一节中,我们使用`net.initialize(init.Normal(sigma=0.01))`使模型`net`的权重参数采用正态分布的随机初始化方式。如果不指定初始化方法,例如`net.initialize()`,MXNet将使用默认的随机初始化方法:权重参数每个元素随机采样于-0.07到0.07之间的均匀分布,偏差参数全部清零。


### Xavier随机初始化

还有一种比较常用的随机初始化方法叫做Xavier随机初始化 [1]。假设某全连接层的输入个数为$a$,输出个数为$b$,Xavier随机初始化将使得该层中权重参数的每个元素都随机采样于均匀分布

$$U\left(-\sqrt{\frac{6}{a+b}}, \sqrt{\frac{6}{a+b}}\right).$$

它的设计主要考虑到,模型参数初始化后,每层输出的方差不该受该层输入个数影响,且每层梯度的方差也不该受该层输出个数影响。

## 小结

* 深度模型有关数值稳定性的典型问题是衰减和爆炸。当神经网络的层数较多时,模型的数值稳定性容易变差。
* 我们通常需要随机初始化神经网络的模型参数。


## 练习

* 有人说随机初始化模型参数是为了“打破对称性”。这里的“对称”应如何理解?
* 我们是否可以将线性回归或softmax回归中所有的权重参数都初始化为相同值?


## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/8052)

![](../img/qr_numerical-stability-and-init.svg)

## 参考文献

[1] Glorot, X., & Bengio, Y. (2010, March). Understanding the difficulty of training deep feedforward neural networks. In Proceedings of the thirteenth international conference on artificial intelligence and statistics (pp. 249-256).
Loading

0 comments on commit 5618b8d

Please sign in to comment.