Использование генератора с маринованными данными в Dataloader для PyTorch - PullRequest
0 голосов
/ 11 февраля 2019

Я уже делал некоторую предварительную обработку и выбор функций, и у меня есть входные данные для обучения маринованию, которые состоят из списка списков, например (но с маринованным)

[[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 (благодаря его многопроцессорным возможностям), но эффективным способом памяти, когда мне не нужно читать весь файл в память.

1 Ответ

0 голосов
/ 11 февраля 2019

См. мой другой ответ для ваших вариантов.

Короче говоря, вам необходимо либо предварительно обработать каждый образец в отдельных файлах, либо использовать формат данных, который не нужно загружать полностью в память для чтения.

...