【深度学习】Pytorch 教程(十四):PyTorch数据结构:6、数据集(Dataset)与数据加载器(DataLoader):自定义鸢尾花数据类

2024-07-30 11:17:25 浏览数 (3)

一、前言

  本文将介绍PyTorch中数据集(Dataset)与数据加载器(DataLoader),并实现自定义鸢尾花数据类

二、实验环境

  本系列实验使用如下环境

代码语言:javascript复制
conda create -n DL python==3.11
代码语言:javascript复制
conda activate DL
代码语言:javascript复制
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia

三、PyTorch数据结构

1、Tensor(张量)

  Tensor(张量)是PyTorch中用于表示多维数据的主要数据结构,类似于多维数组,可以存储和操作数字数据。

1. 维度(Dimensions)

  Tensor(张量)的维度(Dimensions)是指张量的轴数或阶数。在PyTorch中,可以使用size()方法获取张量的维度信息,使用dim()方法获取张量的轴数。

2. 数据类型(Data Types)

  PyTorch中的张量可以具有不同的数据类型:

  • torch.float32或torch.float:32位浮点数张量。
  • torch.float64或torch.double:64位浮点数张量。
  • torch.float16或torch.half:16位浮点数张量。
  • torch.int8:8位整数张量。
  • torch.int16或torch.short:16位整数张量。
  • torch.int32或torch.int:32位整数张量。
  • torch.int64或torch.long:64位整数张量。
  • torch.bool:布尔张量,存储True或False。

【深度学习】Pytorch 系列教程(一):PyTorch数据结构:1、Tensor(张量)及其维度(Dimensions)、数据类型(Data Types)

3. GPU加速(GPU Acceleration)

【深度学习】Pytorch 系列教程(二):PyTorch数据结构:1、Tensor(张量): GPU加速(GPU Acceleration)

2、张量的数学运算

  PyTorch提供了丰富的操作函数,用于对Tensor进行各种操作,如数学运算、统计计算、张量变形、索引和切片等。这些操作函数能够高效地利用GPU进行并行计算,加速模型训练过程。

1. 向量运算

【深度学习】Pytorch 系列教程(三):PyTorch数据结构:2、张量的数学运算(1):向量运算(加减乘除、数乘、内积、外积、范数、广播机制)

2. 矩阵运算

【深度学习】Pytorch 系列教程(四):PyTorch数据结构:2、张量的数学运算(2):矩阵运算及其数学原理(基础运算、转置、行列式、迹、伴随矩阵、逆、特征值和特征向量)

3. 向量范数、矩阵范数、与谱半径详解

【深度学习】Pytorch 系列教程(五):PyTorch数据结构:2、张量的数学运算(3):向量范数(0、1、2、p、无穷)、矩阵范数(弗罗贝尼乌斯、列和、行和、谱范数、核范数)与谱半径详解

4. 一维卷积运算

【深度学习】Pytorch 系列教程(六):PyTorch数据结构:2、张量的数学运算(4):一维卷积及其数学原理(步长stride、零填充pad;宽卷积、窄卷积、等宽卷积;卷积运算与互相关运算)

5. 二维卷积运算

【深度学习】Pytorch 系列教程(七):PyTorch数据结构:2、张量的数学运算(5):二维卷积及其数学原理

6. 高维张量

【深度学习】pytorch教程(八):PyTorch数据结构:2、张量的数学运算(6):高维张量:乘法、卷积(conv2d~ 四维张量;conv3d~五维张量)

3、张量的统计计算

【深度学习】Pytorch教程(九):PyTorch数据结构:3、张量的统计计算详解

4、张量操作

1. 张量变形

【深度学习】Pytorch教程(十):PyTorch数据结构:4、张量操作(1):张量变形操作

2. 索引
3. 切片

【深度学习】Pytorch 教程(十一):PyTorch数据结构:4、张量操作(2):索引和切片操作

4. 张量修改

【深度学习】Pytorch 教程(十二):PyTorch数据结构:4、张量操作(3):张量修改操作(拆分、拓展、修改)

5、张量的梯度计算

【深度学习】Pytorch教程(十三):PyTorch数据结构:5、张量的梯度计算:变量(Variable)、自动微分、计算图及其可视化

6、数据集(Dataset)与数据加载器(DataLoader)

  数据集(Dataset)是指存储和表示数据的类或接口。它通常用于封装数据,以便能够在机器学习任务中使用。数据集可以是任何形式的数据,比如图像、文本、音频等。数据集的主要目的是提供对数据的标准访问方法,以便可以轻松地将其用于模型训练、验证和测试。

  数据加载器(DataLoader)是一个提供批量加载数据的工具。它通过将数据集分割成小批量,并按照一定的顺序加载到内存中,以提高训练效率。数据加载器常用于训练过程中的数据预处理、批量化操作和数据并行处理等。

以下是一个具体案例,介绍如何使用PyTorch中的数据集和数据加载器:

代码语言:javascript复制
import torch
from torch.utils.data import Dataset, DataLoader

# 定义自定义数据集类
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]

# 创建数据集实例
data = [1, 2, 3, 4, 5]
dataset = MyDataset(data)

# 创建数据加载器实例
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)

# 遍历数据加载器
for batch in dataloader:
    print(batch)

在上面的案例中,首先定义了一个自定义数据集类MyDataset,包含了__len____getitem__两个方法。__len__方法返回数据集的长度,__getitem__方法根据给定的索引返回数据集中的样本。

然后,创建了一个数据集实例dataset,传入了一组示例数据。再创建数据加载器实例dataloader,设置了批量大小为2,并开启了数据的随机打乱。

最后,在遍历数据加载器的过程中,每次打印出的batch是一个批量大小为2的数据。在实际应用中,可以根据具体的需求对每个批次进行进一步的处理和训练。

1. 数据集(Dataset)

  PyTorch中,Dataset(数据集)是用于存储和管理训练、验证或测试数据的抽象类。它是一个可迭代的对象,可以通过索引或迭代方式访问数据样本。

  PyTorch提供了torch.utils.data.Dataset类,可以通过继承该类来创建自定义的数据集。自定义数据集时需要实现下面两个主要的方法:

  • __len__()方法:返回数据集中样本的数量
  • __getitem__(index)方法:根据给定的索引index,返回对应位置的数据样本
代码语言:javascript复制
import torch
from torch.utils.data import Dataset

class CustomDataset(Dataset):
    def __init__(self, data):
        self.data = data
    
    def __len__(self):
        return len(self.data)
    
    def __getitem__(self, index):
        sample = self.data[index]
        # 可以继续添加对数据样本进行预处理或转换操作
        # 返回经过处理的数据样本
        return sample

# 自定义数据
data = [1, 2, 3, 4, 5]
dataset = CustomDataset(data)

# 访问数据集中的样本
sample = dataset[0]
print(sample)  # 输出: 1

  使用自定义数据集时,可以将其与 torch.utils.data.DataLoader结合使用,以便更方便地进行数据的批量加载和处理。

2. 数据加载器(DataLoader)

  DataLoader(数据加载器)是用于批量加载和处理数据的实用工具。它提供了对数据集的迭代器,并支持按照指定的批量大小、随机洗牌等方式加载数据

  • 批量加载数据:DataLoader可以从数据集中按照指定的批量大小加载数据。每个批次的数据可以作为一个张量或列表返回,便于进行后续的处理和训练。
  • 数据随机洗牌:通过设置shuffle=True,DataLoader可以在每个迭代周期中对数据进行随机洗牌,以减少模型对数据顺序的依赖性,提高训练效果。
  • 多线程数据加载:DataLoader支持使用多个线程来并行加载数据,加快数据加载的速度,提高训练效率。
  • 数据批次采样:除了按照批量大小加载数据外,DataLoader还支持自定义的数据批次采样方式。可以通过设置batch_sampler参数来指定自定义的批次采样器,例如按照指定的样本顺序或权重进行采样。
代码语言:javascript复制
import torch
from torch.utils.data import Dataset, DataLoader


# 自定义数据集类
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]


# 自定义数据加载器类
class MyDataLoader(DataLoader):
    def __init__(self, dataset, batch_size=1, shuffle=False, num_workers=0):
        super().__init__(dataset, batch_size, shuffle, num_workers=num_workers)

    def collate_fn(self, batch):
        # 自定义的数据预处理、合并等操作
        # 这里只是简单地将样本转换为Tensor,并进行堆叠
        return torch.stack(batch)


# 自定义数据集类
data = [1, 2, 3, 4, 5]
dataset = MyDataset(data)

# 创建数据加载器实例
dataloader = MyDataLoader(dataset, batch_size=2, shuffle=True)

# 遍历数据加载器
for batch in dataloader:
    # batch是一个包含多个样本的张量(或列表)
    # 这里可以对批次数据进行处理
    print(batch)

  在创建DataLoader时,指定了批量大小batch_size和是否随机洗牌shuffle。

通过DataLoader加载数据集后,使用for循环迭代加载数据批次。每个批次的数据将作为一个张量或列表返回,可以根据需要在循环中对批次数据进行处理。

3. 实战——鸢尾花数据集
代码语言:javascript复制
import torch
from sklearn.datasets import load_iris
from torch.utils.data import Dataset, DataLoader
 
# 此函数用于加载鸢尾花数据集
def load_data(shuffle=True):
    x = torch.tensor(load_iris().data)
    y = torch.tensor(load_iris().target)
 
    # 数据归一化
    x_min = torch.min(x, dim=0).values
    x_max = torch.max(x, dim=0).values
    x = (x - x_min) / (x_max - x_min)
 
    if shuffle:
        idx = torch.randperm(x.shape[0])
        x = x[idx]
        y = y[idx]
    return x, y
 
# 自定义鸢尾花数据类
class IrisDataset(Dataset):
    def __init__(self, mode='train', num_train=120, num_dev=15):
        super(IrisDataset, self).__init__()
        x, y = load_data(shuffle=True)
        if mode == 'train':
            self.x, self.y = x[:num_train], y[:num_train]
        elif mode == 'dev':
            self.x, self.y = x[num_train:num_train   num_dev], y[num_train:num_train   num_dev]
        else:
            self.x, self.y = x[num_train   num_dev:], y[num_train   num_dev:]
 
    def __getitem__(self, idx):
        return self.x[idx], self.y[idx]
 
    def __len__(self):
        return len(self.x)
 
batch_size = 16
 
# 分别构建训练集、验证集和测试集
train_dataset = IrisDataset(mode='train')
dev_dataset = IrisDataset(mode='dev')
test_dataset = IrisDataset(mode='test')
 
train_loader = DataLoader(train_dataset, batch_size=batch_size,shuffle=True)
dev_loader = DataLoader(dev_dataset, batch_size=batch_size)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=True)

0 人点赞