【发布时间】:2018-07-04 03:17:08
【问题描述】:
是否有任何一般性建议可以有效地处理自定义数据集中的数据,以便它与小批量 eval/train 循环很好地配合?为了更具体地说明我的意思,假设我定义了这个将 x 映射到 x+1 的合成玩具数据集:
import torch.utils.data as data
class Dataset(data.Dataset):
def __init__(self):
super(Dataset, self).__init__()
# list of [x, y]
self.dataset = [
[1, 2],
[2, 3],
[3, 4],
[4, 5]
]
def __getitem__(self, index):
item = self.dataset[index]
return item[0], item[1]
def __len__(self):
return len(self.dataset)
实际上,这将被包装在 DataLoader 中并在 eval/train 循环中访问,如下所示:
dataset = Dataset()
data_loader = data.DataLoader(dataset=dataset, batch_size=2, shuffle=True)
epochs = 100
for i_epoch in range(epochs):
for i_minibatch, minibatch in enumerate(data_loader):
x, y = minibatch
# predict and train
数据集对象可能会返回原始 Python 对象,如数字或列表,就像在我的示例实现中一样,但是在最后一个代码 sn-p 的“预测和训练”部分中,我们需要一些特定的数据类型来计算东西,比如一个 torch.FloatTensor(似乎数据加载器可以隐式执行此操作),甚至可能包装为一个 torch.autograd.Variable,并且可能还需要对 .cuda() 进行一些调用。我的问题是关于何时进行这些数据转换和函数调用的一般建议。
例如,一种选择是将所有内容都保存为数据集中的 torch.FloatTensor,在 data_loader 循环中,我们可以添加变量包装器并调用 .cuda()。我们还可以通过在 Dataset 构造函数或 getitem 方法中调用 .cuda() 来获得 GPU 上的全部或部分数据。我认为所有这些方法都可能有利有弊。如果我要为多个 epoch 训练模型,我不想在每个 epoch 或小批量迭代中引入不必要的开销,这些开销可以通过预先计算数据集中的内容来避免。可能对 pytorch 内部有更多了解的人(可能与幕后发生的某些缓存或 jit 编译有关)可能能够指出选择一种方法而不是另一种方法的更具体的原因。
【问题讨论】:
标签: pytorch