公益AI-TASK03-过拟合、欠拟合及其解决方案;梯度消失、梯度爆炸;循环神经网络进阶
过拟合、欠拟合及其解决方案
1.过拟合、欠拟合的概念
2.权重衰减
3.丢弃法
训练误差和泛化误差
在解释上述现象之前,我们需要区分训练误差(training error)和泛化误差(generalization error)。通俗来讲,前者指模型在训练数据集上表现出的误差,后者指模型在任意一个测试数据样本上表现出的误差的期望,并常常通过测试数据集上的误差来近似。计算训练误差和泛化误差可以使用之前介绍过的损失函数,例如线性回归用到的平方损失函数和softmax回归用到的交叉熵损失函数。
机器学习模型应关注降低泛化误差。
验证数据集
从严格意义上讲,测试集只能在所有超参数和模型参数选定后使用一次。不可以使用测试数据选择模型,如调参。由于无法从训练误差估计泛化误差,因此也不应只依赖训练数据选择模型。鉴于此,我们可以预留一部分在训练数据集和测试数据集以外的数据来进行模型选择。这部分数据被称为验证数据集,简称验证集(validation set)。例如,我们可以从给定的训练集中随机选取一小部分作为验证集,而将剩余部分作为真正的训练集。
K折交叉验证
由于验证数据集不参与模型训练,当训练数据不够用时,预留大量的验证数据显得太奢侈。一种改善的方法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成K个不重合的子数据集,然后我们做K次模型训练和验证。每一次,我们使用一个子数据集验证模型,并使用其他K-1个子数据集来训练模型。在这K次训练和验证中,每次用来验证模型的子数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。
过拟合和欠拟合
接下来,我们将探究模型训练中经常出现的两类典型问题:
一类是模型无法得到较低的训练误差,我们将这一现象称作欠拟合(underfitting);
另一类是模型的训练误差远小于它在测试数据集上的误差,我们称该现象为过拟合(overfitting)。 在实践中,我们要尽可能同时应对欠拟合和过拟合。虽然有很多因素可能导致这两种拟合问题,在这里我们重点讨论两个因素:模型复杂度和训练数据集大小。
模型复杂度
为了解释模型复杂度,我们以多项式函数拟合为例。给定一个由标量数据特征 x 和对应的标量标签 y 组成的训练数据集,多项式函数拟合的目标是找一个 K 阶多项式函数
y^=b+∑k=1Kxkwk
来近似 y 。在上式中, wk 是模型的权重参数, b 是偏差参数。与线性回归相同,多项式函数拟合也使用平方损失函数。特别地,一阶多项式函数拟合又叫线性函数拟合。
训练数据集大小
影响欠拟合和过拟合的另一个重要因素是训练数据集的大小。一般来说,如果训练数据集中样本数过少,特别是比模型参数数量(按元素计)更少时,过拟合更容易发生。此外,泛化误差不会随训练数据集里样本数量增加而增大。因此,在计算资源允许的范围之内,我们通常希望训练数据集大一些,特别是在模型复杂度较高时,例如层数较多的深度学习模型。
权重衰减
权重衰减等价于 L2 范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常用手段。
L2范数正则化
L2 范数正则化在模型原损失函数基础上添加L2范数惩罚项,从而得到训练所需要最小化的函数。L2范数惩罚项指的是模型权重参数每个元素的平方和与一个正的常数的乘积。以线性回归中的线性回归损失函数为例
?(w1,w2,b)=1n∑i=1n12(x(i)1w1+x(i)2w2+b?y(i))2
其中w1,w2是权重参数,b是偏差参数,样本i的输入为x(i)1,x(i)2,标签为y(i),样本数为n。将权重参数用向量w=[w1,w2]表示,带有L2范数惩罚项的新损失函数为
?(w1,w2,b)+λ2n|w|2,
其中超参数λ>0。当权重参数均为0时,惩罚项最小。当λ较大时,惩罚项在损失函数中的比重较大,这通常会使学到的权重参数的元素较接近0。当λ设为0时,惩罚项完全不起作用。上式中L2范数平方|w|2展开后得到w21+w22。 有了L2范数惩罚项后,在小批量随机梯度下降中,我们将线性回归一节中权重w1和w2的迭代方式更改为
可见, L2 范数正则化令权重 w1 和 w2 先自乘小于1的数,再减去不含惩罚项的梯度。因此, L2 范数正则化又叫权重衰减。权重衰减通过惩罚绝对值较大的模型参数为需要学习的模型增加了限制,这可能对过拟合有效。
高维线性回归实验从零开始的实现
下面,我们以高维线性回归为例来引入一个过拟合问题,并使用权重衰减来应对过拟合。设数据样本特征的维度为 p 。对于训练数据集和测试数据集中特征为 x1,x2,…,xp 的任一样本,我们使用如下的线性函数来生成该样本的标签:
y=0.05+∑i=1p0.01xi+?
其中噪声项 ? 服从均值为0、标准差为0.01的正态分布。
初始化模型参数
定义L2范数惩罚项
定义和测试训练
观察过拟合
使用权重衰减
丢弃法
多层感知机中神经网络图描述了一个单隐藏层的多层感知机。其中输入个数为4,隐藏单元个数为5,且隐藏单元 hi ( i=1,…,5 )的计算表达式为
hi=?(x1w1i+x2w2i+x3w3i+x4w4i+bi)
这里 ? 是激活函数, x1,…,x4 是输入,隐藏单元 i 的权重参数为 w1i,…,w4i ,偏差参数为 bi 。当对该隐藏层使用丢弃法时,该层的隐藏单元将有一定概率被丢弃掉。设丢弃概率为 p ,那么有 p 的概率 hi 会被清零,有 1?p 的概率 hi 会除以 1?p 做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量 ξi 为0和1的概率分别为 p 和 1?p 。使用丢弃法时我们计算新的隐藏单元 h′i
h′i=ξi1?phi
由于 E(ξi)=1?p ,因此
E(h′i)=E(ξi)1?phi=hi
即丢弃法不改变其输入的期望值。让我们对之前多层感知机的神经网络中的隐藏层使用丢弃法,一种可能的结果如图所示,其中 h2 和 h5 被清零。这时输出值的计算不再依赖 h2 和 h5 ,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即 h1,…,h5 都有可能被清零,输出层的计算无法过度依赖 h1,…,h5 中的任一个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,一般不使用丢弃法
总结
欠拟合现象:模型无法达到一个较低的误差
过拟合现象:训练误差较低但是泛化误差依然较高,二者相差较大
梯度消失、梯度爆炸
1.梯度消失和梯度爆炸
2.考虑到环境因素的其他问题
3.Kaggle房价预测
梯度消失和梯度爆炸
深度模型有关数值稳定性的典型问题是消失(vanishing)和爆炸(explosion)。
当神经网络的层数较多时,模型的数值稳定性容易变差。
假设一个层数为 L 的多层感知机的第 l 层 H(l) 的权重参数为 W(l) ,输出层 H(L) 的权重参数为 W(L) 。为了便于讨论,不考虑偏差参数,且设所有隐藏层的激活函数为恒等映射(identity mapping) ?(x)=x 。给定输入 X ,多层感知机的第 l 层的输出 H(l)=XW(1)W(2)…W(l) 。此时,如果层数 l 较大, H(l) 的计算可能会出现衰减或爆炸。举个例子,假设输入和所有层的权重参数都是标量,如权重参数为0.2和5,多层感知机的第30层输出为输入 X 分别与 0.230≈1×10?21 (消失)和 530≈9×1020 (爆炸)的乘积。当层数较多时,梯度的计算也容易出现消失或爆炸。
随机初始化参数模型
在神经网络中,通常需要随机初始化模型参数。下面我们来解释这样做的原因。
回顾多层感知机一节描述的多层感知机。为了方便解释,假设输出层只保留一个输出单元 o1 (删去 o2 和 o3 以及指向它们的箭头),且隐藏层使用相同的激活函数。如果将每个隐藏单元的参数都初始化为相等的值,那么在正向传播时每个隐藏单元将根据相同的输入计算出相同的值,并传递至输出层。在反向传播中,每个隐藏单元的参数梯度值相等。因此,这些参数在使用基于梯度的优化算法迭代后值依然相等。之后的迭代也是如此。在这种情况下,无论隐藏单元有多少,隐藏层本质上只有1个隐藏单元在发挥作用。因此,正如在前面的实验中所做的那样,我们通常将神经网络的模型参数,特别是权重参数,进行随机初始化。
Pytorch的默认随机初始化
随机初始化模型参数的方法有很多。在线性回归的简洁实现中,我们使用torch.nn.init.normal_()
使模型net
的权重参数采用正态分布的随机初始化方式。不过,PyTorch中nn.Module
的模块参数都采取了较为合理的初始化策略(不同类型的layer具体采样的哪一种初始化方法的可参考源代码),因此一般不用我们考虑。
Xavier随机初始化
还有一种比较常用的随机初始化方法叫作Xavier随机初始化。 假设某全连接层的输入个数为 a ,输出个数为 b ,Xavier随机初始化将使该层中权重参数的每个元素都随机采样于均匀分布
U(?6a+b?????√,6a+b?????√).
它的设计主要考虑到,模型参数初始化后,每层输出的方差不该受该层输入个数影响,且每层梯度的方差也不该受该层输出个数影响。
协变量偏移
这里我们假设,虽然输入的分布可能随时间而改变,但是标记函数,即条件分布P(y∣x)不会改变。虽然这个问题容易理解,但在实践中也容易忽视。
想想区分猫和狗的一个例子。我们的训练数据使用的是猫和狗的真实的照片,但是在测试时,我们被要求对猫和狗的卡通图片进行分类。
显然,这不太可能奏效。训练集由照片组成,而测试集只包含卡通。在一个看起来与测试集有着本质不同的数据集上进行训练,而不考虑如何适应新的情况,这是不是一个好主意。不幸的是,这是一个非常常见的陷阱。
统计学家称这种协变量变化是因为问题的根源在于特征分布的变化(即协变量的变化)。数学上,我们可以说P(x)改变了,但P(y∣x)保持不变。尽管它的有用性并不局限于此,当我们认为x导致y时,协变量移位通常是正确的假设。
标签偏移
当我们认为导致偏移的是标签P(y)上的边缘分布的变化,但类条件分布是不变的P(x∣y)时,就会出现相反的问题。当我们认为y导致x时,标签偏移是一个合理的假设。例如,通常我们希望根据其表现来预测诊断结果。在这种情况下,我们认为诊断引起的表现,即疾病引起的症状。有时标签偏移和协变量移位假设可以同时成立。例如,当真正的标签函数是确定的和不变的,那么协变量偏移将始终保持,包括如果标签偏移也保持。有趣的是,当我们期望标签偏移和协变量偏移保持时,使用来自标签偏移假设的方法通常是有利的。这是因为这些方法倾向于操作看起来像标签的对象,这(在深度学习中)与处理看起来像输入的对象(在深度学习中)相比相对容易一些。
病因(要预测的诊断结果)导致 症状(观察到的结果)。
训练数据集,数据很少只包含流感p(y)的样本。
而测试数据集有流感p(y)和流感q(y),其中不变的是流感症状p(x|y)。
概念偏移
另一个相关的问题出现在概念转换中,即标签本身的定义发生变化的情况。这听起来很奇怪,毕竟猫就是猫。的确,猫的定义可能不会改变,但我们能不能对软饮料也这么说呢?事实证明,如果我们周游美国,按地理位置转移数据来源,我们会发现,即使是如图所示的这个简单术语的定义也会发生相当大的概念转变。
如果我们要建立一个机器翻译系统,分布P(y∣x)可能因我们的位置而异。这个问题很难发现。另一个可取之处是P(y∣x)通常只是逐渐变化。
Kaggle房价预测实战
作为深度学习基础篇章的总结,我们将对本章内容学以致用。下面,让我们动手实战一个Kaggle比赛:房价预测。本节将提供未经调优的数据的预处理、模型的设计和超参数的选择。我们希望读者通过动手操作、仔细观察实验现象、认真分析实验结果并不断调整方法,得到令自己满意的结果。
获取和读取数据集
预处理数据
训练模型
K折交叉验证
我们在模型选择、欠拟合和过拟合中介绍了 K 折交叉验证。它将被用来选择模型设计并调节超参数。下面实现了一个函数,它返回第i折交叉验证时所需要的训练和验证数据。
在 K 折交叉验证中我们训练 K 次并返回训练和验证的平均误差
模型选择
我们使用一组未经调优的超参数并计算交叉验证误差。可以改动这些超参数来尽可能减小平均测试误差。 有时候你会发现一组参数的训练误差可以达到很低,但是在 K 折交叉验证上的误差可能反而较高。这种现象很可能是由过拟合造成的。因此,当训练误差降低时,我们要观察 K 折交叉验证上的误差是否也相应降低。
预测并在Kaggle中提交结果
循环神经网络进阶
本节介绍循环神经网络,下图展示了如何基于循环神经网络实现语言模型。我们的目的是基于当前的输入与过去的输入序列,预测序列的下一个字符。循环神经网络引入一个隐藏变量 H ,用 Ht 表示 H 在时间步 t 的值。 Ht 的计算基于 Xt 和 Ht?1 ,可以认为 Ht 记录了到当前字符为止的序列信息,利用 Ht 对序列的下一个字符进行预测。
循环神经网络的构造
我们先看循环神经网络的具体构造。假设 Xt∈Rn×d 是时间步 t 的小批量输入, Ht∈Rn×h 是该时间步的隐藏变量,则:
Ht=?(XtWxh+Ht?1Whh+bh).
其中, Wxh∈Rd×h , Whh∈Rh×h , bh∈R1×h , ? 函数是非线性激活函数。由于引入了 Ht?1Whh , Ht 能够捕捉截至当前时间步的序列的历史信息,就像是神经网络当前时间步的状态或记忆一样。由于 Ht 的计算基于 Ht?1 ,上式的计算是循环的,使用循环计算的网络即循环神经网络(recurrent neural network)。
在时间步 t ,输出层的输出为:
Ot=HtWhq+bq.
其中 Whq∈Rh×q , bq∈R1×q 。
one-hot向量
我们需要将字符表示成向量,这里采用one-hot向量。假设词典大小是 N ,每次字符对应一个从 0 到 N?1 的唯一的索引,则该字符的向量是一个长度为 N 的向量,若字符的索引是 i ,则该向量的第 i 个位置为 1 ,其他位置为 0 。下面分别展示了索引为0和2的one-hot向量,向量长度等于词典大小。
我们每次采样的小批量的形状是(批量大小, 时间步数)。下面的函数将这样的小批量变换成数个形状为(批量大小, 词典大小)的矩阵,矩阵个数等于时间步数。也就是说,时间步 t 的输入为 Xt∈Rn×d ,其中 n 为批量大小, d 为词向量大小,即one-hot向量长度(词典大小)。
初始化模型参数
定义模型
裁剪梯度
循环神经网络中较容易出现梯度衰减或梯度爆炸,这会导致网络几乎无法训练。裁剪梯度(clip gradient)是一种应对梯度爆炸的方法。假设我们把所有模型参数的梯度拼接成一个向量 g ,并设裁剪的阈值是 θ 。裁剪后的梯度
min(θ∥g∥,1)g
的 L2 范数不超过 θ 。
定义预测函数
以下函数基于前缀prefix(含有数个字符的字符串)来预测接下来的num_chars个字符。这个函数稍显复杂,其中我们将循环神经单元rnn设置成了函数参数,这样在后面小节介绍其他循环神经网络时能重复使用这个函数。
困惑度
我们通常使用困惑度(perplexity)来评价语言模型的好坏。回忆一下“softmax回归”一节中交叉熵损失函数的定义。困惑度是对交叉熵损失函数做指数运算后得到的值。特别地,
- 最佳情况下,模型总是把标签类别的概率预测为1,此时困惑度为1;
- 最坏情况下,模型总是把标签类别的概率预测为0,此时困惑度为正无穷;
- 基线情况下,模型总是预测所有类别的概率都相同,此时困惑度为类别个数。
vocab_size
。定义模型训练函数
跟之前章节的模型训练函数相比,这里的模型训练函数有以下几点不同:
使用困惑度评价模型。
在迭代模型参数前裁剪梯度。
对时序数据采用不同采样方法将导致隐藏状态初始化的不同。
【公益AI-TASK03-过拟合、欠拟合及其解决方案;梯度消失、梯度爆炸;循环神经网络进阶】训练模型并创作歌词
推荐阅读
- 太平之莲
- 七年之痒之后
- 牛人进化+|牛人进化+ 按自己的意愿过一生
- 2021-02-10(找不回的“年味”……)
- 生命过客——第10章|生命过客——第10章 初为人母
- gitlab|gitlab 通过备份还原 admin/runner 500 Internal Server Error
- 回忆曾经看过的小说
- 那些年我们玩过的街机
- 说得清,说不清
- 2017-7-17