一、DataLoader是做什么的

在数据加载过程当中,面对数据量比较大的数据集,需要做的分割,打乱步骤等重复性的工作就可以做一个接口一块做了,这个接口就是DataLoader接口。

接下来就看一下这个数据在进入DataLoader后有什么变化

1.1 加载数据

  1. import torch
  2. import numpy as np
  3. xy = np.random.rand(759, 9)
  4. xData = torch.from_numpy(xy[:, 0:-1]) # 取除了最后一列的数据
  5. yData = torch.from_numpy(xy[:, [-1]]) # 取最后一列的数据, [-1]是为了保持维度是二维
  6. ## 打印数据的大小
  7. print(xData.size(), yData.size())

torch.Size([759, 8]) torch.Size([759, 1])

1.2 使用Dataset和DataLoader类

Dataset是一个包装类§ DataLoader函数 - 图1,用来将数据包装为Dataset类,然后传入DataLoader中,我们在使用DataLoader这个类来更加快捷的对数据进行操作。

Data_Loader是一个比较重要的类,它为我们提供的常有的操作:

  • batch_size(分为的batch的个数)
  • shuffle(是否进行数据的打乱)
  • num_workers(加载数据的时候使用几个子进程)

我们使用TensorDataset将数据包装成Dataset

  1. from torch.utils.data import Dataset, DataLoader, TensorDataset
  2. from torch.autograd import Variable
  3. import numpy as np
  4. import torch
  5. dealDataset = TensorDataset(xData, yData)
  6. trainLoader = DataLoader(dataset=dealDataset, batch_size=32, shuffle=True, num_workers=2)
  7. for epoch in range(2):
  8. for i, data in enumerate(trainLoader):
  9. # 将数据从train_loader中读出来,一次读取的样本数是32个
  10. inputs, labels = data
  11. # 将这些数据转换成Variable类型
  12. inputs, label = Variable(inputs), Variable(labels)
  13. # 接下来跑模型
  14. 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指的是分割后数据第个一维度的大小,请看:

  1. import torch
  2. import numpy as np
  3. from torch.utils.data import Dataset, DataLoader, TensorDataset
  4. from torch.autograd import Variable
  5. xy = np.random.rand(256, 1, 759, 9)
  6. xData = torch.from_numpy(xy[:, :, :, 0:-1]) # 取除了最后一列的数据
  7. yData = torch.from_numpy(xy[:, :, :, [-1]]) # 取最后一列的数据, [-1]是为了保持维度是二维
  8. ## 打印数据的大小
  9. print(xData.size(), yData.size());
  10. dealDataset = TensorDataset(xData, yData)
  11. trainLoader = DataLoader(dataset=dealDataset, batch_size=128, shuffle=True, num_workers=2)
  12. for epoch in range(2):
  13. for i, data in enumerate(trainLoader):
  14. # 将数据从train_loader中读出来,一次读取的样本数是32个
  15. inputs, labels = data
  16. # 将这些数据转换成Variable类型
  17. inputs, label = Variable(inputs), Variable(labels)
  18. # 接下来跑模型
  19. 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)的索引。

  1. class DealDataset(Dataset):
  2. """
  3. 这里是自定义的一个继承自Dataset的类
  4. """
  5. def __init__(self):
  6. xy = np.random.rand(759, 9)
  7. self.xData = torch.from_numpy(xy[:, 0:-1]) # 取除了最后一列的数据
  8. self.yData = torch.from_numpy(xy[:, [-1]]) # 取最后一列的数据, [-1]是为了保持维度是二维
  9. self.len = xy.shape[0]
  10. def __getitem__(self, index):
  11. return self.xData[index], self.yData[index]
  12. def __len__(self):
  13. return self.len
  14. dealDataset = DealDataset()
  15. trainLoader = DataLoader(dataset=dealDataset, batch_size=32, shuffle=True, num_workers=2)
  16. for epoch in range(2):
  17. for i, data in enumerate(trainLoader):
  18. # 将数据从train_loader中读出来,一次读取的样本数是32个
  19. inputs, labels = data
  20. # 将这些数据转换成Variable类型
  21. inputs, label = Variable(inputs), Variable(labels)
  22. # 接下来跑模型
  23. print(epoch, i, 'inputs', inputs.data.size(), 'labels', labels.data.size())