Hinton神经网络与机器学习 9. 提高神经网络的泛化能力

提高网络泛化能力的若干方法

概论

当训练网络用的数据量比较小,而网络又特别复杂时,就容易发生过拟合现象。其原因是,尽管数据集的输入和输出之间存在着某种规律性的关系,但是任何有限的训练集都会包含采样误差,也就是说,训练集中的某些规律可能是偶然的,只是因为选中了某些特殊的训练样例才会出现。因此,拟合模型时,并不能确定所有规律都是真实的规律,也不能保证如果重新对样本抽样,这些规律是否还能存在。因此,模型同时拟合了必然规律和偶然规律。如果模型参数太多,拟合得“太好”,就会很好地拟合训练集中的偶然误差,不好泛化,因此需要一些正则化方法来防止过拟合

解决过拟合的最好方法,也是最简单的方法,就是获得更多数据。第二种方法是精巧地去限制网络的能力,使其有足够的能力拟合必然规律,同时难以拟合偶然规律。这种方法比较困难,不过也有若干种做法。第三种方法在下一讲介绍,就是讲多种不同的模型平均起来。如果这些模型形式不同,犯的错误也不同,那么三个臭皮匠赛过诸葛亮,可以用训练数据的不同子集分别训练多个模型,这种方法称为装袋法(bagging)。第四种方法是贝叶斯方法,即只是用一个神经网络结构,但是使用不同组权重来分别预测,最后对预测结果求平均。这三节主要是看第二种方法

单论限制模型能力,也有若干种做法。其一是从网络结构下手。如果能缩小隐藏层层数和每层的单元数,就能控制网络中连接的个数,即参数数量。其二是使用比较小的权重做初始化,因此它需要非常长的时间才会过拟合,然后提早停止训练使其没有过拟合的机会。这种做法基于的假设是网络先找到必然规律。第三种方法非常常见,即对隐藏层层数和每层单元数不做限制,而是使用惩罚项或者权重的平方/绝对值做约束,来惩罚过大的权重。最后,可以通过往权重中或者激活中加入噪声来控制模型能力。通常情况下,会把以上这些方法组合起来使用

验证集

上述这些方法通常都会用到一些超参数,例如隐藏层层数、隐藏节点数、权重惩罚项的大小等等。很多人可能会通过在测试集上实验来选取一组最好的超参数,但是这种做法是非常错误的,因为按照某个测试集精细调整过的模型不一定在新的测试集上好用。也就是说,你会被假象蒙蔽。这里举一个极端情况:假设测试数据完全是随机的,答案不依赖于输入,或者不能被输入预测(例如某些金融领域的问题)。如果选择了某个在测试集上表现很好的模型,这个模型比瞎猜的效果好得多,你以为发现了宇宙的真谛,可以走上人生巅峰了,但是实际上用另一个测试集测试,这个模型基本还是会跟瞎猜的效果半斤八两

正确的做法是将整个数据集分成三个部分:训练数据用来训练模型,验证数据不用来训练,而是用来决定如何设置超参数。也就是说,使用验证数据来检查模型效果。做完这些以后,使用最好的超参数训练一边模型,然后在测试数据上看模型的最终效果。因此,测试数据只能用一次,目的是给出网络效果的无偏估计

有一种方法能更好地估计模型效果,就是让数据轮流做验证集。具体做法是,还是保留一份测试集来做最终的无偏估计,不过将剩下的数据分成\(N\)等份,每次用\(N-1\)份数据训练,第\(N\)份数据做验证,然后做一个轮转。例如,将数据集分成5份,第一次用第1 2 3 4四组数据训练,第5组数据验证,第二次用2 3 4 5四组数据训练,第1组数据验证,以此类推。这样可以得到\(N\)个估计。这种方法叫做\(N\)折交叉验证。注意这\(N\)个估计彼此并不独立

提前停止法

如果要在一个小电脑上训练一个大模型,没有时间用不同超参数训练好几个模型,那么有一种方法可以有效防止过拟合。首先,用一些小的权重来初始化模型。随着模型的训练,这些权重会增长。此时,观察模型在验证集上的效果,当它的效果变差时,结束训练。注意如果使用的评估指标是错误率而不是平方误差,那么这个指标可能会在验证集上浮动,因此最保险的做法是确定模型效果变差时再回到没有变差的那个点

这种方法能控制模型能力的原因是权重比较小的模型通常能力不足,而权重没有时间变得特别大。那么为什么权重小会导致网络能力不足呢?考虑一个有若干输入单元、若干隐藏单元和若干输出单元的模型。当权重很小时,如果隐藏单元是logistic单元,输入接近0,那么logistic的值会在线性区域的中间部分,即此时logistic单元的表现跟线性单元很像。也就是说,权重很小的时候,整个网络实际上像是一个线性网络,将输入直接映射为输出。随着网络的学习,权重变大,达到logistic单元的非线性区域,这些参数才真正被用上了。从另一个角度讲,这意味着可用的参数随着权重变大而变多,因此提前停止实际上限制了真正可用的参数数量,让网络在训练集上的表现和在验证集上的表现几乎相等——这种现象可以理解为,网络学习到了必然规律,还没开始学习偶然规律

限制权重大小

权重惩罚

通过限制权重大小来控制模型的复杂程度,标准做法是引入惩罚项,惩罚大的权重。其隐含的假设是,小权重的网络比大权重的网络简单

通常使用L2权重惩罚项来限制网络权重,也就是限制权重的平方。这种方法在某些神经网络的文献当中称为权重衰减,因为对惩罚项求导的结果像是把权重强推到零。引入L2惩罚项以后,代价函数变为 \[ C= E+ \frac{\lambda}{2}\sum_iw_i^2 \] 将其对\(w_i\)求偏导,有 \[ \frac{\partial C}{\partial w_i} = \frac{\partial E}{\partial w_i} + \lambda w_i \\ {\rm when\ }\frac{\partial C}{\partial w_i} = 0, w_i = -\frac{1}{\lambda}\frac{\partial E}{\partial w_i} \] 因此,在达到代价函数的最小值时,只有当该权重有比较大的误差导数时,这个权重才会比较大。因此加入L2惩罚项以后不会有那种值很大又什么都不做的权重存在。这种做法的好处是,首先,极大提高了网络的泛化能力,因为如果出现了大值而无用的权重,网络可能会用它来拟合偶然规律(取样误差)。其次,这样会使模型变得平滑,使输出的变化速度慢于输入的变化速度。假设网络接受两个相似的输入,有L2正则项的那个会倾向让两个输入的权重各为\(w/2\),而没有正则项的会让一个输入的权重为\(w\)另一个为0。如果现在将其中某个输入替换为一个完全不同的值,前者的变化会比后者小

除去L2正则项,L1正则项也是一个常用的方法,它所惩罚的是权重的绝对值。使用L1正则项会使大部分权重变为0(L2正则项会让大部分权重变得很小,但不会完全为0)。或者,可以使用一种更极端的惩罚函数,使得代价函数的梯度在权重很大时反而很小,这样它会把小的权重都淘汰掉,只剩下很少几个大的权重

权重限制

要在权重上做文章来避免过拟合,除了对权重加以惩罚以外,还可以对权重施加一些限制条件。也就是说,对隐藏层单元和输出层单元的输入权重,对其范数设置一个封顶的值。如果权重的范数超过了这个限定值,就把每个分量除以限定值,做放缩。这种方法与权重惩罚相比有如下几点好处

  • 首先,可以人为设置一个比较合理的上限
  • 其次,可以避免隐藏单元在零点附近震荡,此时它的权重都非常微小,起不到什么效果
  • 最后,可以防止权重爆炸

需要注意的是,当某个单元达到了限定值,它所有权重的有效惩罚取决于大的梯度。所以如果某些输入权重有很大的梯度,就会试图增大自己的范数,把其它权重的范数变小。也就是说,如果把权重限制也看做是一种惩罚项,它做的事情是让大权重的值变得合理,而让小权重更小。这种做法比设定一个固定的惩罚值来将不相关权重推到0要有效。实际上,这种做法就像是让某些限制条件满足的拉格朗日乘子

使用噪声做正则项

假设现在有一个简单的线性神经网络,代价函数是平方误差,网络结构是输入单元直接连接到输出单元。现在,往输入添加高斯噪声,即输入变为\(x_i + N(0, \sigma_i^2)\)。经由权重\(w_i\)的处理,最后的输出也会带有高斯噪声,即输出变为\(y_j + N(0, w_i^2\sigma_i^2)\)。也就是说,额外增加的这个方差实际上使得平方误差项又增加了一个随机项,该随机项满足均值为0,方差为\(\sigma_i^2\)的高斯分布。因此最小化新的平方误差时,也会最小化\(N(0, w_i^2\sigma_i^2)\)这一项,这一项的作用可以看作是给\(w_i\)增加了一个系数为\(\sigma_i^2\)的L2惩罚项。具体推导如下 \[ \begin{align*} y^{\rm noisy} &= \sum_iw_i(x_i + \epsilon_i) = \sum_iw_ix_i + \sum_i w_i\epsilon_i \ \ (\epsilon_i \sim N(0, \sigma_i^2)) \\ \mathbb{E}\left[(y^{\rm noisy} - t)^2\right] &= \mathbb{E}\left[\left(y+ \sum_{i}w_i\epsilon_i - t\right)^2\right] = \mathbb{E}\left[\left((y - t)+ \sum_{i}w_i\epsilon_i\right)^2\right] \\ &= (y-t)^2 + \mathbb{E}\left[2(y-t)\sum_iw_i\epsilon_i\right] + \mathbb{E}\left[\left(\sum_iw_i\epsilon_i\right)^2\right] \\ &= (y-t)^2 + 2(y-t)\sum_iw_i\mathbb{E}[\epsilon_i] + \mathbb{E}\left[\sum_iw_i^2\epsilon_i^2\right] + \mathbb{E}\left[\sum_{i\not= j}w_iw_j\epsilon_i\epsilon_j\right] \end{align*} \] 由于\(\epsilon_i \sim N(0, \sigma_i^2)\),且对\(i\not= j\)\(\epsilon_i\)\(\epsilon_j\)相互独立,因此\(\mathbb{E}[\epsilon_i] = 0,\ \mathbb{E}[\epsilon_i\epsilon_j] = \mathbb{E}[\epsilon_i]\mathbb{E}[\epsilon_j] = 0\)。又\({\rm Var}[\epsilon_i] = \sigma_i^2 = \mathbb{E}[\epsilon_i^2] - (\mathbb{E}[\epsilon_i])^2 = \mathbb{E}[\epsilon_i^2]\),因此上式最后可以化简为 \[ \mathbb{E}\left[(y^{\rm noisy} - t)^2\right] = (y-t)^2 + \sum_iw_i^2\sigma_i^2 \] 对于更复杂的网络,可以往权重中加入高斯噪声来限制网络的能力。这种做法不再等价于使用L2惩罚项,但是效果却更好,尤其是对于RNN更是这样

也可以在激活中使用噪声,将其作为一种正则化手段。假设使用反向传播来训练一个多层神经网络,网络的隐藏单元使用logistic函数做激活函数。在做正向传播时,动一些手脚:让隐藏单元随机输出0或者1(输出1的概率就是sigmoid函数的输出),但是反向传播的时候使用的是通过正常正向传播得出的,确定的实数。这种方法会让网络在训练集上的表现变差,而且训练过程变慢。但是如果用在测试集上,效果会有显著提高

贝叶斯方法简介

本节是对贝叶斯方法的一个简介。贝叶斯方法的原理是,不再考虑模型参数最可能的设置,而是先考虑参数的所有可能设置,然后对观察到的数据,判断每种设置的概率。贝叶斯理论的思考框架假设对任何事件都有一个先验概率分布,数据提供一个似然项,将先验分布和似然结合就可以得 到一个后验分布。其中,似然项更倾向使数据更有可能成为观测到的样子的参数设置,可以不符合先验分布。如果能得到足够的数据,不管先验分布与似然有多大的偏离,似然都会“克服”先验分布。如果数据足够,真相必然会水落石出,也就是说,即便先验是错的,最后也能得到正确的假设

来看一个关于掷硬币的例子。假设有一枚硬币,我们对其内部构造一无所知,只知道投掷它会以概率\(p\)得到正面,概率\(1-p\)得到反面。现在投掷了100次,得到53个正面,那么参数\(p\)应该是多少?频率学派通过最大似然法会说\(p=0.53\)。注意这个数计算的过程并不是特别显然。将“扔100次硬币得到53个正面”这个事件记为\(D\),则这个事件发生的概率\(P(D) = p^{53}(1-p)^{47}\)。令\(dP(D)/dp = 0\),可以得出\(p=0.53\)

不过,用最大似然法决定模型参数存在一些问题。假设我们只投了一次硬币,得到一个正面,那我们并不能说这个硬币掷出正面的概率是1。事实上,更可靠地猜测应该是0.5,但是如何证明呢?或者更重要的是,是否存在一个唯一且合理的答案?

我们知之不多,没有太多数据,因此难以确保\(p\)究竟应该是多少。所以我们应该拒绝给出一个单个的答案,而是给出所有可能答案的整个概率分布。如果先验的“信念”是硬币有一半机会掷出正面,那么\(p=0.5\)是很有可能的,\(p=1\)是很不可能的。这里,先把先验设为所有不同的\(p\)出现的机会都相等,然后,观察到硬币掷出了一个正面,所以对每个可能的先验\(p\),乘以以这个参数为基础,掷出正面的概率。例如,对\(p=1\),那么它预测只会掷出正面,因此对这个参数乘以1。对\(p=0\)的先验乘以0,对\(p=0.5\)的先验乘以0.5,以此类推。这样可以得到一个未归一化的后验分布。最后,对整个线下面积归一化,可以得到投掷第一次硬币以后参数的概率密度。接下来,再做一次实验,假设投出了反面,重复做上述过程,可以得到一个新的概率密度。经过剩余的98次投递,得到的是一个峰值在0.53左右的一个图像

所有以上这些过程都可以用贝叶斯定理来描述。令参数\(W\)和数据集\(D\)的联合概率为\(P(D, W)\)(对有监督学习问题,数据集包含了目标值)。这个值可以用两种方式计算 \[ P(D)P(W|D) = P(D, W) = P(W)P(D|W) \] 将等式两边同时除以\(P(D)\),有 \[ P(W|D) = \frac{P(W)P(D|W)}{P(D)} \] 贝叶斯定理告诉我们,\(W\)给定数据\(D\)的后验分布,等于\(W\)的先验分布与给定\(W\)的值观察到已知数据\(D\)的概率的乘积,再使用\(P(D)\)归一化。而数据\(D\)的概率可以表示为 \[ P(D) = \int_WP(W)P(D|W) \] 由于\(P(D)\)是对所有可能的\(W\)求积分,因此\(P(D)\)不依赖于具体的\(W\)的值。不过\(P(W)\)\(P(D|W)\)依赖具体的\(W\)

权重衰减的贝叶斯角度解释

如果要使用完整的贝叶斯方法,就要计算模型每种可能参数组合的后验概率。不过有一种简化方法,就是找到一组参数设置,它既能满足对参数的先验信念,也能符合所观测到的数据。这种方法称为最大后验(Maximum A Posteriori, MAP)学习,它可以很好地解释使用权重衰减法时真正发生了什么

使用有监督的最大似然学习方法来最小化平方误差的时候,找到的权重向量需要使残差(目标值与网络预测值之差)的平方最小化。这个任务目标等价于要找到一个权重向量,使之最大化正确答案的概率密度的对数值。为了说明这样的等价性,假设正确答案是通过往神经网络的输出中添加高斯噪声来产生,那么在这种情况下得到正确答案的概率是多少?这个问题可以这么描述。假设网络的输出\(y_c = f({\rm input}_ c, W)\),由于真实的目标值是输出添加噪声的结果,因此条件概率密度可以写为 \[ P(t_c|y_c) = \frac{1}{\sqrt{2\pi}\sigma}\exp\left\{-\frac{(t_c-y_c)^2}{2\sigma^2}\right\} \] 对等式左右两边取对数,有 \[ -\log P(t_c|y_c) = k + \frac{(t_c-y_c)^2}{2\sigma^2}, k =\frac{1}{\sqrt{2\pi}\sigma} \] 因此,如果代价函数是得到正确答案的概率的负对数,那么代价函数的形式相当于是在最小化两者距离的平方

接下来来看一下解决这个问题的贝叶斯方法。前面说过,要使用贝叶斯方法,就要找到所有可能权重对应的全部后验分布——对于神经网络来讲,这么做有点难。虽然可以使用蒙特卡罗法来近似这个分布,但是有一种更简单的做法,就是找到可能性最大的权重向量。尽管可以先随机初始化一个\(W\),然后通过让\(P(W|D)\)变大来调整\(W\),但是这种做法容易陷入局部最小值。更好的方法是在对数范畴内解决这个问题,即若要最小化代价函数,就计算概率的负对数值。OK,现在的目标是最大化不同训练样例产生目标值的概率的乘积,假设各个样例\(c\)的输出误差是独立的,则有 \[ P(D|W) = \prod_c P(t_c|W) = \prod_c P(t_c|f({\rm input}_c, W)) \] 由于对数函数是单调的,不改变原函数的单调性,因此可以两边取对数(计算概率的乘积容易发生下溢) \[ \log P(D|W) = \sum_c \log P(t_c|W) \] 同样的方法可以用到贝叶斯定理里。定义代价函数为\(-\log P(W|D)\),则有 \[ {\rm Cost} = -\log P(W|D) = -\log P(W) - \log P(D|W) + \log P(D) \] 由于\(\log P(D)\)\(W\)无关,因此优化\(W\)时可以不考虑这项。此外,\(-\log P(W)\),也就是权重的负对数先验,只取决于\(W\)。由前面的说明,最大化权重的对数概率相当于最小化某个距离的平方,因此如果假设权重的先验满足一个期望为0的高斯分布,那么最小化权重的平方等价于最大化权重的对数概率。这个概率密度可以写为 \[ \begin{align*} &P(W) = \frac{1}{\sqrt{2\pi}\sigma}\exp\left\{-\frac{w^2}{2\sigma_w^2}\right\} \\ \Rightarrow & -\log P(W) = \frac{w^2}{2\sigma^2_W} + k \end{align*} \] 这样,就可以得到一种对权重衰减(或称权重惩罚)的解释。假设真实目标值增加了期望为0,方差为\(\sigma_D^2\)的高斯噪声,权重的先验满足一个期望为0,方差为\(\sigma_W^2\)的高斯分布,那么记代价函数为\(C^\ast\),有 \[ C^\ast = \frac{1}{2\sigma_D^2}\sum_c (y_c - t_c)^2 + \frac{1}{2\sigma_W^2}\sum_i w_i^2 \] 等式两边同时乘以\(2\sigma_D^2\),有 \[ C = E + \frac{\sigma_D^2}{\sigma_W^2}\sum_iw_i^2 \]

这里\(E\)就是通常优化神经网络时用到的平方误差,第二项的\(\sigma_D^2/\sigma_W^2\)就是权重的惩罚项。这意味着,如果前面提到的先验概率分布都成立,那么惩罚项就不再是一个超参数,不是一个随意的值

MacKay的权重惩罚项设定法

MacKay在20世纪90年代曾经提出过一种不需要验证集的权重惩罚项设定法。在学到可以最小化平方误差的模型以后,可以通过残差误差的方差来找到输出方差的最佳值。对于权重的先验,由于其满足高斯分布,可以先猜测方差是多少,然后使用一种称作经验贝叶斯的方法来调整,即就使用学到的权重的方差。具体内容可以参考下述论文

MacKay, D. J. (1995). Probable networks and plausible predictions—a review of practical Bayesian methods for supervised neural networks. Network: Computation in Neural Systems, 6(3), 469-505.

坚持原创技术分享,您的支持将鼓励我继续创作!