【发布时间】:2019-07-04 09:49:48
【问题描述】:
我之前做过一些预处理和特征选择,并且我有一个包含列表列表的泡菜训练输入数据,例如(但腌制)
[[1,5,45,13], [23,256,4,2], [1,12,88,78], [-1]]
[[12,45,77,325], [23,257,5,28], [3,7,48,178], [12,77,89,99]]
[[13,22,78,89], [12,33,97], [-1], [-1]]
[-1] 是一个填充标记,但我认为这并不重要。
因为文件有很多千兆字节,我希望节省内存并使用生成器逐行读取泡菜(逐个列表)。我已经找到了this answer 这可能会有所帮助。如下所示:
def yield_from_pickle(pfin):
with open(pfin, 'rb') as fhin:
while True:
try:
yield pickle.load(fhin)
except EOFError:
break
接下来,我希望在 PyTorch (1.0.1) Dataloader 中使用这些数据。从我在其他答案中找到的内容来看,我必须为它提供一个Dataset,您可以对其进行子集化,但它必须包含__len__ 和__getitem__。它可能是这样的:
class TextDataset(Dataset):
def __init__(self, pfin):
self.pfin = pfin
def __len__(self):
# memory-lenient way but exhaust generator?
return sum(1 for _ in self.yield_from_pickle())
def __getitem__(self, index):
# ???
pass
def yield_from_pickle(self):
with open(self.pfin, 'rb') as fhin:
while True:
try:
yield pickle.load(fhin)
except EOFError:
break
但我完全不确定这是否可能。如何以合理的方式实现__len__ 和__getitem__?我不认为我对 __len__ 所做的事情是一个好主意,因为这会耗尽生成器,而且我完全不知道如何在保留生成器的同时安全地实现 __getitem__。
有没有更好的方法?总而言之,我想构建一个可以馈送到 PyTorch 的 Dataloader 的数据集(因为它的多处理能力),但以一种内存高效的方式,我不必将整个文件读入内存。
【问题讨论】:
标签: python dataset generator pickle pytorch