PyTorch–数据加载和处理 一、数据处理与加载 torch.utils.data.Dataset 和 torch.utils.data.DataLoader 是pytorch中高效地处理数据,帮助我们管理数据集、批量加载和数据增强的强大工具。
**full-batch:**直接加载所有的样本数据.
**mini-batch:**将样本数据分成等量的子集,训练或测试时将所有子集进行迭代,遍历完所有的样本后算作一个epoch.
mini-batch优点:可以加快训练速度;可以更有效地更新模型参数,克服鞍点;减少内存占用,尤其是处理大型数据集时,不需要一次性将整个数据集加载到内存中。
Mini-Batch 的缺点:由于每次梯度下降只使用部分数据,可能导致模型的精度较低;在训练过程中,损失函数可能会出现上下波动,但总体趋势是下降的。
**epoch:**所有的训练次数
**batch-size:**一次训练用的数据
**iteration:**内层迭代
1.dataset 通过继承 torch.utils.data.Dataset
这个抽象类 来加载自己的数据集。
Dataset 两种使用方式
将所有数据一次性加载进内存 :适用于数据规模较小的场景。
按需加载数据 :适用于数据量较大的场景,如图像或语音数据,按索引逐批加载,节约内存。
1 2 3 4 5 6 7 8 class DiadetsDataset(Dataset): def __init__(self):#初始化 pass def __getitem__(self, index):#索引 pass def __len__(self):#长度 pass dataset = DiadetsDataset()
2、dataLoader DataLoader
按批次加载数据,支持多线程加载并进行数据打乱。
1 2 3 4 5 6 7 8 9 10 11 train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, #指定batch_size,如果需要打乱数据,shuffle=True num_workers=2)#num_workers个并行进程 #for epoch in range(100): # for i,data in enumerate(train_loader,0): #这样windows下会报错 if __name__ == '__main__': for epoch in range(100): for i,data in enumerate(train_loader,0):
三、完整代码示例 刘二大人PyTorch深度学习实践 完整代码(利用matplotlib库进行可视化):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 import numpy as np import torch import matplotlib.pyplot as plt from torch.utils.data import Dataset # 是一个抽象类,只能继承,不能实例化 from torch.utils.data import DataLoader class DiadetesDataset(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 = DiadetesDataset('./data/diabetes.csv.gz') train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2) # num_workers个并行进程 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)) # 这样可以一直用x return x model = Model() criterion = torch.nn.BCELoss(reduction='mean') optimizer = torch.optim.SGD(model.parameters(), lr=0.001) epoch_list = [] loss_list = [] if __name__ == '__main__': for epoch in range(100): total_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data # 自动变成tensor y_pred = model(inputs) loss = criterion(y_pred, labels) total_loss += loss optimizer.zero_grad() loss.backward() optimizer.step() average_loss = total_loss / len(train_loader) epoch_list.append(epoch) loss_list.append(average_loss) print("Epoch:", epoch, "average loss:", average_loss) # 训练完后绘制损失曲线 # 如果 epoch_list 和 loss_list 是 Tensor epoch_list = np.array(epoch_list) # 将 epoch_list 转换为 numpy 数组 loss_list = [loss.detach().numpy() for loss in loss_list] # 对 loss_list 中的每个 tensor 进行转换 plt.plot(epoch_list, loss_list, label='Loss Curve', marker='o') plt.xlabel('Epoch') plt.ylabel('Loss') plt.title('Loss Curve') plt.legend() plt.grid(True) plt.show()