Я настраиваю конвейер 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
случайной выборки видеокадров, хранящихся в файле tfrecord
кажется совершенно невозможным (см. Здесь). Кроме того, я просмотрел from_generator()
данные from_generator()
для tf.data.Dataset
но это определенно не будет работать в нескольких потоках. Любые предложения более чем приветствуются.