掌握PyTorch数据预处理(二):打造精准模型的基石!!!

2023-12-14 16:11:49

引言

在当今的深度学习时代,PyTorch已经成为许多机器学习研究者和工程师的首选框架。然而,仅仅依赖优秀的模型架构并不足以实现卓越的预测性能。在将数据输入模型之前,对其进行适当的预处理是至关重要的。在这篇文章中,我们将继续探讨利用PyTorch进行数据预处理的技巧,从而为你的模型奠定精准预测的基石。

掌握PyTorch数据预处理(一):让模型表现更上一层楼!!!

其他数据预处理技巧

划分数据集

使用PyTorch的数据处理工具torch.utils.data.random_split,我们可以轻松地将数据集随机划分为【训练集】、【验证集】和【测试集】。这种划分数据的方法在深度学习的实践中非常常见,因为它能帮助我们更好地理解和评估模型在不同数据集上的性能。

以下是如何使用torch.utils.data.random_split随机划分数据集的示例代码:

import torch
from torch.utils.data import DataLoader, random_split, TensorDataset

# 随机初始化数据集 dataset
random_data = torch.randn(1000, 1, 28, 28)  # 随机初始化1000个数据
random_label = torch.randint(0, 10, (1000,))  # 随机初始化1000个标签,每个标签都是从 0 到 9 之间的随机整数 
dataset = TensorDataset(random_data, random_label)  # 封装数据集

# 定义划分数据集的比例
train_ratio = 0.6  # 训练集占6成
val_ratio = 0.2  # 验证集占2成
test_ratio = 0.2  # 测试集占2成

# 确保比例总和为1
assert train_ratio + val_ratio + test_ratio == 1.0

# 计算每个集合的大小
train_size = int(train_ratio * len(dataset))
val_size = int(val_ratio * len(dataset))
test_size = len(dataset) - train_size - val_size

# 使用random_split进行划分
train_dataset, val_dataset, test_dataset = random_split(dataset, [train_size, val_size, test_size])

创建自己的数据集

在PyTorch中,要创建自己的数据集,需要继承Dataset类并实现以下两个方法:

  • __len__: 返回数据集的大小。
  • __getitem__: 根据索引返回一个数据样本。

构建Dataset子类

import torch
from torch.utils.data import Dataset
import numpy as np
from PIL import Image

class MyDataset(Dataset):
    def __init__(self, images, labels, transform=None):
        self.images = images  # 图像数据,numpy数组
        self.labels = labels  # 标签数据,列表
        self.transform = transform  # 可选的数据变换

    def __len__(self):
        # 返回数据集的大小,即图像的数量
        return len(self.images)

    def __getitem__(self, idx):
        # 根据索引返回一个数据样本
        img = self.images[idx]
        label = self.labels[idx]
        if self.transform:
            img = self.transform(img)  # 如果有定义数据变换,就应用它
        return img, label  # 返回图像和标签

创建自己的数据集(Dataset子类实例化)

示例代码如下:

import os
import numpy as np
from torchvision import transforms
from PIL import Image

# 假设 images 是一个numpy数组,包含了所有的图像数据
# 假设 labels 是一个列表,包含了所有的标签
images = np.random.rand(100, 1, 28, 28)  # 随机生成100个1x28x28的图像
labels = [0]*50 + [1]*50  # 假设有50个类别0和50个类别1的标签

# 定义一个数据变换,将PIL.Image对象转换为torch.Tensor,并标准化到[-1,1]范围内
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

# 创建MyDataset实例 ---> my_dataset 
my_dataset = MyDataset(images, labels, transform=transform)

数据加载器

在深度学习中,数据加载是一个至关重要的步骤。数据的组织方式和加载速度直接影响到模型的训练效率。PyTorch提供了一个非常方便的工具,torch.utils.data.DataLoader,可以帮助我们更有效地加载数据。

DataLoader的功能

DataLoader是一个灵活且强大的工具,主要有以下几个功能:

  1. 批量处理数据:DataLoader可以将数据划分为多个批次(batch),这对于内存有限的情况下训练大型数据集非常有用。
  2. 打乱数据:在每个训练周期(epoch)开始时,DataLoader可以随机打乱数据,这有助于减少模型过拟合并提高泛化能力。
  3. 并行加载数据:DataLoader支持使用多个子进程并行加载数据,这样可以充分利用硬件资源,提高数据加载速度。

使用DataLoader

使用DataLoader非常简单,只需要以下几个步骤:

首先,你需要将数据集转换为PyTorch的Dataset对象。这可以通过定义一个继承自torch.utils.data.Dataset的类并实现__len____getitem__方法来完成。例如:

from torch.utils.data import Dataset

class MyDataset(Dataset):
    def __init__(self, data):
        self.data = data
    
    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, index):
        return self.data[index]

然后,创建一个DataLoader对象,将数据集作为输入,并设置一些参数,如批次大小(batch size)、是否打乱数据(shuffle)等:

from torch.utils.data import DataLoader

# 假设 my_dataset 是PyTorch的`Dataset`对象
# 示例1
dataloader = DataLoader(my_dataset, batch_size=32, shuffle=True) # 需要打乱数据集,并且每个批次训练32个数据

# 示例2
dataloader = DataLoader(my_dataset, batch_size=64, shuffle=False) # 不需要打乱数据集,并且每个批次训练64个数据

# 示例3
dataloader = DataLoader(my_dataset, batch_size=64, shuffle=True, num_workers=2) # 需要打乱数据集,并且每个批次训练64个数据, 处理主进程外,还需要使用两个额外的进程【并行】加载数据

现在,可以在训练循环中使用这个dataloader。每次迭代,它都会提供一个批次的数据,示例代码如下:

for epoch in range(num_epochs):  # 迭代整个数据集多次
    for batch_data in dataloader:  # 每次获取一个批次的数据
    	...
        # 使用 batch_data 进行模型训练或评估...

结束语

如果本博文对你有所帮助/启发,可以点个赞/收藏支持一下,如果能够持续关注,小编感激不尽~
如果有相关需求/问题需要小编帮助,欢迎私信~
小编会坚持创作,持续优化博文质量,给读者带来更好de阅读体验~

文章来源:https://blog.csdn.net/qq_41813454/article/details/134902350
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。