- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在设置一个 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()
输入,但这似乎肯定不会在多个线程中运行。任何建议都非常受欢迎。
最佳答案
我在处理类似问题时偶然发现了这个问题。我想出了一个基于使用Python生成器的解决方案,以及TF数据集构建方法from_generator
.因为我们使用了生成器,所以 HDF5 文件应该只打开一次以供读取,并且只要有要读取的条目就保持打开状态。因此,它不会在每次调用时都打开、读取然后关闭以获取下一个数据元素。
为了允许用户将 HDF5 文件名作为参数传递,我生成了一个具有 __call__
方法的类,因为 from_generator
指定生成器必须是可调用的.这是生成器:
import h5py
import tensorflow as tf
class generator:
def __init__(self, file):
self.file = file
def __call__(self):
with h5py.File(self.file, 'r') as hf:
for im in hf["train_img"]:
yield im
通过使用生成器,代码应该从上次返回结果时每次调用中断的地方重新开始,而不是从头开始运行所有内容。在这种情况下,它位于内部 for
循环的下一次迭代中。所以这应该跳过再次打开文件进行读取,只要有数据yield
就保持打开状态。有关生成器的更多信息,请参阅 this excellent Q&A .
当然,您必须替换 with
block 中的任何内容,以匹配您的数据集的构建方式以及您想要获得的输出。
ds = tf.data.Dataset.from_generator(
generator(hdf5_path),
tf.uint8,
tf.TensorShape([427,561,3]))
value = ds.make_one_shot_iterator().get_next()
# Example on how to read elements
while True:
try:
data = sess.run(value)
print(data.shape)
except tf.errors.OutOfRangeError:
print('done.')
break
同样,在我的例子中,我存储了 uint8
高度 427
、宽度 561
和 3
的图像我的数据集中的颜色 channel ,因此您需要在上述调用中修改它们以匹配您的用例。
我有一个处理多个 HDF5 文件的建议解决方案。基本思想是像往常一样从文件名构造一个 Dataset
,然后使用 interleave
一种同时处理多个输入文件的方法,例如从每个输入文件中获取样本以形成一个批处理。
思路如下:
ds = tf.data.Dataset.from_tensor_slices(filenames)
# You might want to shuffle() the filenames here depending on the application
ds = ds.interleave(lambda filename: tf.data.Dataset.from_generator(
generator(filename),
tf.uint8,
tf.TensorShape([427,561,3])),
cycle_length, block_length)
这样做是同时打开 cycle_length
文件,并在移动到下一个文件之前从每个文件中生成 block_length
项 - 请参阅 interleave
文档了解细节。您可以在此处设置值以匹配适合您的应用程序的值:例如,您需要一次处理一个文件还是同时处理多个文件,您是否只想一次从每个文件中获取一个样本,等等.
编辑:对于并行版本,请查看 tf.contrib.data.parallel_interleave
!
如果您决定采用该解决方案,请注意使用 from_generator
的特殊性。对于 TensorFlow 1.6.0,documentation of from_generator
提到这两个注释。
在不同的环境或分布式训练中应用它可能具有挑战性:
NOTE: The current implementation of Dataset.from_generator() uses tf.py_func and inherits the same constraints. In particular, it requires the Dataset- and Iterator-related operations to be placed on a device in the same process as the Python program that called Dataset.from_generator(). The body of generator will not be serialized in a GraphDef, and you should not use this method if you need to serialize your model and restore it in a different environment.
如果生成器依赖于外部状态,请注意:
NOTE: If generator depends on mutable global variables or other external state, be aware that the runtime may invoke generator multiple times (in order to support repeating the Dataset) and at any time between the call to Dataset.from_generator() and the production of the first element from the generator. Mutating global variables or external state can cause undefined behavior, and we recommend that you explicitly cache any external state in generator before calling Dataset.from_generator().
关于python - TensorFlow - tf.data.Dataset 读取大型 HDF5 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48309631/
如果我用 dataset.batch(n).prefetch(m), 将预提取m个批次或m个 sample ? 最佳答案 Dataset.prefetch(m) 转换预取其直接输入的m元素。在这种情况
根据 TensorFlow documentation 、tf.contrib.data.Dataset 类的 prefetch 和 map 方法,都有一个名为 buffer_size 的参数. 对于
我正在使用 Flink 0.10.1 的 DataSet API 编写应用程序。我可以在 Flink 中使用单个运算符获取多个收集器吗? 我想做的是如下所示: val lines = env.read
为了使用 Google Colabs TPU,我需要一个 tf.dataset.Dataset .那么如何在这样的数据集上使用数据增强? 更具体地说,到目前为止我的代码是: def get_datas
我有一个包含 2 个相关数据表(主数据表和详细信息)的数据集。我想将与我的过滤器匹配的数据(例如主数据列 A =“XXX”)复制到另一个数据集。 现在我发现这个过程需要很长时间(1k 条记录大约需要一
我正在使用 .pvd文件同时加载多个文件到 Paraviw。对于具有单个数据集的时间序列,该文件看起来像这样: 我想指定要与 a.*.vtu 一起加载的其他文件(
我听说 Google 主办(或将举办)一场网络分类竞赛,他们提供了一个大型(170k+ 文档)网站数据集,这些网站被分为多个类别(体育、计算机、科学等),我尝试环顾四周在他们的 2009 年到 201
谁能给我解释一下 DataSet.Copy() vs Dataset.Clone()也让我知道一些我们可以使用这些的场景 最佳答案 Clone 将创建一个新的空数据集,其架构(表和列)与旧数据集相同。
dataset = dataset.batch(50) dataset = dataset.prefetch(buffer_size=1) 是预取 1 个批次还是 1 个元素? 根据 tensorfl
在 Delphi 中,与 Dataset.Next 相比,使用 Dataset.Prior 是否会降低性能? 背景: 我有一个在数据集中搜索特定记录的例程。我从数据集中的最后一条记录开始,然后使用 D
我正在使用 Spark(2.0) 开发 Spark SQL,并使用 Java API 读取 CSV。 CSV 文件中有一个双引号、逗号分隔的列。例如:“Express Air,Delivery Tru
为什么要使用DataSet.BeginInit 和DataSet.EndInit? 我已经经历了official msdn documentation ,它说 Begins the initializ
我正在尝试向新的数据集 X 添加一个位于不同数据集 Y 中的数据表。如果我直接添加它,我会得到以下错误: DataTable already belongs to another DataSet. 我
我有一个表示为形状为 (num_features, num_examples) 的 NumPy 矩阵的数据集,我希望将其转换为 TensorFlow 类型 tf.Dataset。 我正在努力理解这两种
这是 question 的转发在 ai.stackexchange 中询问。由于该论坛没有太多吸引力,我想我可以在这里尝试一下机会。 我有一个特定对象的不同尺寸的图像数据集。该物体的一些图像也处于不同
我有两个数据集: main_ds = tf.data.Dataset.from_tensor_slices(list(range(1000, 1100))) backgroud_ds = tf.dat
拥有Dataset单列 json 字符串: +--------------------+ | value| +--------------------+ |{"Contex
我正在尝试解决 Azure 数据工厂中的以下场景: 我在 Azure Blob 存储中有大量文件夹。每个文件夹包含不同数量的 parquet 格式的文件。文件夹名称包含生成该文件夹中包含的数据的日期,
我正在尝试解决 Azure 数据工厂中的以下场景: 我在 Azure Blob 存储中有大量文件夹。每个文件夹包含不同数量的 parquet 格式的文件。文件夹名称包含生成该文件夹中包含的数据的日期,
我有一个顺序数据集,我可以从中创建窗口来训练 RNN。在某些情况下,我想扔掉某些 window 。但是,当我使用 dataset.window 和 dataset.filter 时,管道内部会出现一些
我是一名优秀的程序员,十分优秀!