浅谈模型优化

简单介绍模型选择与拟合、权重衰减、Dropout 等模型优化概念。

欠拟合与过拟合

神经网络的本质是在大量的数据中寻找不变的规律,或模式。对于学习模式,可以有两种方式:一是简单地让模型“记忆”给定的数据集,二是让模型通过数据集“理解”数据的分布特征。前者一般在离散的小数据集上表现较好,而后者在更大的数据集(尤其是训练数据远小于预测数据范围时)通常有更好的表现。

泛化误差与训练误差

如何去衡量这二者的优劣呢?我们给出训练误差(training error)和泛化误差(generalization error)。我们称模型在学习数据集中的数据后再进行预测的误差为训练误差,而在陌生数据集上(如真实数据应用)产生的误差为泛化误差。显然,我们希望泛化误差尽可能地小,来更好地适应实际应用。

而一个很现实的问题是,在模型训练阶段,我们通常只能获得训练误差,而很难获得准确的泛化误差。那是否可以简单地认为训练误差约等于泛化误差呢?在统计学中,格里文科–康特利定理指出:

当样本量趋于无穷大时,样本的经验分布函数几乎必然一致收敛到总体的真实分布函数。

也就是说,当训练数据集足够大时,训练误差几乎必然等于泛化误差。

定理考虑了训练数据和测试数据均符合独立同分布假设(i.i.d. assumption),即采样过程关于采样顺序并没有关联。在现实中,我们很难找到一个完美符合独立同分布假设的应用场景,甚至有些会严重违背这一假设。一个简单的例子是使用大学生的人脸图像训练针对老年人的人脸识别系统,这显然不符合上述假设,因为大学生与老年人有很大的差异。

即便假定数据符合独立同分布假设,解释泛化性也是一个极其困难的问题。实践上,我们希望在训练误差尽可能小的基础上,同时使泛化误差与训练误差的差较小。如果一个模型在训练中表现得过于完美,那么其泛化能力就会令人担忧,导致模型过拟合。

一个模型的泛化性很大程度上取决于模型复杂性。实践中,我们一般认为模型的复杂度与可调整参数的数量(或自由度)、参数的取值范围、训练数据的数量高度相关。当我们使用更简单的模型和大量的数据时,我们期望泛化误差和训练误差相近;而模型更复杂且样本更少时,尽管训练误差会毫无疑问地下降,泛化误差可能会增大。下图展示了模型复杂度对拟合程度的影响。

capacity-vs-error

训练集、测试集与验证集

那什么样的模型是合适的呢?我们需要使用某种方法来衡量训练误差和泛化误差。我们可以通过模型在训练集上的表现来确定训练误差,而泛化误差的获得则要复杂些。直接使用测试集进行预测是不可取的:这会导致模型选择过程中不可避免地倾向于选择泛化程度高即测试集误差小的模型,进而导致测试集被过拟合。这一现象也称作测试集泄露。

一个常见的做法是采用独立于训练集和测试集之外的第三个数据集——验证集(validation set),通过获得模型在验证集上的表现来尽可能估算泛化误差。

实践中,可供我们使用的数据集通常是有限的,我们需要尽可能使用每一个样本进行训练。上述方法显然占用了过多的数据用于测试和验证,这压缩了训练集的数量。我们通常可以采用 K 折交叉验证的方式构成验证集。我们先将训练集分为 K 个不重叠的子集,然后进行 K 次模型训练与验证。每次训练中,我们对 K - 1 个子集构成新的训练集,对于剩余的 1 个子集则留为验证集,最后取 K 次实验的结果取平均值估计误差。

权重衰减

我们知道,扩大数据集规模可以提高模型的泛化能力,缓解过拟合问题。另一种有效的方式是采用权重衰减(weight decay)的方法来环节过拟合。前文提到,模型复杂度与参数的数量和取值范围相关。不难发现,单单调节模型参数数量带来的拟合情况可能过于粗糙,无法精细调节模型拟合程度。于是,我们可以考虑使用限制参数的取值范围来细粒度调节拟合程度。

为什么限制参数取值范围可以调整拟合程度呢?一个很简单的例子是线性回归:y^=Wx+b\hat{\mathbf{y}} = \mathbf{Wx} + \mathbf{b} ,当权重 W\mathbf{W} 很大时,输入值 x\mathbf{x} 一点点细微的改变就会导致预测值 y^\hat{\mathbf{y}} 发生极大的改变,而实际情况可能是更为平滑的。所以,限制参数的取值范围可以一定程度上降低过拟合风险,提高泛化能力。

范数与正则化

我们希望限制模型的复杂性。从直觉上来讲,我们模型拟合出的函数 ff 越接近函数 f=0f = 0 时,模型越简单。那么我们的任务也就是衡量模型与 f=0f = 0 之间的距离。这与模型参数的范数密切相关,此处简单介绍一下线性代数中范数与正则化相关概念。

形象地说,范数(norm)表示一个向量的分量的大小。这不难联系到平面几何中欧几里得距离的概念。事实上,欧几里得距离是一个 L2L_2 范数,表示为:

x2=i=1nxi2, \|\mathbf{x}\|_2 = \sqrt{\sum_{i=1}^n x_i^2},

即向量元素平方和的平方根。同时我们也有 L1L_1 范数,表示为向量元素的绝对值之和:

x1=i=1nxi. \|\mathbf{x}\|_1 = \sum_{i=1}^n \left|x_i \right|.

更一般地,我们有 LpL_p 范数:

xp=(i=1nxip)1/p. \|\mathbf{x}\|_p = \left(\sum_{i=1}^n \left|x_i \right|^p \right)^{1/p}.

深度学习中,以 L1L_1 范数和 L2L_2 范数最为常用,分别对应 L1L_1 正则化和 L2L_2 正则化。

所谓正则化(regularization),即对原始损失函数引入额外信息,防止过拟合和提高模型泛化能力的一类方法。可以认为,正则化在原始损失函数 L0L_0 的基础上增加了关于参数的惩罚项,即 L=L0+lL = L_0 + l

L2L_2 正则化

而权重衰减属于正则化技术的一种,也称为 L2L_2 正则化 。对于线性回归中的均方误差损失,我们的初始损失表达为:

L(w,b)=1ni=1n12(wx(i)+by(i))2. L(\mathbf{w}, b) = \frac{1}{n}\sum_{i=1}^n \frac{1}{2}\left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right)^2.

按照正则化的概念,我们应该在原始损失函数的基础上添加正则化项,使得模型的训练目标由“最小化预测与实际值之间的差异”转变为“在最小化预测与实际值之间的差异的基础上,尽可能使模型简单”。那么我们的新损失函数就是:

L(w,b)+λ2w22, L(\mathbf{w}, b) + \frac{\lambda}{2} \|\mathbf{w}\|^2_2,

其中 λ\lambda 是可以调节的超参数。实践上一般取 λ=0\lambda = 0 ,寻找最优学习率,而后在最优学习率固定的情况下从 λ=1\lambda = 1 开始以 10 倍为标准放大/缩小 λ\lambda ,找到合适的数量级,而后进行微调确定最终的 λ\lambda

从上式可以看出,L2L_2 正则化对过大的参数施加了巨大的惩罚,导致模型倾向于更小的参数,来避免过拟合。而 L1L_1 正则化可以使参数稀疏化,只保留对模型由重要作用的特征,用于特征选择。

Dropout

深层神经网络对比线性网络一个重要的不同是隐藏层的存在,这使得模型可以考虑不同特征之间的关联。一个好的预测模型,正如上文所述,应该是简单的,且在未知数据上有较好的表现。L2L_2 正则化考虑了模型参数大小的简单性,而 Dropout(暂退法)则关注模型的平滑性,即一些噪声不应该对整体预测结果产生较大的影响。

那么,为了增强网络对抗噪声的能力,我们可以考虑手动在网络中加入一定噪声。这种方法就是 Dropout 法。Dropout 在前向传播中,对每一层加入噪声。标准的 dropout 会在训练中将某些神经元的活性值置为 00 ,即丢弃某些神经元,进而从某些程度上降低网络对于其他神经元的高度依赖,迫使网络学习更有泛化性的特征。

在标准 dropout 中,我们有:

h={0 概率为 ph1p 其他情况 \begin{split}\begin{aligned} h' = \begin{cases} 0 & \text{ 概率为 } p \\ \frac{h}{1-p} & \text{ 其他情况} \end{cases} \end{aligned}\end{split}
其中,h1p\frac{h}{1-p} 是对参数大小的缩放,确保了模型在后续测试时的参数值仍然有效。

实际应用中,我们可以将 dropout 应用到多层感知机中,降低模型过拟合。下图是一个例子。

dropout

具体地说,我们在训练过程中,对于每一次 epoch ,都重新生成一个 dropout 神经元的集合,从而变相地在训练过程中同时训练了多个神经网络。从某种意义上说,dropout 也是在使用多次求值取平均的思想来降低过拟合。

一般来讲,dropout 只在训练时使用,测试时不采用 dropout 。