动手学深度学习Pytorch版Task03

过拟合、欠拟合及其解决方案

1.概念
无法得到较低的训练误差称作欠拟合
得到的误差极小即远小于训练集的误差称作过拟合
2.模型选择
验证数据集
从严格意义上讲,测试集只能在所有超参数和模型参数选定后使用一次。不可以使用测试数据选择模型,如调参。由于无法从训练误差估计泛化误差,因此也不应只依赖训练数据选择模型。鉴于此,我们可以预留一部分在训练数据集和测试数据集以外的数据来进行模型选择。这部分数据被称为验证数据集,简称验证集(validation set)。例如,我们可以从给定的训练集中随机选取一小部分作为验证集,而将剩余部分作为真正的训练集。
K折交叉验证
由于验证数据集不参与模型训练,当训练数据不够用时,预留大量的验证数据显得太奢侈。一种改善的方法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成K个不重合的子数据集,然后我们做K次模型训练和验证。每一次,我们使用一个子数据集验证模型,并使用其他K-1个子数据集来训练模型。在这K次训练和验证中,每次用来验证模型的子数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。

模型复杂度

为了解释模型复杂度,我们以多项式函数拟合为例。给定一个由标量数据特征xx和对应的标量标签yy组成的训练数据集,多项式函数拟合的目标是找一个KK阶多项式函数
在这里插入图片描述
来近似 yy。在上式中,wkwk是模型的权重参数,bb是偏差参数。与线性回归相同,多项式函数拟合也使用平方损失函数。特别地,一阶多项式函数拟合又叫线性函数拟合。
给定训练数据集,模型复杂度和误差之间的关系:
在这里插入图片描述
训练数据集大小
训练数据集大小¶影响欠拟合和过拟合的另一个重要因素是训练数据集的大小。一般来说,如果训练数据集中样本数过少,特别是比模型参数数量(按元素计)更少时,过拟合更容易发生。此外,泛化误差不会随训练数据集里样本数量增加而增大。因此,在计算资源允许的范围之内,我们通常希望训练数据集大一些,特别是在模型复杂度较高时,例如层数较多的深度学习模型。

权重衰减

方法
权重衰减等价于 L2L2 范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常用手段
L2 范数正则化
L2L2范数正则化在模型原损失函数基础上添加L2L2范数惩罚项,从而得到训练所需要最小化的函数。L2L2范数惩罚项指的是模型权重参数每个元素的平方和与一个正的常数的乘积。以线性回归中的线性回归损失函数为例:
在这里插入图片描述
其中w1,w2w1,w2是权重参数,bb是偏差参数,样本ii的输入为x(i)1,x(i)2x1(i),x2(i),标签为y(i)y(i),样本数为nn。将权重参数用向量w=[w1,w2]w=[w1,w2]表示,带有L2L2范数惩罚项的新损失函数为
在这里插入图片描述
其中超参数λ>0λ>0。当权重参数均为0时,惩罚项最小。当λλ较大时,惩罚项在损失函数中的比重较大,这通常会使学到的权重参数的元素较接近0。当λλ设为0时,惩罚项完全不起作用。上式中L2L2范数平方|w|2|w|2展开后得到w21+w22w12+w22。
有了L2L2范数惩罚项后,在小批量随机梯度下降中,我们将线性回归一节中权重w1w1和w2w2的迭代方式更改为
在这里插入图片描述
可见,L2L2范数正则化令权重w1w1和w2w2先自乘小于1的数,再减去不含惩罚项的梯度。因此,L2L2范数正则化又叫权重衰减。权重衰减通过惩罚绝对值较大的模型参数为需要学习的模型增加了限制,这可能对过拟合有效。
简洁实现

def fit_and_plot_pytorch(wd):
    # 对权重参数衰减。权重名称一般是以weight结尾
    net = nn.Linear(num_inputs, 1)
    nn.init.normal_(net.weight, mean=0, std=1)
    nn.init.normal_(net.bias, mean=0, std=1)
    optimizer_w = torch.optim.SGD(params=[net.weight], lr=lr, weight_decay=wd) # 对权重参数衰减
    optimizer_b = torch.optim.SGD(params=[net.bias], lr=lr)  # 不对偏差参数衰减
    
    train_ls, test_ls = [], []
    for _ in range(num_epochs):
        for X, y in train_iter:
            l = loss(net(X), y).mean()
            optimizer_w.zero_grad()
            optimizer_b.zero_grad()
            
            l.backward()
            
            # 对两个optimizer实例分别调用step函数,从而分别更新权重和偏差
            optimizer_w.step()
            optimizer_b.step()
        train_ls.append(loss(net(train_features), train_labels).mean().item())
        test_ls.append(loss(net(test_features), test_labels).mean().item())
    d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',
                 range(1, num_epochs + 1), test_ls, ['train', 'test'])
    print('L2 norm of w:', net.weight.data.norm().item())

丢弃法

多层感知机中神经网络图描述了一个单隐藏层的多层感知机。其中输入个数为4,隐藏单元个数为5,且隐藏单元hihi(i=1,…,5i=1,…,5)的计算表达式为
在这里插入图片描述
这里ϕϕ是激活函数,x1,…,x4x1,…,x4是输入,隐藏单元ii的权重参数为w1i,…,w4iw1i,…,w4i,偏差参数为bibi。当对该隐藏层使用丢弃法时,该层的隐藏单元将有一定概率被丢弃掉。设丢弃概率为pp,那么有pp的概率hihi会被清零,有1−p1−p的概率hihi会除以1−p1−p做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量ξiξi为0和1的概率分别为pp和1−p1−p。使用丢弃法时我们计算新的隐藏单元h′ihi′
在这里插入图片描述
由于E(ξi)=1−pE(ξi)=1−p,因此
在这里插入图片描述
即丢弃法不改变其输入的期望值。让我们对之前多层感知机的神经网络中的隐藏层使用丢弃法,一种可能的结果如图所示,其中h2h2和h5h5被清零。这时输出值的计算不再依赖h2h2和h5h5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即h1,…,h5h1,…,h5都有可能被清零,输出层的计算无法过度依赖h1,…,h5h1,…,h5中的任一个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,一般不使用丢弃法

在这里插入图片描述

梯度消失和梯度爆炸

解释
假设一个层数为LL的多层感知机的第ll层H(l)H(l)的权重参数为W(l)W(l),输出H(L)H(L)的权重参数为W(L)W(L)。为了便于讨论,不考虑偏差参数,且设所有隐藏层的激活函数为恒等映射(identity mapping)ϕ(x)=xϕ(x)=x。给定输入XX,多层感知机的第ll层的输出H(l)=XW(1)W(2)…W(l)H(l)=XW(1)W(2)…W(l)。此时,如果层数ll较大,H(l)H(l)的计算可能会出现衰减或爆炸。举个例子,假设输入所有层的权重参数都是标量,如权重参数为0.2和5,多层感知机的第30层输出为输入XX分别与0.230≈1×10−210.230≈1×10−21(消失)530≈9×1020530≈9×1020
(爆炸)的乘积。当层数较多时,梯度的计算也容易出现消失或爆炸。
随机初始化模型参数
1.PyTorch的默认随机初始化
2.Xavier随机初始化
考虑环境因素
1.协变量偏移
2.标签偏移
3.概念偏移

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值