一、DataLoader是做什么的
在数据加载过程当中,面对数据量比较大的数据集,需要做的分割,打乱步骤等重复性的工作就可以做一个接口一块做了,这个接口就是DataLoader
接口。
接下来就看一下这个数据在进入DataLoader
后有什么变化
1.1 加载数据
import torch
import numpy as np
xy = np.random.rand(759, 9)
xData = torch.from_numpy(xy[:, 0:-1]) # 取除了最后一列的数据
yData = torch.from_numpy(xy[:, [-1]]) # 取最后一列的数据, [-1]是为了保持维度是二维
## 打印数据的大小
print(xData.size(), yData.size())
torch.Size([759, 8]) torch.Size([759, 1])
1.2 使用Dataset和DataLoader类
Dataset
是一个包装类,用来将数据包装为Dataset
类,然后传入DataLoader
中,我们在使用DataLoader
这个类来更加快捷的对数据进行操作。
Data_Loader
是一个比较重要的类,它为我们提供的常有的操作:
- batch_size(分为的batch的个数)
- shuffle(是否进行数据的打乱)
- num_workers(加载数据的时候使用几个子进程)
我们使用TensorDataset
将数据包装成Dataset
类
from torch.utils.data import Dataset, DataLoader, TensorDataset
from torch.autograd import Variable
import numpy as np
import torch
dealDataset = TensorDataset(xData, yData)
trainLoader = DataLoader(dataset=dealDataset, batch_size=32, shuffle=True, num_workers=2)
for epoch in range(2):
for i, data in enumerate(trainLoader):
# 将数据从train_loader中读出来,一次读取的样本数是32个
inputs, labels = data
# 将这些数据转换成Variable类型
inputs, label = Variable(inputs), Variable(labels)
# 接下来跑模型
print(epoch, i, 'inputs', inputs.data.size(), 'labels', labels.data.size())
0 0 inputs torch.Size([32, 8]) labels torch.Size([32, 1]) 0 1 inputs torch.Size([32, 8]) labels torch.Size([32, 1]) 0 2 inputs torch.Size([32, 8]) labels torch.Size([32, 1]) 0 3 inputs torch.Size([32, 8]) labels torch.Size([32, 1]) …. 1 21 inputs torch.Size([32, 8]) labels torch.Size([32, 1]) 1 22 inputs torch.Size([32, 8]) labels torch.Size([32, 1])
注意:这里的batch_size
指的是分割后数据第个一维度的大小,请看:
import torch
import numpy as np
from torch.utils.data import Dataset, DataLoader, TensorDataset
from torch.autograd import Variable
xy = np.random.rand(256, 1, 759, 9)
xData = torch.from_numpy(xy[:, :, :, 0:-1]) # 取除了最后一列的数据
yData = torch.from_numpy(xy[:, :, :, [-1]]) # 取最后一列的数据, [-1]是为了保持维度是二维
## 打印数据的大小
print(xData.size(), yData.size());
dealDataset = TensorDataset(xData, yData)
trainLoader = DataLoader(dataset=dealDataset, batch_size=128, shuffle=True, num_workers=2)
for epoch in range(2):
for i, data in enumerate(trainLoader):
# 将数据从train_loader中读出来,一次读取的样本数是32个
inputs, labels = data
# 将这些数据转换成Variable类型
inputs, label = Variable(inputs), Variable(labels)
# 接下来跑模型
print(epoch, i, 'inputs', inputs.data.size(), 'labels', labels.data.size())
torch.Size([256, 1, 759, 8]) torch.Size([256, 1, 759, 1]) 0 0 inputs torch.Size([128, 1, 759, 8]) labels torch.Size([128, 1, 759, 1]) 0 1 inputs torch.Size([128, 1, 759, 8]) labels torch.Size([128, 1, 759, 1]) 1 0 inputs torch.Size([128, 1, 759, 8]) labels torch.Size([128, 1, 759, 1]) 1 1 inputs torch.Size([128, 1, 759, 8]) labels torch.Size([128, 1, 759, 1])
二、集成Dataset类
接下来,继承一下Dataset
类,自定义一个将数据处理成DataLoader
的类。
当我们继承了一个Dataset
类,我们需要重写len
方法,该方法提供了dataset
的大小;getitem
方法,该方法支持从0到len(self)
的索引。
class DealDataset(Dataset):
"""
这里是自定义的一个继承自Dataset的类
"""
def __init__(self):
xy = np.random.rand(759, 9)
self.xData = torch.from_numpy(xy[:, 0:-1]) # 取除了最后一列的数据
self.yData = torch.from_numpy(xy[:, [-1]]) # 取最后一列的数据, [-1]是为了保持维度是二维
self.len = xy.shape[0]
def __getitem__(self, index):
return self.xData[index], self.yData[index]
def __len__(self):
return self.len
dealDataset = DealDataset()
trainLoader = DataLoader(dataset=dealDataset, batch_size=32, shuffle=True, num_workers=2)
for epoch in range(2):
for i, data in enumerate(trainLoader):
# 将数据从train_loader中读出来,一次读取的样本数是32个
inputs, labels = data
# 将这些数据转换成Variable类型
inputs, label = Variable(inputs), Variable(labels)
# 接下来跑模型
print(epoch, i, 'inputs', inputs.data.size(), 'labels', labels.data.size())