目录
【1】在进行神经网络训练的时候,对数据的处理包括:
使用dataset 构建数据
dataloader进行batch的划分
Pytorch导入数据主要依靠 torch.utils.data.DataLoader
和 torch.utils.data.Dataset
这两个类来完成。
ps:batch的划分:将数据进行一个划分,使得训练速度更快
【2】dataset:
torch.utils.data.Dataset:这是一个抽象类,所以我们需要对其进行派生,从而使用其派生类来创建数据集。最主要的两个函数实现为__Len__和__getitem__。
__init__:可以在这里设置加载的data和label。
__Len__:获取数据集大小
__getitem__:根据索引获取一条训练的数据和标签。
torch.utils.data.DataLoader:接收torch.utils.data.Dataset作为输入,得到DataLoader,它是一个迭代器,方便我们去多线程地读取数据,并且可以实现batch以及shuffle的读取等。
输入:data_list
data_list
是一个列表,其中每个元素都表示一个数据样本。每个数据样本通常会包含一个输入张量和一个标签张量,格式可以根据具体的应用自行定义。
import torch
# 生成随机数据
x_data = torch.randn(100, 1)
y_data = 2 * x_data + 1
# 将数据封装成元组形式,并存储到列表中
data_list = [(x, y) for x, y in zip(x_data, y_data)]
示例代码学习:
import torch
from torch.utils.data import Dataset
class myDataset(Dataset):
def __init__(self):
#创建5*2的数据集
self.data = torch.tensor([[1,2],[3,4],[2,1],[3,4],[4,5]])
#5个数据的标签
self.label = torch.tensor([0,1,0,1,2])
#根据索引获取data和label
def __getitem__(self,index):
return self.data[index], self.label[index] #以元组的形式返回
#获取数据集的大小
def __len__(self):
return len(self.data)
data = myDataset()
print(f'data size is : {len(data)}')
print(data[1]) #获取索引为1的data和label
data size is : 5
(tensor([3, 4]), tensor(1))
torch.utils.data.Dataset
通过__getitem__
获取单个数据,如果希望获取批量数据、shuffle或者其它的一些操作,那么就要由torch.utils.data.DataLoader来实现了,它的实现形式如下:
data.DataLoader(
dataset,
batch_size = 50,
shuffle = False,
sampler=None,
batch_sampler = None,
num_workers = 0,
collate_fn =
pin_memory = False,
drop_last = False,
timeout = 0,
worker_init_fn = None,
)dataset:待传入的数据集,也就是上面自己实现的myData。
batch_size:每个batch有多少个样本
shuffle:代表数据会不会被随机打乱,在每个epoch开始的时候,对数据进行重新排序。
sampler:自定义从数据集中取样本的策略,如果指定这个参数,那么shuffle必须为False
batch_sampler:类似于sampler,不过返回的是一个迷你批次的数据索引。
num_workers:是数据载入器使用的进程数目,默认为0。
collate_fn:用于自定义sample 如何形成 batch sample 的函数。因为getitem只是得到一条数据,collate_fun组成一个batch数据
pin_memory:如果设置为True,那么data loader将会在返回它们之前,将tensors拷贝到CUDA中的固定内存(CUDA pinned memory)中。
drop_last:如果设置为true,那么最后的batch的大小如果小于batch_size,那么则会丢弃。
timeout:如果是正数,表明等待从worker进程中收集一个batch等待的时间,若超出设定的时间还没有收集到,那就不收集这个内容了。这个numeric应总是大于等于0。默认为0。
worker_init_fn:它决定了每个数据载入的子进程开始时运行的函数
示例:
设置了drop_last = True
,最后一个batch会被丢弃。
from torch.utils.data import DataLoader
data = myDataset()
my_loader = DataLoader(data,batch_size=2,shuffle=False,num_workers = 0,drop_last=True)
for step,train_data in enumerate(my_loader):
Data,Label = train_data
print("step:",step)
print("data:",Data)
print("Label:",Label)
step: 0
data: tensor([[1, 2],
[3, 4]])
Label: tensor([0, 1])
step: 1
data: tensor([[2, 1],
[3, 4]])
Label: tensor([0, 1])
【3】dataset tensordataset:
TensorDataset
是torch.utils.data.Dataset
的子类,而Dataset
是所有自定义数据集的基类。两者之间最大的不同在于数据存储的形式:
Dataset
可以包含任意形式的数据,例如图片、音频等等,但需要用户自行处理和转换成模型可接受的形式。TensorDataset
仅适用于存储张量形式的数据,即每个样本都需要是张量(tensor)类型。
因此,在使用上,如果我们已经将数据转换成了张量形式,则可以直接使用TensorDataset
来存储和管理数据;如果数据还没有转换成张量形式,则需要先将数据转换成张量形式后再使用Dataset
或TensorDataset
来进行存储和管理。
在实际应用中,TensorDataset
通常与DataLoader
结合使用,用于自动生成batch以及数据的打乱和随机化操作。同时,由于TensorDataset
提供了简单、快速的方式来存储和访问数据,因此也经常被用作深度学习模型的输入数据
【4】使用dataset过程的出错:
(1)检查函数是否命名正确,防止出现 init 写为int这种小错误
(2)已有列表【【】,【】,【】,【】,。。。。】 1131个子列表,每个子列表代表一个数据的特征,每个子列表中前四个代表input 最后一个代表label 使用dataset 进行划分:
- 按照官方无修改版本:出现报错:stack excepts each tensor to be eaual size 【子列表直接维度是不一样的,无法stack】
- dataloader 在return len(self.data_source) 这一步 出现 tuple object cannot be interpreted as an integer:【这个错误通常是由于在定义
Dataset
对象时,__len__()
方法返回了一个元组或列表类型的数据,而DataLoader
期望返回的是一个整数。】 - 在 dataloader return torch.stace(batch,0,out=out) 这一步出现报错stack excepts each tensor to be equal size:【在定义dataloader 的时候,
collate_fn
函数返回了不同大小的张量。因为每个子列表中的数据维度不一样】 - 最后:使用手动划分:}