Я настраиваю конвейер TensorFlow для чтения больших файлов HDF5 в качестве входных данных для моих моделей глубокого обучения. Каждый файл HDF5 содержит 100 видеороликов переменной длины, хранящихся в виде коллекции сжатых изображений JPG (для управления размером на диске). Используя tf.data.Dataset
и сопоставление с tf.py_func
, читать примеры из файла HDF5 с использованием пользовательской логики Python довольно просто. Например:
def read_examples_hdf5(filename, label):
with h5py.File(filename, 'r') as hf:
# read frames from HDF5 and decode them from JPG
return frames, label
filenames = glob.glob(os.path.join(hdf5_data_path, "*.h5"))
labels = [0]*len(filenames) # ... can we do this more elegantly?
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(
lambda filename, label: tuple(tf.py_func(
read_examples_hdf5, [filename, label], [tf.uint8, tf.int64]))
)
dataset = dataset.shuffle(1000 + 3 * BATCH_SIZE)
dataset = dataset.batch(BATCH_SIZE)
iterator = dataset.make_one_shot_iterator()
next_batch = iterator.get_next()
Этот пример работает, однако проблема в том, что кажется, что tf.py_func
может обрабатывать только один пример за раз. Поскольку в моем контейнере HDF5 хранится 100 примеров, это ограничение вызывает значительные накладные расходы, поскольку файлы постоянно нужно открывать, читать, закрывать и открывать повторно. Было бы гораздо эффективнее прочитать все 100 видео примеров в объект набора данных, а затем перейти к следующему файлу HDF5 (желательно в нескольких потоках, каждый поток имеет дело со своей собственной коллекцией файлов HDF5).
Итак, мне бы хотелось, чтобы в фоновом режиме выполнялось несколько потоков, которые считывают видеокадры из файлов HDF5, декодируют их из JPG и затем передают их в объект набора данных. До появления конвейера tf.data.Dataset
это было довольно просто с использованием операций RandomShuffleQueue
и enqueue_many
, но похоже, что в настоящее время нет элегантного способа сделать это (или отсутствует документация).
Кто-нибудь знает, как лучше всего достичь моей цели? Я также изучил (и реализовал) конвейер с использованием файлов tfrecord
, но получение случайной выборки видеокадров, хранящихся в файле tfrecord
, кажется совершенно невозможным (см. здесь). Кроме того, я просмотрел from_generator()
входы для tf.data.Dataset
, но, похоже, это определенно не будет работать в нескольких потоках. Любые предложения более чем приветствуются.
tf.data.Dataset.map(your_map_function, num_parallel_calls=N)
делает то, что вы хотите? Он будет запускатьN
потока вашей функции карты. Проблема, которую я вижу в этом, заключается в том, что теперь у вас есть 6 потоков, каждый из которых читает 1 файл HDF5, а это означает, что вам лучше иметь достаточно памяти для всех 6 файлов Full HDF5. Я пришел к этому вопросу из-за связанного вопроса, который я опубликовал, пытаясь решить проблему ограниченной памяти и больших файлов HDF5. stackoverflow.com/questions/48349409/ - person David Parks   schedule 20.01.2018