优化过程

1、优化过程中过拟合与欠拟合
过拟合和欠拟合模型是深度学习模型在训练过程中比较容易出现的不好的现象。
当模型的表现能力弱于事件的真实表现时,会出现欠拟合现象。某个非线性模型合适的解如图1(a)所示。如果用线性模型去训练这个非线性问题,自然难以得到合适的解,如图1(b)所示。

相反,当模型的表现能力强于事件的真实表现时,会出现过拟合现象,过拟合现象是指模型为了追求训练集的准确率,过多地学习一些非普遍的特征,导致模型的泛化能力下降。虽然能很好地拟合训练集,但是在测试集上表现不佳。正常拟合的模型如图2(a)所示,过拟合的模型如图2(b)所示。

影响模型过拟合和欠拟合的原因主要有两个:数据(数据量大小)和模型容量(模型复杂度),其关系见表1。
数据简单 | 数据复杂 | |
模型容量低 | 正常 | 欠拟合 |
模型容量高 | 过拟合 | 正常 |
从数据量的角度理解:当用于训练模型的数据太少时容易出现过拟合现象;数据太多容易出现欠拟合现象。这个现象可以通过生活中的例子来解释:假设一个大学生正在努力准备期末考试。如果用于考试的备考题库(训练集)太简单,学生可能试图通过死记硬背考题的答案来做准备。他甚至可以完全记住过去考试的答案,实际上这样做他并没有真的理解题目。这种记住训练集中每个样本的现象被称之为过拟合。相反,如果用于考试的备考题库太多太难,超出学生记忆过的范围,同时学生也很难理解题目之间相关性以及分析数据的特征。这种训练集太难,模型无法胜任处理工作的现象被称之为欠拟合。
从模型复杂程度的角度理解:为什么一个大学生会想到背答案?如果换个幼儿园的小朋友来做题还会想到背答案这个方法吗?其实,一个大学生可以类比成一个复杂的模型,而一个幼儿园小朋友可以类比成一个简单的模型。由此可以轻易地判断出,一个复杂的模型更容易出现过拟合现象,因为它更容易记住训练集中的每个样本而不是学习到普适的特征。
最后,训练误差和泛化误差是衡量模型拟合效果的两个重要指标。首先解释一下什么是训练误差和泛化误差:
(1)训练误差(Training Error),指模型在训练数据集上计算得到的误差。
(2)泛化误差(Generalization Error),指模型应用在同样从原始样本的分布中抽取的无限多数据样本时,模型误差的期望。
问题是,我们永远不能准确地计算出泛化误差。这是因为无限多的数据样本是一个虚构的对象。在实际中,只能通过将模型应用于一个独立的测试集来估计泛化误差,该测试集由随机选取的、未曾在训练集中出现的数据样本构成。
过拟合现象的一个明显的特点是模型的训练误差很小,但是泛化误差很大。而欠拟合现象的体现是模型的训练误差和泛化误差都很大。训练模型的目的是希望模型能适用于真实世界,即模型的泛化误差要小,因此,过拟合和欠拟合现象都是在训练深度学习模型中应该尽量避免的问题。
过拟合现象也可以从“维度诅咒”的角度进行解释。在之前介绍的深度学习模型中,每层神经网络的感知机数量都不同,这相当于对原始数据进行升、降维,在不同的维度空间下提取原始数据的特征。不同维度空间又是什么意思?举个例子,现在使用一个简单的线性分类器,试图完美地对猫和狗进行分类。首先可以从一个特征开始,如“圆眼”特征,分类结果如图3所示。

由于猫和狗都是圆眼睛,此时无法获得完美的分类结果。因此,可能会决定增加其它特征,如“尖耳朵”特征,分类结果如图4所示。

此时发现,猫和狗两个类型的数据分布渐渐离散,最后,增加第三个特征,例如“长鼻子”特征,得到一个三维特征空间,如图5所示。

此时,模型已经可以很好地拟合出一个分类决策面对猫和狗两个类型进行分类了。那么很自然地联想一下:如果继续增加特征数量,将原始数据映射到更高维度的空间下是不是更有利于分类呢?
事实并非如此。注意当增加问题维数的时候,训练样本的密度是呈指数下降的。假设10个训练实例涵盖了完整的一维特征空间,其宽度为5个单元间隔。因此,在一维情况下,样本密度为(10/5=2)样本/间隔。
在二维情况下,仍然有10个训练实例,现在它用5×5=25个单位正方形面积涵盖了二维的特征空间。因此,在二维情况下,样本密度为(10/25=0.4)样本/间隔。
最后,在三维的情况下,10个样本覆盖了5×5×5=125个单位立方体特征空间体积。因此,在三维的情况下,样本密度为(10/125=0.08)样本/间隔。
如果不断增加特征,则特征空间的维数也在增长,并变得越来越稀疏。由于这种稀疏性,找到一个可分离的超平面会变得非常容易。在这种情况下,模型训练的分类决策面可以非常轻易且完美地区分所有个体。有读者可能会说:对于训练数据做完美的区分,这岂不是很好吗?
其实不然,因为训练数据是取自真实世界的,且任何一个训练集都不可能包含大千世界中的全部情况。就好比采集猫狗数据集时不可能拍摄到全世界的所有猫狗一样。此时对于这个训练数据集做完美的区分实际上会固化模型的思维,使其在真实世界中的泛化能力很差。这个现象在生活中其实就是“钻牛角尖”。举个例子:假设我们费尽心思想出了一百种特征来定义中国的牛,这种严格的定义可以很容易地将牛与其他物种区分开来。但是有一天,一只英国的奶牛漂洋过海游到了中国。由于这只外国牛只有90种特征符合中国对牛的定义,就不把它定义为牛了。这种做法显然是不合理的,原因是特征空间的维度太高,把这种现象称为“维度诅咒”,当问题的维数变得比较大时,分类器的性能降低。“维度诅咒”现象如图6所示。

接下来的问题是“太大”指的是多大,如何避免维度诅咒?遗憾的是没有固定的规则来确定分类中应该有多少特征。事实上,这取决于可用训练数据的数量,决策边界的复杂性以及所使用分类器的类型。如果可以获得训练样本的理论无限量,则维度的诅咒将被终结。
在实际工作中,我们似乎都认同这样一个事实:如果增加数据提取的特征维度,或者说如果模型需要更高维度的输入,那么相应地,也需要增加训练数据。例如在人工提取特征的时候,如果结合了多个特征,最后的求解模型的训练往往也需要更多的数据。又如在深度神经网络中,由于输入维度过高,往往需要增加大量的训练数据,否则模型会“喂不饱”。
回顾刚才的例子,由于高特征维度的空间膨胀,原来样本变得稀疏,原来距离相近的一些样本也都变得距离极远。这种维度诅咒现象增加了模型过拟合的风险,因为随着数据维度的增加,模型更容易学习到训练数据中的噪声而非其真实结构。
防止过拟合对于构建能够泛化到新数据上的深度学习模型至关重要。过拟合的模型虽然在训练数据上表现优异,但其在未见过的数据上的表现往往较差,限制了模型的实用性和可靠性。为了避免过拟合,常见的做法包括正则化、Dropout和数据增强。
L1正则化(L1 Regularization)是机器学习和统计领域中用于防止模型过拟合的技术之一。它通过在损失函数中添加一个与模型参数的绝对值成正比的惩罚项来工作。假设我们有一个简单的神经网络,它由一个输入层、两个隐藏层和一个输出层组成。每个层之间的权重矩阵由\(\mathrm{W}\)表示。
设神经网络的输出为\(h(W,x^{(i)})\),真实值为\(y^{(i)}\),则MSE损失函数定义为:
\(J_{MSE}(W)=\frac{1}{m}\sum_{i=1}^{m}\left(h(W,x^{(i)})-y^{(i)}\right)^{2}\)
其中:\(\mathrm{m}\)是训练样本的数量;\(\mathbf{W}\)代表神经网络所有的权重。
当为其添加L1正则化时,损失函数变为:
\(J_{L1}(\boldsymbol{W})=\frac{1}{m}\sum_{i=1}^{m}\left(h(\boldsymbol{W},\boldsymbol{x}^{(i)})-\boldsymbol{y}^{(i)}\right)^{2}+\lambda\sum_{l}\sum_{i}\sum_{j}\left|\boldsymbol{W}_{ij}^{(l)}\right|\)
这里除了损失函数外的额外项就是当前添加的L1正则。在减小损失函数的过程中,由于正则项和原损失是相加的,所以它们都会在模型训练期间慢慢减小,又因为正则项是所有参数绝对值的求和,所以减小正则项就意味着限制模型中的所有参数不要太大,防止出现梯度不稳定的训练问题。注意:\(\lambda\)是正则化的强度参数。\(W_{ij}^{(l)}\)是第\(\mathrm{l}\)层的权重矩阵中的元素,从第\(\mathrm{i}\)个神经元到第\(\mathrm{j}\)个神经元的连接。外部的求和覆盖了网络中的所有层、所有神经元及其连接。
L1正则化引入的效果是:
(1)权重稀疏性:L1正则化导致网络中很多权重趋近于0,从而引入了权重的稀疏性。
(2)简化模型:由于部分权重变为0,网络的某些连接实际上会被“关闭”,这有助于减少过拟合并简化模型。
正如之前提到的,选择适当的正则化强度(即\(\lambda\)值)是关键。太小的值可能不会有太大的正则化效果,而太大的值可能会导致过多的权重变为0,从而过度简化模型。通常,交叉验证是确定最佳\(\lambda\)值的好方法。
对比之下,L2正则(L2 Regularization)是在损失函数上加一个\(\boldsymbol{\omega}\)的绝对值平方项,产生让\(\boldsymbol{\omega}\)尽可能不要太大的效果。L2正则一般不考虑参数b的正则,只是计入参数\(\boldsymbol{\omega}\)的正则,因为b参数量小,不易增加模型的复杂性,也不易带来模型输出的方差。正则化参数b反而可能导致模型欠拟合。损失函数再加入L2正则后,新的损失函数\(L^{\prime}\)表示为:
\(L^{\prime}=L+\frac{1}{2}\lambda\|\boldsymbol{\omega}_{t-1}\|^2\)
对损失函数\(L^{\prime}\)求导得到导数\(g^{\prime}\):
\(g^{\prime}=g+\lambda\boldsymbol{\omega}_{t-1}\)
使用梯度下降算法更新参数\(\boldsymbol{\omega}_{t}\):
\(\omega_t=\omega_t-\eta g-\eta\lambda\omega_{t-1}=(1-\eta\lambda)\boldsymbol{\omega}_t-\eta\boldsymbol{g}\)
通常\(\eta\lambda<1\),所以与参数\(\boldsymbol{\omega}_{t}\)相乘时,有衰减权重的作用,因此L2正则又被称为权重衰减。
正则可以看作通过约束模型复杂度来防止过拟合现象的一些手段。首先,模型复杂度是由模型的参数量大小和参数的可取值范围一起决定的。因此正则方法也分为两个方向:一个方向致力于约束模型参数的取值范围,例如上述的正则方法;一个方向致力于约束模型参数量,例如丢弃法(Dropout),如图7。没有经过丢弃法处理的网络如图7(a)所示,丢弃法处理过的网络模型如图7(b)所示。在训练过程中,丢弃法随机地将每一层神经网络的所有节点以一定的概率将其输出置为零,具体的实现方法是将与被丢弃神经元相连的所有权重置零。这些被丢弃的神经元在当前训练样本的前向传播和反向传播过程中不会被激活或更新。

从图7中可以发现,经过Dropout计算之后的模型,其参数数量明显减少了,通过这种方式来降低模型的复杂度。
上述的所有方法是从模型复杂度角度来防止过拟合现象的。下面将解释从训练集容量角度来防止过拟合现象,这类方法被称为数据增强(Data Augmentation)。原理很简单,只要提升训练数据集的样本数量就可以防止过拟合现象。以计算机视觉任务为例,可以从图像数据集中抽出每个样本,针对每个样本做不同的随机裁剪、水平翻转、颜色光照变换,对比度增减等操作,这样可以由一张原图得到很多的副本图像。将这些图像一起作为模型的训练集,即可增加数据集的容量,示例图片如图8所示。

当然,这种简单的方式已经比较古老了。现在也可以使用生成对抗网络(GANs)等生成类深度学习模型,来生成新的样本作为训练样本,经过实验验证也是可行的。
到此,关于防止深度学习训练产生过拟合现象的三种方式已经介绍完了(正则、丢弃法和数据增强)。至于防止模型欠拟合的方法则比较简单,增加模型复杂度即可。例如,可以通过直接增加深度学习模型隐藏层的数量,让模型变深一些;或增加每层神经网络的节点数量,让模型变宽一些。
2、优化过程中梯度不稳定
深度学习模型是通过不断堆叠层级结构组成的神经网络模型,由于在前向传播中,每层神经网络其实是一次相乘求和的操作;所以堆叠多层的深度学习模型的计算本质是一个累乘的模型。在反向传播中,由于链式法则的使用,累乘的性质依然存在,而累乘会导致数值不稳定的问题,这种数值不稳定性问题在深度学习训练过程中会直接造成梯度传播的两个问题:
(1)梯度消失:在深层神经网络中,梯度弥散是指在反向传播过程中梯度逐渐变小,以至于在网络的较浅层梯度接近于零。这导致网络的这些层的权重几乎不更新,使得模型难以学习到输入数据的复杂特征。
(2)梯度爆炸:相对地,梯度爆炸是指梯度在反向传播过程中变得异常大,导致权重更新过度,从而造成模型参数极端不稳定,甚至数值溢出。这会导致模型无法收敛,训练过程中的权重更新剧烈,使得模型性能大幅下降。
防止出现梯度不稳定问题的方法之一是进行数据归一化处理。也就是对每个训练的Mini-batch做归一化,叫做Batch Normalization(BN)。BN在之后的网络模型中频繁出现,成为神经网络中必不可少的一环。下面将从训练角度解释一下BN操作的原理。
在网络训练过程中,由于参数不断改变导致后续每一层输入的分布也随之发生变化,而学习的过程又要使每一层适应输入的分布,因此我们不得不降低学习率、小心地初始化。这个分布发生变化的现象被称之为内部协变量偏移(Internal Co-variate Shift,ICS)。为了解决这个问题,研究人员提出了一种解决方案:在训练网络时,将输入数据减去均值。这一操作的目的是加快网络的训练速度。
为什么减均值可以加快训练呢,这里做一个简单地说明。首先,图像数据具有高度的相关性,相似的图像在抽象为高维空间的数据分布时是接近的。假设其分布如图9(a)所示(一个点代表一个图像,简化为二维)。由于初始化的时候,参数一般都是0均值的,因此开始的拟合\(y=\omega x+b\),基本在原点附近,如图9(b)线所示。因此,网络需要经过多次学习才能逐步达到如实线的拟合,即收敛得比较慢。如果对输入数据先做减均值操作,显然可以加快学习,如图9(c)所示。

可视化解释:BN就是对神经网络每层输入数据的数据分布进行归一化操作,由不规律的数据分布,如图10(a)所示;变成了规则的数据分布,如图10(b)所示。箭头表示模型寻找最优解的过程,显然图10(b)中的方式更方便、更容易。

最后,BN方法的公式如下所示:
输入信息:\(\mathrm{x}\)的值超过小批量:\(B={x_{1..m}}\) ;要学习的参数:\(\mathrm{r}\) 、 \(\beta\);
输出信息:\({y_{i}=BN_{{\gamma,\beta}}(x{_i})}\)。
算法过程如下:
\(\mu_s\leftarrow\frac{1}{m}\sum_{i=1}^mx_i\) (1)
\(\sigma_{_B}^{^2}\leftarrow\frac{1}{m}\sum_{i=1}^{^m}(x_{_i}-\mu_{_B})^2\) (2)
\(\hat{X}_1\leftarrow\frac{X_\mathrm{i}-\mu_\mathrm{\beta}}{\sqrt{\sigma_\mathrm{\beta}^2+\epsilon}}\) (3)
\(y_i\leftarrow\hat{\gamma}x_i+\beta\equiv BN_{\beta,\gamma}(x_i)\) (4)
式(1)沿着通道计算了每个批量的均值\(\mu\);接着式(2)沿着通道计算了每个批量的方差\(\sigma^{2}\);式(3)对\(\mathrm{x}\)做归一化\(x^{\prime}=(x-\mu)/\sqrt{\sigma^{2}+\varepsilon}\);最后式(4)加入缩放和平移变量\(\mathrm{r}\)和\(\beta\)。其中归一化后的值,\(y=\gamma x^{\prime}+\beta\)加入缩放平移变量的原因是:不一定每次都是标准正态分布,也许需要偏移或者拉伸。保证每一次数据经过归一化后还保留原有学习得来的特征,同时又能完成归一化操作,加速训练。这两个参数是用来学习的参数,可以随着网络训练的迭代而更新。
除了累乘问题带来的梯度不稳定以外,网络参数的初始化和激活函数的不当选择也会导致梯度的不稳定问题。例如在梯度弥散中,使用如Sigmoid或Tanh这样的激活函数,其导数在输入值非常高或非常低时接近零,导致梯度逐层减小。而在梯度爆炸中,权重初始化过大或使用了没有饱和上限的激活函数(如ReLU),可能导致梯度随着层数增加而指数级增长。因此有一些工作便是来优化激活函数的,例如针对ReLU的变体激活函数Leaky-ReLU、Swish、ReLU6等等,这些变种通过在负区间提供非零斜率,减少了梯度在负输入值时的消失;在正区间进行最大值限制,防止梯度累成的梯度爆炸,通过这些措施有助于保持梯度在整个网络中的健康流动,特别是在深层网络中。最后,一个合理的网络参数初始化也可以帮助梯度的健康传递,例如特别适用于ReLU激活函数网络的He初始化方法,适用于Sigmoid和Tanh激活函数网络的Xavier初始化方法等等,这里不再展开叙述。
作者
arwin.yu.98@gmail.com