学习笔记-PyTorch-常用数据形式以及加载处理

1.常用数据形式

        此处所说的数据形式是指数据集中的数据加载到模型中的形式,常见数据形式包括全批次Batch、迷你批次Mini-Batch。全批次Batch处理是指在每次迭代中处理整个数据集,计算损失函数和参数梯度,然后更新模型参数。这种方法每次更新参数都需要遍历所有样本,导致计算量大、速度慢,不适合在线学习场景。但是如果数据输入变为串行,将无法充分利用GPU的并行计算优势。而迷你批次Mini-Batch处理通过每次仅处理一小部分数据来进行梯度计算,既能够利用GPU的并行处理能力,又能减轻处理大规模数据集时的计算负担,且在训练过程中可以动态调整模型参数,更好地适应在线学习的需求。

        常见的一些参数:

  • Epoch(训练周期):指对整个训练数据集进行一次完整的前向传播和后向传播。在每个Epoch中,模型会遍历所有的训练样本。

  • Batch-Size(批次大小):指在一次前向传播和后向传播中处理的训练样本数量。批次大小决定了每次迭代中处理的数据量。

  • Iteration(迭代):指在一个Epoch中,模型进行的前向传播和后向传播的次数。迭代次数等于训练样本总数除以批次大小(即 total_samples / batch_size)。每次迭代处理一个批次的数据,进行一次参数更新。

          例如,如果一个训练数据集有1000个样本,批次大小设置为100,那么在一个Epoch中,模型将进行10次迭代(1000 / 100 = 10),每次迭代处理100个样本。

        Dataset是一个抽象类,定义了数据集的基本结构和操作方法,主要用于存储数据和标签,能够返回数据集中样本的数量,并能根据索引获取数据集中的一个样本及其对应的标签。直接import的Dataset是一个抽象类,不能被直接实例化,需要重新构造Dataset的子类,再去实例化,且该子类必须实现__init__、__getitem__、__len__这三个核心方法,直接使用PASS是不可以的,一定要准确定义该类应该如何访问和处理数据集。

        DataLoader是一个迭代器,用于从 Dataset中加载数据,并提供更高级的数据加载功能,如批量加载、打乱数据、多线程加载、数据采样等。可直接使用DataLoader的API完成该任务:

  • dataset:要加载的数据集,是一个实现了 __getitem____len__ 方法的 Dataset 对象。

  • batch_size:每个批次中的样本数量。如果设置为 None,则每个批次将包含所有数据集中的样本。

  • shuffle:如果设置为 True,则在每个epoch开始时打乱数据集,确保每个批次的样本都是随机选取的。如果不打乱数据可能导致模型学习到这种顺序偏差,而不是数据的真实特征。

  • sampler:定义从数据集中抽取样本的策略。如果指定了 sampler,则 shuffle 参数将被忽略。

  • batch_sampler:类似于 sampler,但用于生成批次的索引。如果指定了 batch_sampler,则 batch_sizeshufflesamplerdrop_last 参数将被忽略。

  • num_workers:用于数据加载的工作进程数。如果设置为0,则数据加载将在主进程中进行。设置为大于0的值可以加速数据加载,但可能会增加内存消耗。

  • collate_fn:一个函数,用于在将多个样本数据合并成一个批次之前对它们进行处理。默认情况下,它简单地堆叠张量。

  • pin_memory:如果设置为 True,则数据加载器会在返回之前将数据固定到内存中,这可以加速CPU到GPU的数据传输。

  • drop_last:如果设置为 True,则如果数据集的大小不能被 batch_size 整除,则丢弃最后一个不完整的批次。

  • timeout:数据加载器等待工作进程完成加载的时间(以秒为单位)。如果设置为0,则不会等待。

  • worker_init_fn:一个函数,用于在工作进程启动时调用,可以用于设置一些特定的环境变量或种子。

  • prefetch_factor:(关键字参数)预取批次的数量,用于提高数据加载的效率。默认值为2。

  • persistent_workers:(关键字参数)如果设置为 True,则在迭代器耗尽后保持工作进程活跃,这可以加速后续迭代器的开始。默认值为 False

class DiabetesDataset(Dataset):   #Dataset是抽象类,不能被实例化
    def __init__(self,filepath):
        xy=np.loadtxt(filepath,delimiter=',',dtype=np.float32)
        self.len=xy.shape[0]
        self.x_data=torch.from_numpy(xy[:,:-1])
        self.y_data=torch.from_numpy(xy[:,[-1]])
    def __getitem__(self,index):  #魔法方法,可直接把类当函数使用
        return self.x_data[index],self.y_data[index]
    def __len__(self):            #魔法方法,可直接把类当函数使用
        return self.len
    
dataset=DiabetesDataset('diabetes.csv.gz')
train_loader=DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=2)

2.完整代码

import torch
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import numpy as np
import matplotlib.pyplot as plt


class DiabetesDataset(Dataset):   #Dataset是抽象类,不能被实例化
    def __init__(self,filepath):
        xy=np.loadtxt(filepath,delimiter=',',dtype=np.float32)
        self.len=xy.shape[0]
        self.x_data=torch.from_numpy(xy[:,:-1])
        self.y_data=torch.from_numpy(xy[:,[-1]])
    def __getitem__(self,index):  #魔法方法,可直接把类当函数使用
        return self.x_data[index],self.y_data[index]
    def __len__(self):            #魔法方法,可直接把类当函数使用
        return self.len
    
dataset=DiabetesDataset('diabetes.csv.gz')
train_loader=DataLoader(dataset=dataset,batch_size=32,shuffle=True)

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))
        x=self.sigmoid(self.linear3(x))
        return x

model=Model()
criterion=torch.nn.BCELoss(reduction='mean')          #计算损失,括号内的参数是是否算平均值
optimizer=torch.optim.SGD(model.parameters(),lr=0.01)

loss_list=[]
for epoch in range(100):
    for i,data in enumerate(train_loader,0):
        inputs,labels=data
        y_pred=model(inputs)
        loss=criterion(y_pred,labels)
        loss_list.append(loss.item())
        print(epoch,i,loss.item())
        optimizer.zero_grad()
        loss.backward()
        optimizer. Step()

  

        输出结果如下所示,第一列表示第几轮,第二列表示这一轮第几个Batch,最后一列表示这一个Batch的平均误差。可以看到第二轮的时候,第4Batch的平均误差就明显下降了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值