Я уже делал некоторую предварительную обработку и выбор функций, и у меня есть входные данные для обучения маринованию, которые состоят из списка списков, например (но с маринованным)
[[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]
- токен заполнения,но я не думаю, что это имеет значение.
Поскольку файл состоит из нескольких гигабайт, я хочу сэкономить память и использовать генератор для чтения в рассоле строка за строкой (список за списком).Я уже нашел этот ответ , который может быть полезным.Это будет выглядеть следующим образом:
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 .Из того, что я нашел в других ответах, я должен передать ему Набор данных , который вы можете поднастроить, но который должен содержать __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 (благодаря его многопроцессорным возможностям), но эффективным способом памяти, когда мне не нужно читать весь файл в память.