(课程笔记)深度学习入门 - 8 - DataLoader

本文详细介绍了DataLoader在PyTorch中的关键作用,包括其批处理、随机洗牌和并发预取功能。讲解了DataLoader的参数设计策略,并通过实例展示了如何使用DataLoader进行神经网络训练,包括数据集准备、模型创建、损失函数和优化器的选择,以及训练流程。
摘要由CSDN通过智能技术生成

一、DataLoader背景知识与概念

        定义:DataLoader是 PyTorch 提供的一个数据加载器,用于对数据进行批量加载和处理。它在训练神经网络时起到了重要的作用。它存在于 torch.utils.data 包下,需要的时候应该在该包下导入DataLoader。

        问题1:为什么需要DataLoader?

        神经网络的训练过程通常需要大量的数据,而将所有数据一次性加载到内存中是不可行的。这时候就需要使用 DataLoader 将数据分成小批次进行加载。DataLoader 可以自动完成数据的批量加载、随机洗牌(shuffle)、并发预取等操作,从而提高模型训练的效率。

        问题2:DataLoader有什么特点?

        (1)批处理: DataLoader 可以将数据分成小批次进行加载,从而使得每次迭代都能处理多个数据样本。

        (2)随机洗牌(shuffle): DataLoader 具有随机洗牌功能,可以在每个迭代之前将数据顺序打乱,从而减少模型对输入数据的依赖性。

        (3)并发预取(prefetching): DataLoader 可以使用多线程或多进程来提前预取数据,充分利用 CPU 的性能,加速数据加载过程。

        (4)方便的数据转换: DataLoader 可以通过自定义的数据转换函数对原始数据进行预处理,如裁剪、缩放、标准化等。

二、DataLoader的参数设计

1、DataLoader 的常用参数

dataset: 指定数据集,通常是 torch.utils.data.Dataset 类的实例。

batch_size: 每个批次的样本数量。

shuffle: 是否对数据进行洗牌操作。

num_workers: 加载数据时的并发线程或进程数。

drop_last: 当数据样本数量不能被批次大小整除时,是否丢弃最后一个不完整的批次。

collate_fn: 自定义的数据处理函数,用于将多个样本汇集到一个批次中。‘’

2、DataLoader的参数设计建议

        在调整 DataLoader 的参数时,需要根据具体问题和数据集的特点进行考虑。以下是一些常见的调整方法:

(1)batch_size根据可用内存和模型的需求,增加或减少批次大小。较大的批次大小可以提高训练速度,但也可能会增加内存占用。

(2)shuffle是否进行随机洗牌:对于训练数据,通常会设置为 True来减少模型对输入数据顺序的依赖性。对于验证和测试数据,通常会设置为False。

(3)num_workers根据计算机硬件的配置和数据加载的速度来设置,并发加载数据以加快训练速度。但是,过多的并行加载也可能会导致性能下降,因此需要进行适当的调整。

(4)drop_last默认情况下, DataLoader 不会丢弃最后一个不完整的批次。但是,在内存有限的情况下,如果内存无法容纳一个完整的批次,可以将 drop_last 设置为 True,丢弃最后一个不完整的批次。

三、用DataLoader实现神经网络训练

0、导包

import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader

1、准备数据集与DataLoader

class DiabetesDataset(Dataset):

    #   DiabetesDataset类继承自torch.utils.data.Dataset
    #   重写了__init__、__getitem__和__len__方法。

    #   1、__init__方法:它加载了名为"diabetes.csv.gz"的数据文件
    #       并将数据划分为输入特征(x_data)和目标标签(y_data)。
    #       x_data是除最后一列之外的所有列,y_data是最后一列。
    #       同时,它还记录了数据集的长度。

    #   2、__getitem__方法:用于获取指定索引的样本,返回的是该索引
    #       处的输入特征和目标标签。

    #   3、__len__方法:返回数据集的长度。



    def __init__(self, filePath):
        xy_data_set = np.loadtxt(filePath, delimiter=',', dtype=np.float32)
        self.len = xy_data_set.shape[0]
        self.x_data = torch.from_numpy(xy_data_set[:, :-1])
        self.y_data = torch.from_numpy(xy_data_set[:, [-1]])


    def __getitem__(self, index):
        return self.x_data[index], self.y_data[index]


    def __len__(self):
        return self.len

#   最后,在创建了DiabetesDataset对象后,使用DataLoader对数据集
#   进行批处理,每批大小为32,打乱顺序,并开启2个工作进程。

dataset = DiabetesDataset("diabetes.csv.gz")
train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2)

        要使用DataLoader去训练神经网络,首先要构建一个类,让这个类继承至Dataset,在这个类中重写3个方法,分别是:init,getitem,len。它们的作用分别是:

        (1)init:初始化代码,给定数据集的filePath,可以进行输入和输出的切割操作,并且记录了这个数据集有多少行,即:有多少个样本;

        (2)getitem:主要是返回指定index处的输入特征以及输出标签值

        (3)len:主要是返回数据集的样本数

        完成类的编写后,利用其构造器,传入数据集的文件路径,生成一个Dataset的实例化对象,此时开始生成DataLoader对象,利用DataLoader类的构造器,传入代表数据集的变量(dataset=?),传入批量处理数据的容量(batch_size=?),决定是否打乱数据集的数据内容(shuffle=?),设置并行线程数量(num_workers=?),这样我们就得到了一个DataLoader对象,并已经设置好了它的参数。

2、创建模型

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.linear1 = torch.nn.Linear(8, 6)
        self.linear2 = torch.nn.Linear(6, 4)
        self.linear3 = torch.nn.Linear(4, 1)
        self.sigmoid = torch.nn.Sigmoid()

    def forward(self, x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        y_pred = self.sigmoid(self.linear3(x))
        return y_pred

model = Model()

3、创建损失函数和优化器

BCE_Loss = torch.nn.BCELoss(reduction="mean")
SGD_optm = torch.optim.SGD(model.parameters(), lr=0.03)

4、开始训练

if __name__ == '__main__':
    epochs = 100

    # 设定训练的总轮数(epoch),每个epoch表示将整个数据集完整地通过模型一次。
    for epoch in range(epochs):

        # 使用enumerate函数遍历train_loader中的每个批次数据。
        # enumerate(train_loader, 0)的返回结果是一个可迭代对象iteration
        # 每次迭代会返回一个元组(index, dataTuple),其中包含了索引和对应的数据元组。
        # i表示当前批次的索引,data包含当前批次的输入特征和目标标签。(索引从0开始)

        for i, data in enumerate(train_loader, 0):

            x_data, y_label = data
            y_predict = model(x_data)
            loss = BCE_Loss(y_predict, y_label)

            print(f"Epoch = {epoch+1}, Part = {i}, Loss = {loss.item()}")

            SGD_optm.zero_grad()
            loss.backward()
            SGD_optm.step()

        这里需要注意的是:我们准备训练100轮,一轮训练32个试验数据,共计会训练3200个样本用于训练模型,循环开始时,我们需要用enumerate()函数把第一批得到的32个样本进行拆解,该函数需要传入一个DataLoader,再传入一个初始索引值,即:enumerate(train_loader , 0)。

        传入参数后,该函数会返回2个结果,第一个是index值(本节初始index为0),第二个是data元组,里面包含了这一批量样本的输入特征与输出标签值,所以要用 x_data 和 y_label 来接收这个元组中的数据。

        接收到数据后,就可以开始训练模型,以及计算损失函数了。

  • 26
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
深度学习中,使用DataLoader来定义数据加载器。数据加载器的作用是将原始数据集加载到模型中进行训练和测试。在定义DataLoader时,我们需要指定以下几个重要参数: 1. 数据集(Dataset):需要将原始数据集实例化为一个Dataset对象,该对象包含了数据集的样本和标签信息。 2. 批次大小(Batch Size):指定每次从数据集中加载的样本数量。 3. 是否打乱数据(Shuffle):可以选择在每个epoch开始时是否对数据进行打乱,以增加训练的随机性。 4. 多线程加载(Num Workers):指定用于数据加载的线程数,可以加快数据加载的速度。 5. 是否使用GPU加速(Pin Memory):如果使用GPU进行训练,可以选择将数据加载到GPU内存中以加速训练过程。 下面是一个示例代码,展示了如何定义一个简单的数据加载器: ```python import torch from torch.utils.data import DataLoader, Dataset # 自定义数据集类 class MyDataset(Dataset): def __init__(self, data, targets): self.data = data self.targets = targets def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx], self.targets[idx] # 定义数据集 data = [...] targets = [...] dataset = MyDataset(data, targets) # 定义数据加载器 batch_size = 32 shuffle = True num_workers = 4 pin_memory = True dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, pin_memory=pin_memory) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值