tf.data
包含在库核心中。
在1.4版本发布说明中描述了一个“重要新特性”,即tf.data.Dataset.apply()
,它是一种“应用自定义转换函数”的方法。与已经存在的tf.data.Dataset.map()
有何不同?tf.data
包含在库核心中。
在1.4版本发布说明中描述了一个“重要新特性”,即tf.data.Dataset.apply()
,它是一种“应用自定义转换函数”的方法。与已经存在的tf.data.Dataset.map()
有何不同?不同之处在于map
会独立地对Dataset
的每个元素执行一个函数,而apply
会一次性对整个Dataset
执行一个函数(例如在文档中给出的group_by_window
)。
apply
的参数是一个接受一个Dataset
并返回一个Dataset
的函数,而map
的参数是一个接受一个元素并返回一个转换后元素的函数。
Sunreef的答案是完全正确的。你可能仍然在想为什么我们引入了Dataset.apply()
,我想提供一些背景。
tf.data
API有一组核心转换,比如Dataset.map()
和Dataset.filter()
,通常对各种数据集都很有用,不太可能改变,并且作为tf.data.Dataset
对象上的方法实现。特别是,它们受到与TensorFlow中其他核心API相同的向后兼容性保证。
然而,核心方法略显狭隘。我们还想自由地尝试新的转换,然后再将其添加到核心中,并允许其他库开发人员创建自己的可重复使用的转换。因此,在TensorFlow 1.4中,我们将一组自定义转换拆分到了tf.contrib.data
中。这些自定义转换包括一些具有非常特定功能的转换(如tf.contrib.data.sloppy_interleave()
),以及一些API仍在不断变化中的转换(如tf.contrib.data.group_by_window()
)。最初,我们将这些自定义转换实现为从Dataset
到Dataset
的函数,这对于管道的语法流程有不良影响。例如:
dataset = tf.data.TFRecordDataset(...).map(...)
# Method chaining breaks when we apply a custom transformation.
dataset = custom_transformation(dataset, x, y, z)
dataset = dataset.shuffle(...).repeat(...).batch(...)
由于这似乎是一种常见的模式,我们添加了 Dataset.apply()
作为将核心和自定义转换链接在单个管道中的方法:
dataset = (tf.data.TFRecordDataset(...)
.map(...)
.apply(custom_transformation(x, y, z))
.shuffle(...)
.repeat(...)
.batch(...))
在整个计划中,这只是一个细小的特性,但希望它有助于使tf.data
程序更易于阅读,并使该库更易于扩展。
tf.data
中,大多数转换都是无状态和流式的,这意味着它们可以立即返回结果,并在处理可能不适合内存的大型数据集时消耗很少的内存。这意味着,如果您在这些转换后有一个 Dataset.repeat()
,它们将在每次通过数据时执行。如果要避免这种情况,请在要执行一次的转换后添加 Dataset.cache()
。 - mrrycustom_transformation
的 "hello world 实现" 吗? - Marsellus Wallacedataset = dataset ...
dataset.batch(batch_size)
dataset.map(normalize_fn)
apply()
的主要作用是在整个数据集上进行转换。简单来说,apply()
的 transformation_func
参数是 Dataset
;map()
的 map_func
参数是 element
apply
函数的文档在哪里可以找到。现在我发现这些函数在tf.contrib.data中,而Dataset API已经移动到了tf.data中,这正是我一直在寻找的地方。 - GPhilomap
用于转换数据集中的值,而apply
则是在数据集本身上操作... 所以apply
可以替代map
吗? - GPhiloapply
is used when you need to consider several elements at once. For example, if you want to create a dataset with averages of five consecutive elements in your dataset, then you couldn't do that withmap
- Sunreefapply
可以完全替代map
(因为如果它可以访问所有项目,它也可以像map
一样逐个访问它们),但编写apply
函数不像编写操作值本身的函数那么直接,因此出于实际原因我们仍然使用map
。 这有意义吗? - GPhiloapply
调用替换map
,那么在apply
内部的函数仍然需要执行相当于map
的操作。 - Sunreef