## 目录
- [1. 训练误差和泛化误差](#1-训练误差和泛化误差)
- [2. 该如何选择模型](#2-该如何选择模型)
- [2.1 验证数据集](#21-验证数据集)
- [2.2 K 折交叉验证](#22-k-折交叉验证)
- [3. ⽋拟合和过拟合](#3-⽋拟合和过拟合)
- [4. 丢弃法(Dropout)](#4-丢弃法dropout)
- [5. 梯度消失/梯度爆炸(Vanishing / Exploding gradients)](#5-梯度消失梯度爆炸vanishing--exploding-gradients)
- [6. 随机梯度下降法(SGD)](#6-随机梯度下降法sgd)
- [6.1 mini-batch梯度下降](#61-mini-batch梯度下降)
- [6.2 调节 Batch_Size 对训练效果影响到底如何?](#62-调节-batch_size-对训练效果影响到底如何)
- [7. 优化算法](#7-优化算法)
- [7.1 动量法](#71-动量法)
- [7.2 AdaGrad算法](#72-adagrad算法)
- [7.3 RMSProp算法](#73-rmsprop算法)
- [7.4 AdaDelta算法](#74-adadelta算法)
- [7.5 Adam算法](#75-adam算法)
- [7.6 局部最优--鞍点问题](#76-局部最优--鞍点问题)
- [8. 如何解决训练样本少的问题](#8-如何解决训练样本少的问题)
- [9. 如何提升模型的稳定性?](#9-如何提升模型的稳定性)
- [10. 有哪些改善模型的思路](#10-有哪些改善模型的思路)
- [11. 如何提高深度学习系统的性能](#11-如何提高深度学习系统的性能)
- [12. 参考文献](#12-参考文献)
## 1. 训练误差和泛化误差
机器学习模型在训练数据集和测试数据集上的表现。如果你改变过实验中的模型结构或者超参数,你也许发现了:当模型在训练数据集上更准确时,它在测试数据集上却不⼀定更准确。这是为什么呢?
因为存在着训练误差和泛化误差:
- **训练误差:**模型在训练数据集上表现出的误差。
- **泛化误差:**模型在任意⼀个测试数据样本上表现出的误差的期望,并常常通过测试数据集上的误差来近似。
训练误差的期望小于或等于泛化误差。也就是说,⼀般情况下,由训练数据集学到的模型参数会使模型在训练数据集上的表现优于或等于在测试数据集上的表现。**由于⽆法从训练误差估计泛化误差,⼀味地降低训练误差并不意味着泛化误差⼀定会降低。**
**机器学习模型应关注降低泛化误差。**
## 2. 该如何选择模型
在机器学习中,通常需要评估若⼲候选模型的表现并从中选择模型。这⼀过程称为模型选择(model selection)。可供选择的候选模型可以是有着不同超参数的同类模型。以多层感知机为例,我们可以选择隐藏层的个数,以及每个隐藏层中隐藏单元个数和激活函数。为了得到有效的模型,我们通常要在模型选择上下⼀番功夫。
### 2.1 验证数据集
从严格意义上讲,测试集只能在所有超参数和模型参数选定后使⽤⼀次。不可以使⽤测试数据选择模型,如调参。由于⽆法从训练误差估计泛化误差,因此也不应只依赖训练数据选择模型。鉴于此,我们可以预留⼀部分在训练数据集和测试数据集以外的数据来进⾏模型选择。这部分数据被称为验证数据集,简称验证集(validation set)。例如,我们可以从给定的训练集中随机选取⼀小部分作为验证集,而将剩余部分作为真正的训练集。
可以通过预留这样的验证集来进行模型选择,判断验证集在模型中的表现能力。
### 2.2 K 折交叉验证
由于验证数据集不参与模型训练,当训练数据不够⽤时,预留⼤量的验证数据显得太奢侈。⼀种改善的⽅法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成K个不重合的⼦数据集,然后我们做K次模型训练和验证。每⼀次,我们使⽤⼀个⼦数据集验证模型,并使⽤其他K − 1个⼦数据集来训练模型。在这K次训练和验证中,每次⽤来验证模型的⼦数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。
## 3. ⽋拟合和过拟合
- **欠拟合:**模型⽆法得到较低的训练误差。
- **过拟合:**是模型的训练误差远小于它在测试数据集上的误差。
给定训练数据集,
- 如果模型的复杂度过低,很容易出现⽋拟合;
- 如果模型复杂度过⾼,很容易出现过拟合。
应对⽋拟合和过拟合的⼀个办法是针对数据集选择合适复杂度的模型。
![](https://gitee.com/kkweishe/images/raw/master/ML/2019-8-18_21-7-0.png)
**训练数据集⼤⼩**
影响⽋拟合和过拟合的另⼀个重要因素是训练数据集的⼤小。⼀般来说,如果训练数据集中样本数过少,特别是⽐模型参数数量(按元素计)更少时,过拟合更容易发⽣。此外,泛化误差不会随训练数据集⾥样本数量增加而增⼤。因此,在计算资源允许的范围之内,我们通常希望训练数据集⼤⼀些,特别是在模型复杂度较⾼时,例如层数较多的深度学习模型。
**正则化**
应对过拟合问题的常⽤⽅法:权重衰减(weight decay),权重衰减等价于L2范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常⽤⼿段。
## 4. 丢弃法(Dropout)
除了上面提到的权重衰减以外,深度学习模型常常使⽤丢弃法(dropout)来应对过拟合问题。丢弃法有⼀些不同的变体。本节中提到的丢弃法特指倒置丢弃法(inverted dropout)。
回忆⼀下,“多层感知机”描述了⼀个单隐藏层的多层感知机。其中输⼊个数为4,隐藏单元个数为5,且隐藏单元hi(i = 1, . . . , 5)的计算表达式为:
![](https://latex.codecogs.com/gif.latex?h_i=\phi(x_1w_{1i}+x_2w_{2i}+x_3w_{3i}+x_4w_{4i}+b_i))
这⾥ϕ是激活函数,x1, . . . , x4是输⼊,隐藏单元i的权重参数为w1i, . . . , w4i,偏差参数为bi。当对该隐藏层使⽤丢弃法时,该层的隐藏单元将有⼀定概率被丢弃掉。设丢弃概率为p,那么有p的概率hi会被清零,有1 − p的概率hi会除以1 − p做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量ξi为0和1的概率分别为p和1 − p。使⽤丢弃法时我们计算新的隐藏单元 ![](https://gitee.com/kkweishe/images/raw/master/ML/2019-8-19_10-38-57.png)。
![](https://gitee.com/kkweishe/images/raw/master/ML/2019-8-19_10-42-10.png)
由于E(ξi) = 1 − p,因此:
![](https://gitee.com/kkweishe/images/raw/master/ML/2019-8-19_10-43-31.png)
**即丢弃法不改变其输⼊的期望值。**让我们对隐藏层使⽤丢弃法,⼀种可能的结果如下图所⽰,其中h2和h5被清零。这时输出值的计算不再依赖h2和h5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即h1, . . . , h5都有可能被清零,输出层的计算⽆法过度依赖h1, . . . , h5中的任⼀个,从而在训练模型时起到正则化的作⽤,并可以⽤来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,⼀般不使⽤丢弃法。
![](https://gitee.com/kkweishe/images/raw/master/ML/2019-8-18_21-24-40.png)
## 5. 梯度消失/梯度爆炸(Vanishing / Exploding gradients)
训练神经网络,尤其是深度神经所面临的一个问题就是梯度消失或梯度爆炸,也就是你训练神经网络的时候,导数或坡度有时会变得非常大,或者非常小,甚至于以指数方式变小,这加大了训练的难度。
本质上,梯度消失和爆炸是一种情况。在深层网络中,由于网络过深,如果初始得到的梯度过小,或者传播途中在某一层上过小,则在之后的层上得到的梯度会越来越小,即产生了梯�