• 李沐深度学习记录3:11模型选择、欠拟合和过拟合


    通过多项式拟合探索欠拟合与过拟合

    import math
    import numpy as np
    import torch
    from torch import nn
    from d2l import torch as d2l
    
    #生成数据集
    max_degree = 20  # 多项式的最大阶数
    n_train, n_test = 100, 100  # 训练和测试数据集大小
    true_w = np.zeros(max_degree)  # 分配大量的空间
    true_w[0:4] = np.array([5, 1.2, -3.4, 5.6])
    
    features = np.random.normal(size=(n_train + n_test, 1))#生成均值为0,标准差为1的正态分布概率密度随机数
    np.random.shuffle(features)
    poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))
    for i in range(max_degree):
        poly_features[:, i] /= math.gamma(i + 1)  # gamma(n)=(n-1)!
    # labels的维度:(n_train+n_test,)
    labels = np.dot(poly_features, true_w)
    labels += np.random.normal(scale=0.1, size=labels.shape)  #加上噪声
    
    #分别对应常数系数、x值、x的次方再除以阶乘、算得的y值
    true_w,features,poly_features,labels=[torch.tensor(x,dtype=torch.float32) for x in [true_w,features,poly_features,labels]]
    true_w[:2],features[:2],poly_features[:2,:],labels[:2]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    #实现函数评估模型损失
    def evaluate_loss(net,data_iter,loss):
        '''评估给定数据集上模型的损失'''
        metric=d2l.Accumulator(2) #记录 损失的总和,样本数量
        for X,y in data_iter:
            out=net(X)
            y=y.reshape(out.shape)
            l=loss(out,y)
            metric.add(l.sum(),l.numel())
        return metric[0]/metric[1]
    
    #from torch.utils import data
    
    #定义训练函数
    def train(train_features, test_features, train_labels, test_labels,
              num_epochs=400):
        loss = nn.MSELoss(reduction='none')
        input_shape = train_features.shape[-1]
        # 不设置偏置,因为我们已经在多项式中实现了它
        net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
        batch_size = min(10, train_labels.shape[0])
        #print(train_labels.shape)   [100]
        #print(train_labels.shape[0])   100
        #print(batch_size)   10
        train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)),
                                    batch_size)
        #等价于以下两行代码
    #     train_dataset=data.TensorDataset(train_features,train_labels.reshape(-1,1))
    #     train_iter=data.DataLoader(train_dataset,batch_size,shuffle=True)
        
        test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)),
                                   batch_size, is_train=False)
        trainer = torch.optim.SGD(net.parameters(), lr=0.01)
        animator = d2l.Animator(xlabel='epoch', ylabel='loss', yscale='log',
                                xlim=[1, num_epochs], ylim=[1e-3, 1e2],
                                legend=['train', 'test'])
        for epoch in range(num_epochs):
            d2l.train_epoch_ch3(net, train_iter, loss, trainer) #训练模型一个迭代周期
            if epoch == 0 or (epoch + 1) % 20 == 0:   #每20个epoch训练迭代周期,评估一次模型损失(包括训练集和测试集),画一次数据点
                animator.add(epoch + 1, (evaluate_loss(net, train_iter, loss),  #评估训练数据集上模型损失
                                         evaluate_loss(net, test_iter, loss)))  #评估测试数据集上模型损失
        print('weight:', net[0].weight.data.numpy())  #输出最终模型的参数权重
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    #使用三阶多项式拟合,与数据生成函数的阶数相同(正常)
    # 从多项式特征中选择前4个维度,即1,x,x^2/2!,x^3/3!
    train(poly_features[:n_train, :4], poly_features[n_train:, :4],
          labels[:n_train], labels[n_train:])
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    #使用线性函数拟合非线性函数(这里是三阶多项式函数),线性模型很容易欠拟合
    # 从多项式特征中选择前2个维度,即1和x
    train(poly_features[:n_train, :2], poly_features[n_train:, :2],
          labels[:n_train], labels[n_train:])
    
    • 1
    • 2
    • 3
    • 4

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/10ad87a962cf40ccb39909b0fa84c7ea.png

    #使用一个阶数过高的复杂多项式模型来训练会造成过拟合。在这种情况下,没有足够的数据用于学到高阶系数应该具有接近于零的值。 因此,这个过于复杂的模型会轻易受到训练数据中噪声的影响。 虽然训练损失可以有效地降低,但测试损失仍然很高。 
    # 从多项式特征中选取所有维度
    train(poly_features[:n_train, :], poly_features[n_train:, :],
          labels[:n_train], labels[n_train:], num_epochs=1500)
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

  • 相关阅读:
    CPU性能优化干货总结
    代码随想录二刷 day04 | 链表之 24两两交换链表中的节点 19删除链表的倒数第N个节点 面试题 02.07. 链表相交 142.环形链表II
    《无条件养育》读书笔记
    Docker学习-目录
    【附源码】计算机毕业设计JAVA学习自律养成小程序前台.mp4
    java毕业设计“传情旧物”网站(附源码、数据库)
    C#计算不规则多边形关系
    【计算机网络】 拥塞控制
    【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
    “could not open `CProgram FilesJavajre7libamd64jvm.cfg”问题解决办法
  • 原文地址:https://blog.csdn.net/qq_46238275/article/details/133579422