PyTorch入门之数据集构建

自定义神经网络训练数据集

区别于其他的机器学习模型,BP(Back Propagation)神经网络的训练多采用一些基于梯度下降的算法对网络的权重和偏置进行逐步地调整,是一个迭代进行的过程。因此,在训练网络之前,需要对数据集进行一些操作,将其封装成适合迭代训练的形式。这篇文章将介绍两种对数据集进行封装的方法。

torch.utils.data.TensorDataset

采用 TensorDataset 对数据集进行封装相对比较简单,但是能够满足大多数的应用需求。

首先看一下 PyTorch 1.2.0 文档当中对于 TensorDataset 类的描述。

CLASS torch.utils.data.TensorDataset(*tensors)
Dataset wrapping tensors.
Each sample will be retrieved by indexing tensors along the first dimension.

along first dimension指的是按照行号对数据集进行索引。因为一般来说,数据集是按照(sample_num, input_size)的形式进行排布的,也就是每行代表一个样本。

下面提供一个简单的例子。

import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler from torch.utils.data import TensorDataset, DataLoader df_data = pd.read_excel('excel_data.xlsx') # 假设输出变量在第一列 scaler = MinMaxScaler() norm_data = scaler.fit_transform(df_data) # norm_data的类型为 numpy.ndarray  x, y = torch.from_numpy(norm_data[:, 1:]), torch.from_numpy(norm_data[:, 0:1]) # 将数据转变成 Tensor 类型 data_set = TensorDataset(x, y) # 输入变量在前,输出变量在后 # 采用 DataLoader 封装 data_set 即可得到能够用于训练神经网络的 data_loader data_loader = DataLoader(dataset=data_set, batch_size=400, shuffle=True, drop_last=False) 

DataLoader 是数据集封装过程中必不可少的一步。因为在神经网络的训练过程中,每一轮的网络权重更新并不是基于全部的训练数据,而是基于一部分数据(具体来说就是batch_size个数据)来进行的。

PyTorch 1.2.0 官方文档当中对 DataLoader 是这样介绍的:

Data loader. Combines a dataset and a sampler, and provides an iterable over the given dataset.

其中,sampler可以理解为采样器,它决定了每轮训练时如何从整个数据集当中选择出batch_size个数据。那么,DataLoader 的作用其实就是将数据集和采样器进行组合,并提供一个可迭代对象。其中的几个常用参数的含义如下:

  • dataset - 需要封装的数据集。
  • batch_size - 每个 batch 包含多少个样本,即每轮训练从全部数据集中选出 batch_size 个样本提供给神经网络。默认值为 1。
  • shuffle - 设置为 True 表示打乱数据集。默认值为 False。
  • drop_last - 设置为 True 表示丢弃不足一个batch的数据。例如共有 930 条数据,当设置batch_size = 90时,数据集就会被分为 90 × 10 + 30,如果设置了drop_last = True,多余的 30 条数据就不会参与到训练当中。默认值为 False。

torch.utils.data.Dataset

除了上面那种比较简洁方便的封装方法之外,还可以通过继承 PyTorch 所提供的 Dataset 类来自定义一个能够供 DataLoader 进行分装的数据集。代码示例如下:

from torch.utils.data import Dataset, DataLoader import numpy as np class MyDataSet(Dataset): def __init__(self, path): """可以在初始化函数当中对数据进行一些操作,比如读取、归一化等""" self.data = np.loadtxt(path) # 读取 txt 数据 self.x = self.data[:, 1:] # 输入变量 self.y = self.data[:, 0] # 输出变量 def __len__(self): """返回数据集当中的样本个数""" return len(self.data) def __getitem__(self, index): """返回样本集中的第 index 个样本;输入变量在前,输出变量在后""" return self.x[index, :], self.y[index] data_set = MyDataSet('data.txt') data_loader = DataLoader(dataset=data_set, batch_size=400, shuffle=True, drop_last=False) 

通过这种方式定义数据集,只要实现__len__()和__getitem__()两个方法即可;其中__len__()的作用是返回数据集当中的样本总个数,__getitem__()的作用是返回指定索引的样本所对应的输入变量与输出变量。除此之外,可以在 MyDataSet 这个类当中按需要定义任何操作。

#学习路径#
全部评论
感谢楼主分享!!!
点赞 回复 分享
发布于 2022-02-22 12:48

相关推荐

明明就不饿:看不懂你到底会啥,什么岗位
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务