Как хранить и загружать данные обучения, состоящие из 50 миллионов массивов 25x25 numpy, во время обучения многоклассовой модели CNN? - PullRequest
3 голосов
/ 21 января 2020

У меня проблема с обработкой изображений, когда существует пять классов, в каждом классе содержится примерно 10 миллионов примеров тренировочных данных, где изображение представляет собой массив 25x25 numpy с z-оценкой.

Очевидно, я не могу загрузить все тренировочные данные в память, поэтому я должен использовать fit_generator.

Я также являюсь тем, кто генерирует и дополняет эти матрицы обучающих данных, но я не могу сделать это в режиме реального времени в течение fit_generator, потому что обучение будет слишком медленным.

Во-первых, как сохранить 50 миллионов массивов 25x25 .npy на диске? Какова будет лучшая практика?

Во-вторых, должен ли я использовать базу данных для хранения этих матриц и запрашивать их во время обучения? Я не думаю, что SQLite поддерживает многопоточность, а поддержка SQL наборов данных все еще экспериментальная в тензорном потоке.

Мне бы хотелось знать, есть ли удобный способ хранения этих 50 миллионов матриц, чтобы поиск во время обучения был оптимальным.

В-третьих, как насчет использования HDF5 * 1018? * формат? Должен ли я вместо этого переключиться на pytorch ?

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Как сохранить np.arrays () на диске?

Хранение их в файле HDF5 - хорошая идея. Тип basi c HDF5 - это Datasets, который содержит многомерные массивы однородного типа. Файлы HDF5 Datasets могут быть собраны вместе в файлы HDF5 Groups, которые также могут содержать другие группы, для создания более сложных структур. Другим способом является выборка ваших numpy массивов или более абстрактных объектов набора данных непосредственно с диска, но тогда ваш файл будет доступен для чтения только Python. Также не рекомендуется по соображениям безопасности . Наконец, если вы хотите оптимизировать формат данных для операций чтения / записи TensorFlow, вы можете использовать формат файла TFRecord. Сохранение массива numpy в формате TFRecord может быть сложным, но, к счастью, кто-то создал скрипт для этого .

Должен ли я использовать базу данных для хранения этих матриц и для запроса от них во время тренировок?

Можно, но тогда вы бы заново изобрели колесо. Что вам нужно, так это один или несколько отдельных процессов в процессе обучения, чтение следующего пакета обучающих наблюдений (предварительная выборка) и применение к ним некоторых преобразований, пока процесс обучения работает с предыдущим пакетом. Таким образом вы избежите любых задержек ввода-вывода и предварительной обработки и сможете получить значительный прирост производительности. Фреймворки AI разработали собственные инструменты для решения этой проблемы. В Pytorch есть класс torch.utils.data.DataLoader. Здесь - учебное пособие, показывающее, как эффективно загружать файлы HDF5 с помощью Dataloader. В TensorFlow вы можете создать входной конвейер , используя класс tf.data.Dataset. Основной подход c состоит в том, чтобы сначала открыть файл (ы) (1), прочитать данные из файла (ов) в память (2), а затем обучить вашу модель, используя то, что находится в памяти (3). Давайте посмеемся над набором данных TF и ​​обучением l oop:

import tf, time

class MyDataset(tf.data.Dataset):
    def __new__(self, filename="image_dataset.proto"):
        time.sleep(0.01) # mock step (1) delay
        return tf.data.TFRecordDataset([filename])

def train(dataset, nb_epoch=10):
    start_time = time.perf_counter()
    for epoch_num in range(nb_epoch):
        for sample in dataset: # where step (2) delay takes place
            time.sleep(0.01) # mock step (3) delay
        tf.print("Execution time:", time.perf_counter() - start_time)

Вы можете просто последовательно применять шаги (1, 2, 3):

train(MyDataset())

Лучше читать следующая партия данных, в то время как процесс обучения все еще тренируется на предыдущей партии, так что шаги (2, 3) могут выполняться в парралеле. Также можно применить преобразования к следующей партии, продолжая тренироваться на предыдущей партии. Для предварительной выборки:

train(MyDataset().prefetch(tf.data.experimental.AUTOTUNE))

Кроме того, вы можете иметь несколько процессов для чтения ваших файлов и иметь последовательность шагов (1, 2), выполняющихся в parralel:

train( tf.data.Dataset.range(2).interleave(\
    MyDataset().prefetch(tf.data.experimental.AUTOTUNE),\
    num_parallel_calls=tf.data.experimental.AUTOTUNE))

Learn больше в документации .

Должен ли я вместо этого переключиться на Pytorch?

Почти все, что может сделать Pytorch, TensorFlow может сделать тоже. Некоторое время TensorFlow был самой готовой к использованию платформой AI, используемой Google для своих TPU. Pytorch догоняет все же. Я бы сказал, что Pytorch больше ориентирован на исследования / разработки, а TensorFlow больше ориентирован на производство. Другое отличие состоит в том, как вы проектируете свои нейронные сети: Pytorch работает, добавляя слои поверх друг друга, в то время как в TensorFlow вы сначала проектируете вычислительный граф, который в какой-то момент запускается для некоторых входных данных. Люди часто разрабатывают свои модели в Pytorch, а затем экспортируют их в формате TensorFlow для использования в производстве.

0 голосов
/ 22 февраля 2020

Вот код, который я нашел на носителе (не могу найти оригинальный пост). Это поможет сгенерировать данные обучения на лету способом производителя-потребителя:

import tensorflow as tf
import numpy as np

from time import sleep

class DataGen():
    counter = 0

    def __init__(self):
        self.gen_num = DataGen.counter
        DataGen.counter += 1

    def py_gen(self, gen_name):
        gen_name = gen_name.decode('utf8') + '_' + str(self.gen_num)
        for num in range(10):
            sleep(0.3)
            yield '{} yields {}'.format(gen_name, num)

Dataset = tf.data.Dataset
dummy_ds = Dataset.from_tensor_slices(['Gen1', 'Gen2', 'Gen3'])
dummy_ds = dummy_ds.interleave(lambda x: Dataset.from_generator(DataGen().py_gen, output_types=(tf.string), args=(x,)),
                               cycle_length=5,
                               block_length=2,
                               num_parallel_calls=5)
data_tf = dummy_ds.as_numpy_iterator()
for d in data_tf:
  print(d)

Вывод:

b'Gen1_0 yields 0'
b'Gen1_0 yields 1'
b'Gen2_0 yields 0'
b'Gen2_0 yields 1'
b'Gen3_0 yields 0'
b'Gen3_0 yields 1'
b'Gen1_0 yields 2'
b'Gen1_0 yields 3'
b'Gen2_0 yields 2'
b'Gen2_0 yields 3'
b'Gen3_0 yields 2'
b'Gen3_0 yields 3'
b'Gen1_0 yields 4'
b'Gen1_0 yields 5'
b'Gen2_0 yields 4'
b'Gen2_0 yields 5'
b'Gen3_0 yields 4'
b'Gen3_0 yields 5'
b'Gen1_0 yields 6'
b'Gen1_0 yields 7'
b'Gen2_0 yields 6'
b'Gen2_0 yields 7'
b'Gen3_0 yields 6'
b'Gen3_0 yields 7'
b'Gen1_0 yields 8'
b'Gen1_0 yields 9'
b'Gen2_0 yields 8'
b'Gen2_0 yields 9'
b'Gen3_0 yields 8'
b'Gen3_0 yields 9'
...