【发布时间】:2018-06-26 20:05:26
【问题描述】:
我正在设置一个 TensorFlow 管道,用于读取大型 HDF5 文件作为我的深度学习模型的输入。每个 HDF5 文件包含 100 个可变大小长度的视频,这些视频存储为压缩 JPG 图像的集合(以使磁盘上的大小易于管理)。使用tf.data.Dataset 和tf.py_func 的映射,使用自定义Python 逻辑从HDF5 文件中读取示例非常容易。例如:
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 文件中的视频帧样本似乎是不可能的(请参阅here)。此外,我查看了tf.data.Dataset 的from_generator() 输入,但这似乎绝对不会在多个线程中运行。任何建议都非常受欢迎。
【问题讨论】:
-
tf.data.Dataset.map(your_map_function, num_parallel_calls=N)做你想做的事吗?它将运行您的地图函数的N线程。我看到的问题是您现在有 6 个线程,每个线程读取 1 个 HDF5 文件,这意味着您最好有足够的内存来存储所有 6 个完整的 HDF5 文件。我之所以提出这个问题,是因为我发布了一个相关问题,试图解决内存有限和大 HDF5 文件的问题。 stackoverflow.com/questions/48349409/… -
HDF5 文件的内存不是问题,因为它不会将整个文件读入内存。但是始终打开-读取-关闭-重新打开...文件仍然存在问题,这将大大降低速度。
标签: python video tensorflow hdf5 tensorflow-datasets