首页人工智能Pytorch【深度学习(PyTorch...

【深度学习(PyTorch篇)】23.数据集划分

本系列文章配套代码获取有以下两种途径:

  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1XuxKa9_G00NznvSK0cr5qw?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/PyTorch





01

数据集划分


通过合理划分和使用训练集、验证集和测试集,我们可以更有效地训练神经网络模型,评估其性能,并确保其在实际应用中的泛化能力。

评估模型效果的主要依据是模型在数据集上的表现如何。数据集主要分为训练集(Training set)、验证集(Validation set)、测试集(Test set)三个数据集合。这三类数据集在神经网络模型评估中的作用各不相同:
  • 训练集(Training Set):
训练集用于训练模型,即调整模型的参数以最小化训练数据上的误差。这是通过反向传播和优化算法(如梯度下降)来实现的。
训练集是模型学习的基础。没有足够多样和代表性的训练数据,模型可能无法学习到必要的特征和模式,导致性能不佳。
  • 验证集(Validation Set):
验证集用于在训练过程中评估模型的性能。它不直接参与模型的训练,而是用来检查模型在训练数据之外的泛化能力。通常,我们会在每个训练周期(epoch)结束后,使用验证集来评估模型的性能,并根据这些评估结果来调整超参数或选择最佳的模型。
验证集有助于防止过拟合(即模型在训练数据上表现良好,但在未见过的数据上表现糟糕)。通过监控验证集上的性能,我们可以及时停止训练,避免模型过度拟合训练数据。
  • 测试集(Test Set):
测试集用于评估最终模型的性能。它只在模型训练完成后使用一次,以评估模型在完全未见过的数据上的性能。测试集的性能指标通常被视为模型性能的最终评估。
测试集提供了模型在实际应用中可能遇到的性能的真实估计。由于测试集在模型训练过程中是未知的,因此其评估结果是公正的,不受训练过程中的任何偏见影响。
02

划分数据集完成神经网络模型:


下面在上一篇构建的神经网络基础上完善。
  • 生成数据:
因需划分数据集,因此本次将生成100个样本数据。
# 设置随机数种子,保证运行结果一致
torch.manual_seed(2024)

def get_fake_data(num):
    """
    生成随机数据,y = 0.5 * x +30并加上一些随机噪声
    """

    x = torch.randint(low = -5, high=30, size=(num,)).to(dtype=torch.float32)
    y = 0.5 * x +30 + torch.randn(num,)
    return x,y

# 生成数据
x , y = get_fake_data(num=100)
x = x * 0.1

# 增加batch维度
x = x.unsqueeze(1)
y = y.unsqueeze(1)
  • 划分数据集:
本次根据7:2:1来划分数据集,使用torch.randperm()函数获取随机打乱的数据集。
# 样本总数量
n_sample = x.shape[0]

# 划分数据集
n_train = int(0.7*n_sample)
n_val = int(0.2*n_sample)
n_test = int(0.1*n_sample)

# 给定一个整数 n 作为输入,它会返回一个从 0 到 n-1 的随机排列的整数张量
suffled_indices = torch.randperm(n_sample)

# 索引张量
train_indices = suffled_indices[:n_train]
val_indices = suffled_indices[n_train:n_train+n_val]
test_indices = suffled_indices[n_train+n_val:]

# 使用索引张量构建数据集
train_x = x[train_indices]
val_x = x[val_indices]
test_x = x[test_indices]

train_y = y[train_indices]
val_y = y[val_indices]
test_y = y[test_indices]
对生成的数据集进行可视化。
# 可视化数据集
fig = plt.figure()
plt.plot(train_x , train_y , 'co' ,label='Training set',markersize=5)
plt.plot(val_x , val_y , '
r*' ,label='Validation set',markersize=7)
plt.plot(test_x , test_y , '
b^' ,label='Test set',markersize=7)

plt.legend()
结果如下所示:

  • 定义模型:
依次构建神经网络模型:
# 神经网络模型
seq_model = nn.Sequential(
    nn.Linear(1,100) ,
    nn.Tanh() ,
    nn.Linear(100,10),
    nn.Tanh() ,
    nn.Linear(10,1)
)
定义损失函数
# 定义损失函数
loss_fn = nn.MSELoss()
实例化优化器
# 实例化一个优化器
learning_rate=1e-2

optimizer = torch.optim.SGD(seq_model.parameters() , lr=learning_rate)
定义训练循环
为了节省开销,使用torch.no_grad()上下文管理器,在验证过程时关闭自动求导。
from IPython import display

# 设置全局字体
plt.rcParams["font.sans-serif"] = "Microsoft YaHei"

def training_loop(n_epochs , optimizer , model , loss_fn , train_x , train_y , val_x , val_y):

    # 记录损失的列表
    train_losses = []
    val_losses = []

    for epoch in range(1 , n_epochs+1):
        #前向传播
        y_p = model(train_x)
        train_loss = loss_fn(y_p ,train_y)

        # 验证过程
        with torch.no_grad():
            val_p = model(val_x)
            val_loss = loss_fn(val_p ,val_y)

        # 梯度归零
        optimizer.zero_grad()
        # 反向传播
        train_loss.backward()
        # 参数更新
        optimizer.step()

        # 记录损失
        train_losses.append(train_loss.item())
        val_losses.append(val_loss.item())

        if epoch % 10 ==0:
            print(f"Epoch : {epoch} , Train_Loss : {train_loss} , Val_Loss : {val_loss}")
            print("-----")


    return train_losses,val_losses
  • 循环训练:
设置参数,迭代500次。
train_losses,val_losses = training_loop(
    n_epochs=500 ,
    optimizer=optimizer , 
    model=seq_model , 
    loss_fn=loss_fn , 
    train_x=train_x , 
    train_y=train_y , 
    val_x=val_x , 
    val_y=val_y)
通过模型输出可以看到验证损失比训练损失要大,这是因为模型是在训练集上训练出来的。
只要两者的损失值较为接近,我们就可以认为模型学习到了关于数据集的一般性知识。
  • 测试集拟合效果:
采用均方误差作为评价指标来评价模型在测试数据集上的效果。
loss_fn(test_y , seq_model(test_x))
通过输出结果可以看到模型在测试集上的损失相比训练集和验证集要大,只要没有显著差距,这都是一个常见现象。
  • 可视化结果:
将数据集以及模型拟合曲线进行可视化显示。
# 原始数据
plt.scatter(train_x , train_y , color="gray" , marker='o' ,label='Training set',s=30)
plt.scatter(val_x , val_y , color="gray" , marker='*' ,label='Validation set',s=30)
plt.scatter(test_x , test_y , color="r" , marker='^' ,label='Test set',s=30)

# 获取xy轴的范围
xmin,xmax,ymin,ymax = plt.axis()
# 输入,模型预测值
plt.plot(torch.arange(xmin , xmax , 0.1).numpy() , seq_model(torch.arange(xmin , xmax , 0.1).unsqueeze(1)).detach().numpy() , 'b-' , label="神经网络模型")
# plt.plot(test_x , seq_model(test_x).detach().numpy() , 'k+' ,markersize=10 , label="神经网络模型预测值")

plt.legend()
plt.show()
结果如下所示:


更多内容可以前往官网查看

https://pytorch.org/


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments