TensorFlowtf.data导入数据(tf.data官方教程)

TensorFlowtf.data导⼊数据(tf.data官⽅教程)
导⼊数据(Reading data)
TensorFlow读取数据的四种⽅法:tf.data、Feeding、QueueRunner、Preloaded data。
本篇的内容主要介绍 的使⽤
⽬录
基于 API,我们可以使⽤简单的代码来构建复杂的输⼊ pipeline。 (例1,从分布式⽂件系统中读取数据、进⾏预处理、合成为 batch、训练中使⽤数据集;例2,⽂本模型的输⼊ pipeline 需要从原始⽂本数据中提取符号、根据对照表将其转换为嵌⼊标识符,以及将不同长度的序列组合成batch数据等。) 使⽤ tf.data API 可以轻松处理⼤量数据、不同的数据格式以及复杂的转换。
API 在 TensorFlow 中引⼊了两个新概念:
(1)tf.data.Dataset:表⽰⼀系列元素,其中每个元素包含⼀个或多个 Tensor 对象。例如,在图⽚管道中,⼀个元素可能是单个训练样本,具有⼀对表⽰图⽚数据和标签的张量。可以通过两种不同的⽅式来创建数据集。
直接从 Tensor 创建 Dataset(例如 Dataset.from_tensor_slices());当然 Numpy 也是可以的,TensorFlow 会⾃动将其转换为Tensor。
通过对⼀个或多个 tf.data.Dataset 对象来使⽤变换(例如 Dataset.batch())来创建 Dataset
(2)tf.data.Iterator:这是从数据集中提取元素的主要⽅法。_next() 指令会在执⾏时⽣成 Dataset 的下⼀个元素,并且此指令通常充当输⼊管道和模型之间的接⼝。最简单的迭代器是“单次迭代器”,它会对处理好的 Dataset 进⾏单次迭代。要实现更复杂的⽤途,您可以通过 `Iterator.initializer` 指令使⽤不同的数据集重新初始化和参数化迭代器,这样⼀来,您就可以在同⼀个程序中对训练和验证数据进⾏多次迭代(举例⽽⾔)。
1. Dataset 的基本机制 ¶
本部分将介绍:
1、Dataset 的基础知识,并尝试创建 Dataset
2、Iterator 的基础知识,并尝试创建 Iterator
3、通过 Iterator 来提取 Dataset 中的数据
要构建输⼊ pipeline,你必须⾸先根据数据集的存储⽅式选择相应的⽅法创建 Datase t 对象来读取数据。(如果你的数据在内存中,请使⽤tf.data.Dataset.from_tensors() 或 tf.data.Dataset.from_tensor_slices() 来创建 Dataset;如果你的数据是 tfrecord 格式的,那么请使⽤ tf.data.TFRecordDataset 来创建 Dataset)
铅球场地示意图
有了 Dataset 对象以后,您就可以通过使⽤ tf.data.Dataset 对象的各种⽅法对其进⾏处理。例如,您可以对Dataset的每⼀个元素使⽤某种变换,例 Dataset.map()(为每个元素使⽤⼀个函数),也可以对多个元素使⽤某种变换(例如 Dataset.batch())。 要了解所有可⽤的变换,。
消耗 Dataset 中值的最常见⽅法是构建迭代器对象。通过迭代器对象,每次可以访问数据集中的⼀个元素 (例如,通过调⽤
Dataset.make_one_shot_iterator())。 tf.data.Iterator 提供了两个指令:Iterator.initializer,您可以通过此指令(重新)初始化迭代器的状态;以及 _next(),此指令返回迭代器中的下⼀个元素的 tf.Tensor 对象。根据您的需求,您可以选择不同类型的迭代器,下⽂将对此进⾏详细介绍。
1.1 了解 Dataset 的结构并尝试创建 Dataset ¶
⼀个 Dataset 对象包含多个元素,每个元素的结构都相同。每个元素包含⼀个或多个 tf.Tensor 对象,
这些对象被称为组件。每个组件都有 tf.DType 属性,表⽰ Tensor 中元素的类型;以及 tf.TensorShape 属性,表⽰每个元素(可能部分指定)的静态形状。您可以通过Dataset.output_types 和 Dataset.output_shapes 属性检查数据集元素各个组件的类型和形状。Dataset 的属性由构成该 Dataset 的元素的属性映射得到,元素可以是单个张量、张量元组,也可以是张量的嵌套元组。例如:
dataset1 = tf.data.Dataset.from_tensor_slices(tf.random_uniform([4, 10]))
print(dataset1.output_types)  # ==> "tf.float32"
print(dataset1.output_shapes)  # ==> "(10,)"
dataset2 = tf.data.Dataset.from_tensor_slices(
(tf.random_uniform([4]),
tf.random_uniform([4, 100], maxval=100, dtype=tf.int32)))
print(dataset2.output_types)  # ==> "(tf.float32, tf.int32)"
print(dataset2.output_shapes)  # ==> "((), (100,))"
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
print(dataset3.output_types)  # ==> (tf.float32, (tf.float32, tf.int32))
print(dataset3.output_shapes)  # ==> "(10, ((), (100,)))"
为 Dataset 中的元素的各个组件命名通常会带来便利性(例如,元素的各个组件表⽰不同特征时)。除了元组之外,还可以使⽤ 命名元组(collections.namedtuple) 或 字典 来表⽰ Dataset 的单个元素。
dataset = tf.data.Dataset.from_tensor_slices(
{"a": tf.random_uniform([4]),
"b": tf.random_uniform([4, 100], maxval=100, dtype=tf.int32)})
print(dataset.output_types)  # ==> "{'a': tf.float32, 'b': tf.int32}"
print(dataset.output_shapes)  # ==> "{'a': (), 'b': (100,)}"
Dataset 的变换⽀持任何结构的数据集。在使⽤ Dataset.map()、Dataset.flat_map() 和 Dataset.filter()
函数时(这些转换会对每个元素应⽤⼀个函数),元素结构决定了函数的参数:
dataset1 = dataset1.map(lambda x: ...)
dataset2 = dataset2.flat_map(lambda x, y: ...)
# Note: Argument destructuring is not available in Python 3.
dataset3 = dataset3.filter(lambda x, (y, z): ...)
1.2 了解迭代器的作⽤,并创建 Iterator ¶
构建了表⽰输⼊数据的 Dataset 后,下⼀步就是创建 Iterator 来访问该数据集中的元素。tf.data API ⽬前⽀持下列迭代器,其复杂程度逐渐上升:
(1)单次迭代器
(2)可初始化迭代器
(3)可重新初始化迭代器
(4)可 feeding 迭代器
单次迭代器是最简单的迭代器形式,仅⽀持对数据集进⾏⼀次迭代,不需要显式初始化。单次迭代器可以处理现有的基于队列的输⼊管道⽀持的⼏乎所有情况,但不⽀持参数化。以 Dataset.range() 为例:
dataset = tf.data.Dataset.range(100)
iterator = dataset.make_one_shot_iterator()
next_element = _next()
for i in range(100):
value = sess.run(next_element)
assert i == value
注意:⽬前,单次迭代器是唯⼀可轻松与 Estimator 配合使⽤的类型。
您需要先运⾏显式 iterator.initializer 指令,才能使⽤可初始化迭代器。虽然有些不便,但它允许您使⽤⼀个或多个 tf.placeholder() 张量(可在初始化迭代器时馈送)参数化数据集的定义。继续以 Dataset.range() 为例:
max_value = tf.placeholder(tf.int64, shape=[])
dataset = tf.data.Dataset.range(max_value)
iterator = dataset.make_initializable_iterator()
next_element = _next()
# Initialize an iterator over a dataset with 10 elements.
sess.run(iterator.initializer, feed_dict={max_value: 10})
for i in range(10):
value = sess.run(next_element)
assert i == value
# Initialize the same iterator over a dataset with 100 elements.
sess.run(iterator.initializer, feed_dict={max_value: 100})
for i in range(100):
value = sess.run(next_element)照明母线
吸附树脂
assert i == value
可重新初始化迭代器 可以通过多个不同的 Dataset 对象进⾏初始化。例如,您可能有⼀个训练输⼊管道,它会对输⼊图⽚进⾏随机扰动来改善泛化;还有⼀个验证输⼊管道,它会评估对未修改数据的预测。这些管道通常会使⽤不同的 Datase t 对象,这些对象具有相同的结构(即每个组件具有相同类型和兼容形状)。
# Define training and validation datasets with the same structure.
training_dataset = tf.data.Dataset.range(100).map(
lambda x: x + tf.random_uniform([], -10, 10, tf.int64))
validation_dataset = tf.data.Dataset.range(50)
# A reinitializable iterator is defined by its structure. We could use the
# `output_types` and `output_shapes` properties of either `training_dataset`
# or `validation_dataset` here, because they are compatible.
iterator = tf.data.Iterator.from_structure(training_dataset.output_types,
training_dataset.output_shapes)
next_element = _next()
training_init_op = iterator.make_initializer(training_dataset)
validation_init_op = iterator.make_initializer(validation_dataset)
# Run 20 epochs in which the training dataset is traversed, followed by the
# validation dataset.
for _ in range(20):
# Initialize an iterator over the training dataset.
sess.run(training_init_op)
for _ in range(100):
sess.run(next_element)
# Initialize an iterator over the validation dataset.
sess.run(validation_init_op)
for _ in range(50):
sess.run(next_element)
可 feeding 迭代器可以与 tf.placeholder ⼀起使⽤,通过熟悉的 feed_dict 机制来选择每次调⽤ tf.Session.run 时所使⽤的 Iterator。它提供的功能与可重新初始化迭代器的相同,但在迭代器之间切换时不需要从数据集的开头初始化迭代器。例如,以上⾯的同⼀训练和验证数据集为例,您可以使⽤ tf.data.Iterator.from_string_handle 定义⼀个可让您在两个数据集之间切换的可 feeding 迭代器:
机床罩壳# Define training and validation datasets with the same structure.
training_dataset = tf.data.Dataset.range(100).map(
lambda x: x + tf.random_uniform([], -10, 10, tf.int64)).repeat()
validation_dataset = tf.data.Dataset.range(50)
# A feedable iterator is defined by a handle placeholder and its structure. We
# could use the `output_types` and `output_shapes` properties of either
# `training_dataset` or `validation_dataset` here, because they have
# identical structure.
handle = tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(
handle, training_dataset.output_types, training_dataset.output_shapes)
next_element = _next()
# You can use feedable iterators with a variety of different kinds of iterator
# (such as one-shot and initializable iterators).
tf2otraining_iterator = training_dataset.make_one_shot_iterator()
validation_iterator = validation_dataset.make_initializable_iterator()
# The `Iterator.string_handle()` method returns a tensor that can be evaluated
# and used to feed the `handle` placeholder.
training_handle = sess.run(training_iterator.string_handle())
validation_handle = sess.run(validation_iterator.string_handle())
# Loop forever, alternating between training and validation.
while True:
# Run 200 steps using the training dataset. Note that the training dataset is
# infinite, and we resume from where we left off in the previous `while` loop
# iteration.
for _ in range(200):
sess.run(next_element, feed_dict={handle: training_handle})
# Run one pass over the validation dataset.
sess.run(validation_iterator.initializer)
for _ in range(50):
sess.run(next_element, feed_dict={handle: validation_handle})
1.3 从迭代器中读取数据 ¶
<_next() ⽅法返回⼀个或多个 tf.Tensor 对象,这些对象对应于迭代器的下⼀个元素。每次 eval 这些张量时,它们都会获取底层数据集中下⼀个元素的值。(请注意,与 TensorFlow 中的其他有状态对象⼀样,调⽤ _next() 并不会⽴即使迭代器进⼊下个状态。相反,您必须使⽤ Ten
sorFlow 表达式中返回的 tf.Tenso r 对象,并将该表达式的结果传递到 tf.Session.run(),以获取下⼀个元素并使迭代器进⼊下个状态。)
如果迭代器到达数据集的末尾,则执⾏ _next() 指令会产⽣ tf.errors.OutOfRangeError。在此之后,迭代器将处于不可⽤状态;如果需要继续使⽤,则必须对其重新初始化。
dataset = tf.data.Dataset.range(5)
iterator = dataset.make_initializable_iterator()
next_element = _next()
# Typically `result` will be the output of a model, or an optimizer's
# training operation.
result = tf.add(next_element, next_element)
sess.run(iterator.initializer)
print(sess.run(result))  # ==> "0"
print(sess.run(result))  # ==> "2"
print(sess.run(result))  # ==> "4"
print(sess.run(result))  # ==> "6"
print(sess.run(result))  # ==> "8"
try:
sess.run(result)
s.OutOfRangeError:
print("End of dataset")  # ==> "End of dataset"
⼀种常⽤的⽅法是将“训练循环”封装在 try-except 块中:
sess.run(iterator.initializer)
while True:
try:
sess.run(result)
s.OutOfRangeError:
break
如果数据集的每个元素都具有嵌套结构,则 _next() 的返回值将是⼀个或多个 tf.Tensor 对象,这些对象具有相同的嵌套结构:
dataset1 = tf.data.Dataset.from_tensor_slices(tf.random_uniform([4, 10]))
dataset2 = tf.data.Dataset.from_tensor_slices((tf.random_uniform([4]), tf.random_uniform([4, 100])))
dataset3 = tf.data.Dataset.zip((dataset1, dataset2))
iterator = dataset3.make_initializable_iterator()
sess.run(iterator.initializer)
next1, (next2, next3) = _next()
注意:next1、next2、next3 由相同的 op / node 产⽣,因此eval next1、next2 或 next3 中的任何⼀个都会使所有组件的迭代器进⼊下个状态。直流电机编码器
1.4 保存迭代器的状态 ¶

本文发布于:2024-09-22 20:27:06,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/335382.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:迭代   数据   元素
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议