深度学习方法探析——训练过程优化
Sun Hao

1. 引言

深层神经网络的训练过程往往需要花费很多时间,特别对于很深的网络,往往需要花费巨大的时间和算力,而且如果网络的结构选择不当,会造成数据欠拟合或过拟合的后果。为了尽可能减少训练深层神经网络的代价,提高模型准确度,本文从训练过程角度讨论了几种可以加速训练速度和精度的方法,包括欠拟合和过拟合的判断方法、解决过拟合的正则化方法、提高训练速度的归一化输入、减缓梯度消失和梯度爆炸的初始化方法。另外,本文还介绍了一种用于检验网络梯度下降正确性的方法——梯度检验。

2. 训练集、验证集和测试集

在深层神经网络模型训练的过程中,需要提供许多数据用于计算最优参数,这些训练用的数据被称为训练集 (train set)。可以注意到模型中还存在许多超参数,这些超参数在模型训练开始都是根据经验设置的,可以使用交叉验证集,也称验证集 (dev set)来挑选超参数,它是参与模型选择过程的。而测试集 (test set)不以任何形式参与到模型的选择中,它用于在选择好模型后对模型的运行状况进行无偏估计。
我们要做的是,在训练集上对模型进行训练;然后尝试不同的模型框架,在验证集上评估这些模型,迭代选出适合的模型;最后在测试集上对该模型的运行状况进行无偏估计,通过不断的循环迭代训练出优秀的模型,该过程如图1所示。

图1 深层神经网络模型训练迭代流程

在数据量比较小的时候,可以按照60%训练集,20%验证集,20%测试集的比例进行划分。但是在大数据时代,数据量可能是百万级别,验证集和测试集占数据总量的比例会趋向于变得更小。有时,如果不需要无偏估计,也可以只设置训练集和验证集,人们通常把这种情况称为只有训练集和测试集,实际上是将验证集过度拟合到了验证集,从而把测试集当做验证集使用。训练集、验证集和测试集的对比如表1所示。

表1 训练集、验证集、测试集对比

3. 偏差和方差

3.1 偏差和方差

估计的偏差 (bias)被定义为

其中,期望作用在所有数据上,是用于定义数据生成分布的的真实值。
估计量的方差 (variance)为

其中,随机变量是训练集。估计量的方差告诉我们,当独立地从潜在的数据生成过程中重采样数据集时,如何期望估计的变化。正如我们希望估计的偏差较小,我们也希望其方差较小。

3.2 欠拟合和过拟合

当讨论偏差和方差时,就不得不研究欠拟合和过拟合的问题。如图2所示,图中的绿点为一组数据集,图2 (a)对数据集拟合了一条直线,得到了一个逻辑回归拟合,它并不能很好地拟合该数据,这就是欠拟合 (underfitting)的情况,该情况下偏差高;如果我们使用一个复杂的网络模型,比如深度神经网络或含有隐藏单元的神经网络,可能就非常适用于这个数据集,如图2 (c)所示,但这显然也不是一种很好的拟合方式,它过度地拟合了训练集中的特殊情况,这就是过拟合 (overfitting),该情况下方差高。图2 (b)就是一种很好的拟合方式,其复杂程度适中,拟合数据更加合理,可以称这种情况为适度拟合 (just right),这种情况下偏差和方差均较小。

图2 三种拟合情况

3.3 欠拟合和过拟合的判断

现假设训练集和验证集的最优化误差为0,我们可以通过比较训练集和验证集的误差大小判断拟合情况。若某情况下训练集的误差小,而验证集的误差大,说明过度拟合了训练集的数据,为高方差;若训练集和验证集的误差都很大且二者相当,则训练集数据没有得到很好的拟合,为高偏差;若训练集和验证集的误差都很大且验证集误差更大一些,则为高偏差高方差的情况,在某些维度上的数据区域偏差高,某些维度上的数据方差高,是最坏的一种情况;若训练集和验证集误差都很小,该情况就为适度拟合。现将欠拟合和过拟合判断方法总结为表2。

表2 欠拟合和过拟合判断方法

3.4 降低偏差和方差的方法

训练网络的最低标准就是能够拟合数据,因此在训练完模型后应该首先评估网络的偏差是否很大。如果发现网络的偏差很大,可以常识几个方法:选择一个新的网络,比如含有更多隐藏层或者隐藏单元的网络;花费更多时间来训练网络;或者尝试更先进的优化算法。其中,使用规模更大的网络通常是有用的。
如果检测到网络的方差很高,最好的办法就是采用更多的数据。但有时我们无法获得更多数据,这时可以尝试使用正则化的方式降低网络的方差,这将在下一节中讲述。

4. 正则化

4.1 正则化

现从逻辑回归模型着手,对正则化进行研究。对逻辑回归模型实施正则化后,其总代价为

其中涉及到了范数的概念,范数定义如下

其中。由于该过程用到了范数,因此称其为称为正则化,的计算过程为

这里只将参数正则化的原因是,几乎包含了所有参数,而只是一个参数,可以忽略不计。
正则化推广到神经网络中,(3)式变为

其中,的计算过程为

该矩阵范数被称作“弗罗贝尼乌斯范数 ()”,用下标F标注。正则化后的只需在原有基础上减去正则项的导数即可:

其中,()代表未正则化前的 。更新后的

可见,正则化每次更新都在原有的上先乘一个小于1点的数再进行梯度下降,因此正则化也被称为“权重衰减”。

4.2 正则化减少过拟合的原理

如前所述,过拟合情况的发生是由于网络过于复杂,拟合了过多的训练集数据,我们希望简化网络模型,正则化减少过拟合的原理可以从两方面直观理解。一方面,正则化朝着减小权重的方向更新 ,可以假设某些被更新到接近于0,这样对应的节点就相当于断开了,网络得到简化。实际上权重的衰减并不会这么大,但可以一定程度简化网络,达到减缓过拟合的效果。
另一方面,我们所用的激活函数,如函数和函数,在0附近近似于线性,正则化将参数往减小的方向调整,假设调整幅度很大,正则化参数λ足够大,就会使得落在线性区域。而线性的激活函数无论有多少层,对输出而言都只有一层,这就使得复杂的网络得到了简化。虽然在实际情况下每层输出不会变为线性,但可以一定程度地减缓过拟合。

4.3 Dropout正则化

正则化外,还有一种十分有效的正则化方法——Dropout正则化,可以理解为随机失活。Dropout的原理是:对每一层的节点设置失活概率,该层中的每个节点都以该概率随机被删除,这在一定程度上简化了网络,可以达到减缓过拟合的效果,如图3所示。

图3 实施Dropout前后的网络

Dropout正则化可以减缓过拟合的原因可以理解为:每个节点的输入都可能随机消失,所以在训练过程中不会过分依赖任何一个节点,这会产生收缩权重的平方范数的效果,这和正则化相类似。值得注意的是,为了不对预测结果在范围上产生变化,需要在每层激活函数的输出数据上除以 (1-失活概率),这起到了归一化的作用。
Dropout的一大缺点就是代价函数 不再被明确定义,或者说在某种程度上很难计算,每次迭代,都会随机移除一些节点,这使得梯度下降的性能很难得到检验。因此,通常可以先关闭Dropout,检查代价函数 J单调递减后再打开Dropout进行迭代训练,这有助于减少程序中的错误。

4.4 正则化实际效果测试

通过理论推理,可以得出正则化可以减缓过拟合的结论,下面将使用python编程实现正则化和Dropout正则化,比较实际结果与理论推理是否一致。首先不适用正则化,对一组数据进行拟合,该组数据有两个特征向量,通过图形化展示如图4所示,不同的y以不同的颜色表示。

图4 待分类数据

现使用一个三层网络对其进行训练,每层节点数分别为2、20、3、1,迭代30000次,得到的总代价曲线如图5所示,训练集和验证集准确度如图6所示,验证集误差比训练集误差大。将训练出的分类器不同部分以不同颜色填图得到图7,可以发现有部分特例也被分类器拟合了,存在过拟合的情况。

图5 未正则化时的总代价曲线
图6 未正则化时的测试验证集准确度
图7 未正则化时训练得到的模型

4.4.1 正则化

对上述模型实施正则化,设置参数为0.7,其余不变,这时总代价曲线如图8所示,训练集和验证集准确度如图9所示。

图8 L2正则化时的总代价曲线
图9 L2正则化时的测试验证集准确度

可以看到,此时验证机误差和训练集误差十分接近,过拟合情况得到了改善。对模型进行颜色填图,得到的分类器模型如图10所示。该模型没有将特殊点拟合进去,实现了不错的二分类,可见正则化的效果是不错的。

图10 L2正则化时训练得到的模型

4.4.2 Dropout正则化

现对最初的模型进行Dropout正则化,将所有节点的失活概率都设置为0.14,其余不变,得到的总代价曲线如图11所示,训练集和验证集准确度如图12所示。

图11 Dropout正则化时的总代价曲线
图12 Dropout正则化时的测试验证集准确度

使用Dropout正则化后,验证集的准确度超过了训练集,说明适当简化网络后得到了更佳的性能。得到的分类器模型如图13所示,该模型也没有将特殊点拟合进去,并且对分界线上得数据进行了合理分配,训练得到的模型性能优于前者。可见,Dropout正则化在一定程度上能缓解数据的过拟合。

图13 Dropout正则化时训练得到的模型

4.5 Early Stopping

除了正则化和Dropout正则化外,Early Stopping也是一种避免数据过拟合的有效方法。在未进行多少次迭代时,参数的值很小,随着迭代次数的增加,的值越来越大,此时就可能会产生过拟合。Early Stopping要做的就是在方差恶化的时候及时停止迭代,如图14所示,后半段验证集误差随着迭代次数增加而增大,方差进而增大,在最优迭代次数处停止迭代可以得到较好的偏差和方差的权衡。

图14 训练验证集误差随迭代次数的变化

Early Stopping的优点是:不必像正则化一样不断测试λ的值以便找到合适的超参数,它只需运行一次梯度下降即可。但它在停止迭代的同时也停止了对总代价的优化,因此它可能影响偏差的大小。换句话说,它是在进行偏差和方差的权衡,降低了方差可能以提高偏差为代价,而不能用两种方法分别解决这两个问题,但在一定程度上这种方法是可行的。

5. 归一化输入

归一化输入是一个很好的加速训练过程的方法,归一化的过程可以分为两步:均值归零化和方差归一化。均值归零化的公式为

其中,为数据的均值

方差归一化的公式为

其中,为数据的方差

归一化输入使输入全部变为均值为0,方差为1的数据,该过程可形象地表现为图15的形式,为便于展示,假定该组数据只有两个特征向量。

图15 归一化输入

下面说明归一化输入可以加速训练过程的原因,当使用未归一化的数据时,其不同特征向量的均值和方差可能有所不同,这将导致不同的特征向量对应的的均值和方差不同,他们的范围可能相差数十甚至上百倍。现以一个二维的为例,绘制其总代价函数,如图16(a)所示,这是未输入归一化的情形,两个维度存在较大范围差。当在其上进行梯度下降时,必须取很小的步长,而且是迂回下降的,因为这个函数是狭长的。而通过如图16(b)的归一化后的数据训练出的W对应的总代价函数为一个碗形,可以很容易地沿一条线进行梯度下降直至谷底,有效节省了训练时间。

图16 归一化前后总代价函数梯度下降

6. 权重初始化

6.1 梯度消失和梯度爆炸

当训练深度较深的深层神经网络时,通过反向传播计算出的梯度有时会变得特别大或特别小,甚至是以指数形式变化,这会极大地加大训练的难度,这就是梯度爆炸和梯度消失。当梯度变得特别小时,每次梯度下降的步长都变得很小,增加了达到谷底的迭代次数;当梯度变得特别大时,梯度下降法只能在谷底两次徘徊,而无法到达谷底,这都十分影响训练的速度和精度。
造成梯度消失和梯度爆炸的原因是:在深层神经网络的训练过程中中一般都会存在这一项 ,深层网络中的一般很大,只要 略微大于1,该项将会变得非常大,反之亦然。这就导致了激活函数的输出很大或很小,同理,对应的梯度也会变得非常大或非常小。

6.2 权重初始化

缓解梯度消失和梯度爆炸的一种方法就是更谨慎地选择随机初始化参数,虽然这不能从根本上解决问题,但会有所帮助。对于一个神经元来说,其输出和输入有如下关系

其中,表示神经网络输入的特征数量。为了防止过大或过小,我们希望在较大时减小,在较小时增大,比较好的方法就是将的方差设置为,我们要做的就是在对每层的权重随机初始化时,在其上乘。特别地,若使用函数作为激活函数,将设置为通常是更佳的,也就是在随机初始化的权重上乘,对于函数来说,就是一个不错的选择。

6.3 几种权重初始化的实际效果测试

这里使用和正则化时相同的训练验证集进行训练,模型仍为一个三层网络每层节点数分别为2、20、3、1,迭代15000次,依次使用零初始化、随机初始化(参数初始化很大)和初始化对模型进行训练,对比三种情况的拟合效果。

6.3.1 零初始化

将所有参数初始化为0,将训练到的分类器模型进行填图得到图17,训练验证集的准确度如图18所示。

图17 零初始化时的模型
图18 零初始化时训练验证集的准确度

可见,这个模型是十分糟糕的,准确度仅在一半左右,将所有输入都预测为0,这验证了我们之前所说的,如果将参数初始化为0,整个网络的对称性会使得每个节点都在做同样的事,这使得每层都等效于只有一个节点,使得这个网络性能和线性的逻辑回归模型差不多,甚至更差。

6.3.2 随机初始化(参数初始化很大)

为了模拟梯度爆炸的情况,我们将随机初始化的参数都乘10,其余设置都与6.3.1节相同。总代价随迭代次数的变化如图19所示,初始总代价很大,这是由初始权重很大造成的,其间总代价出现了几次上升,这正是图16(a)代表的情况,由于梯度爆炸,在谷底两侧不断徘徊。训练得到的模型如图20所示,训练验证集的准确度如图21所示。

图19 随机初始化总代价曲线(参数初始化很大)
图20 随机初始化时的模型
图21 随机初始化时训练验证集的准确度

可见,梯度爆炸的情况下,训练过程被延长,并且模型效果不佳,应该设法避免这种情况发生。

6.3.3 初始化

初始化是用第一个使用它的作者命名的,就是之前提到的对激活函数是时的初始化方法,其在随机初始化的权重上乘初始化下总代价随迭代次数的变化如图22所示,总代价随迭代次数的衰减很快。训练得到的模型如图23所示,训练验证集的准确度如图24所示。

图22 He初始化总代价曲线
图23 He初始化时的模型
图24 He初始化时训练验证集的准确度

在这种初始化方式下,模型的准确度表现良好,可见好的初始化对缓解梯度消失或梯度爆炸的重要性。

7. 梯度检验

在训练神经网络时,有时虽然程序能够正常运行,但很难检查反向传播是否完全正常工作。一种比较好的评估方法就是采用数值逼近,我们称其为梯度检验。梯度检验通过取代价函数上某点左右两侧十分临近的两点的函数值对该点的导数进行估计,这里采用双边公差的原因是其误差比单边公差小。
进行梯度检验要进行的第一件事就是将网络中的参数 转换成一个向量

转换成一个向量

总代价函数的函数,可以写成,接下来要做的就是对每个组成元素使用双边估计得到

最后对得到的两个向量进行比较来估计反向传播的正确性,这里采用下式对两向量进行比较

如果计算得到的值为或更小,说明导数逼近很有可能是正确的;如果它的值在范围内,就应该引起注意,模型训练的过程中可能存在问题。发现网络存在问题时,应该仔细检查所有θ项,查看是否有某一个特定的使得相差较大,并用其追踪求导运算,然后进行调试,直到(18)式的计算结果达到的量级为止。

 Comments