TensorFlow编程人员指南 导入数据.docx

上传人:b****2 文档编号:11498595 上传时间:2023-06-01 格式:DOCX 页数:18 大小:25.21KB
下载 相关 举报
TensorFlow编程人员指南 导入数据.docx_第1页
第1页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第2页
第2页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第3页
第3页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第4页
第4页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第5页
第5页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第6页
第6页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第7页
第7页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第8页
第8页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第9页
第9页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第10页
第10页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第11页
第11页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第12页
第12页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第13页
第13页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第14页
第14页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第15页
第15页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第16页
第16页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第17页
第17页 / 共18页
TensorFlow编程人员指南 导入数据.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

TensorFlow编程人员指南 导入数据.docx

《TensorFlow编程人员指南 导入数据.docx》由会员分享,可在线阅读,更多相关《TensorFlow编程人员指南 导入数据.docx(18页珍藏版)》请在冰点文库上搜索。

TensorFlow编程人员指南 导入数据.docx

TensorFlow编程人员指南导入数据

导入数据

通过 tf.data API,您可以根据简单的可重用片段构建复杂的输入管道。

例如,图片模型的管道可能会汇聚分布式文件系统中的文件中的数据、对每个图片应用随机扰动,并将随机选择的图片合并成用于训练的批次。

文本模型的管道可能包括从原始文本数据中提取符号、根据对照表将其转换为嵌入标识符,以及将不同长度的序列组合成批次数据。

使用 tf.data API可以轻松处理大量数据、不同的数据格式以及复杂的转换。

tf.data API在TensorFlow中引入了两个新的抽象类:

∙tf.data.Dataset 表示一系列元素,其中每个元素包含一个或多个 Tensor 对象。

例如,在图片管道中,元素可能是单个训练样本,具有一对表示图片数据和标签的张量。

可以通过两种不同的方式来创建数据集:

∙创建来源(例如 Dataset.from_tensor_slices()),以通过一个或多个 tf.Tensor 对象构建数据集。

∙应用转换(例如 Dataset.batch()),以通过一个或多个 tf.data.Dataset 对象构建数据集。

∙tf.data.Iterator 提供了从数据集中提取元素的主要方法。

Iterator.get_next() 返回的操作会在执行时生成 Dataset 的下一个元素,并且此操作通常充当输入管道代码和模型之间的接口。

最简单的迭代器是“单次迭代器”,它与特定的 Dataset 相关联,并对其进行一次迭代。

要实现更复杂的用途,您可以通过 Iterator.initializer 操作使用不同的数据集重新初始化和参数化迭代器,这样一来,您就可以在同一个程序中对训练和验证数据进行多次迭代(举例而言)。

基本机制

本指南的这一部分介绍了创建不同种类的 Dataset 和 Iterator 对象的基础知识,以及如何从这些对象中提取数据。

要启动输入管道,您必须定义来源。

例如,要通过内存中的某些张量构建 Dataset,您可以使用 tf.data.Dataset.from_tensors() 或 tf.data.Dataset.from_tensor_slices()。

或者,如果您的输入数据以推荐的TFRecord格式存储在磁盘上,那么您可以构建 tf.data.TFRecordDataset。

有了 Dataset 对象后,您可以通过链接 tf.data.Dataset 对象上的方法调用将其转换为新的 Dataset。

例如,您可以应用单元素转换,例如 Dataset.map()(为每个元素应用一个函数),也可以应用多元素转换(例如 Dataset.batch())。

要了解转换的完整列表,请参阅 tf.data.Dataset 的文档。

消耗 Dataset 中值的最常见方法是构建迭代器对象。

通过此对象,可以一次访问数据集中的一个元素(例如通过调用 Dataset.make_one_shot_iterator())。

tf.data.Iterator 提供了两个操作:

Iterator.initializer,您可以通过此操作(重新)初始化迭代器的状态;以及 Iterator.get_next(),此操作返回对应于有符号下一个元素的 tf.Tensor 对象。

根据您的使用情形,您可以选择不同类型的迭代器,下文介绍了具体选项。

数据集结构

一个数据集包含多个元素,每个元素的结构都相同。

一个元素包含一个或多个 tf.Tensor 对象,这些对象称为组件。

每个组件都有一个 tf.DType,表示张量中元素的类型;以及一个 tf.TensorShape,表示每个元素(可能部分指定)的静态形状。

您可以通过 Dataset.output_types 和 Dataset.output_shapes 属性检查数据集元素各个组件的推理类型和形状。

这些属性的嵌套结构映射到元素的结构,此元素可以是单个张量、张量元组,也可以是张量的嵌套元组。

例如:

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,)))"

为元素的每个组件命名通常会带来便利性,例如,如果它们表示训练样本的不同特征。

除了元组之外,还可以使用 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(lambdax:

...)

dataset2=dataset2.flat_map(lambdax,y:

...)

#Note:

ArgumentdestructuringisnotavailableinPython3.

dataset3=dataset3.filter(lambdax,(y,z):

...)

创建迭代器

构建了表示输入数据的 Dataset 后,下一步就是创建 Iterator 来访问该数据集中的元素。

tf.data API目前支持下列迭代器,复杂程度逐渐增大:

∙单次,

∙可初始化,

∙可重新初始化,以及

∙可馈送。

单次迭代器是最简单的迭代器形式,仅支持对数据集进行一次迭代,不需要显式初始化。

单次迭代器可以处理基于队列的现有输入管道支持的几乎所有情况,但它们不支持参数化。

以 Dataset.range() 为例:

dataset=tf.data.Dataset.range(100)

iterator=dataset.make_one_shot_iterator()

next_element=iterator.get_next()

foriinrange(100):

 value=sess.run(next_element)

 asserti==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=iterator.get_next()

#Initializeaniteratoroveradatasetwith10elements.

sess.run(iterator.initializer,feed_dict={max_value:

10})

foriinrange(10):

 value=sess.run(next_element)

 asserti==value

#Initializethesameiteratoroveradatasetwith100elements.

sess.run(iterator.initializer,feed_dict={max_value:

100})

foriinrange(100):

 value=sess.run(next_element)

 asserti==value

可重新初始化迭代器可以通过多个不同的 Dataset 对象进行初始化。

例如,您可能有一个训练输入管道,它会对输入图片进行随机扰动来改善泛化;还有一个验证输入管道,它会评估对未修改数据的预测。

这些管道通常会使用不同的 Dataset 对象,这些对象具有相同的结构(即每个组件具有相同类型和兼容形状)。

#Definetrainingandvalidationdatasetswiththesamestructure.

training_dataset=tf.data.Dataset.range(100).map(

  lambdax:

x+tf.random_uniform([],-10,10,tf.int64))

validation_dataset=tf.data.Dataset.range(50)

#Areinitializableiteratorisdefinedbyitsstructure.Wecouldusethe

#`output_types`and`output_shapes`propertiesofeither`training_dataset`

#or`validation_dataset`here,becausetheyarecompatible.

iterator=tf.data.Iterator.from_structure(training_dataset.output_types,

                      training_dataset.output_shapes)

next_element=iterator.get_next()

training_init_op=iterator.make_initializer(training_dataset)

validation_init_op=iterator.make_initializer(validation_dataset)

#Run20epochsinwhichthetrainingdatasetistraversed,followedbythe

#validationdataset.

for_inrange(20):

 #Initializeaniteratoroverthetrainingdataset.

 sess.run(training_init_op)

 for_inrange(100):

  sess.run(next_element)

 #Initializeaniteratoroverthevalidationdataset.

 sess.run(validation_init_op)

 for_inrange(50):

  sess.run(next_element)

可馈送迭代器可以与 tf.placeholder 一起使用,通过熟悉的 feed_dict 机制选择每次调用 tf.Session.run 时所使用的 Iterator。

它提供的功能与可重新初始化迭代器的相同,但在迭代器之间切换时不需要从数据集的开头初始化迭代器。

例如,以上面的同一训练和验证数据集为例,您可以使用 tf.data.Iterator.from_string_handle 定义一个可让您在两个数据集之间切换的可馈送迭代器:

#Definetrainingandvalidationdatasetswiththesamestructure.

training_dataset=tf.data.Dataset.range(100).map(

  lambdax:

x+tf.random_uniform([],-10,10,tf.int64)).repeat()

validation_dataset=tf.data.Dataset.range(50)

#Afeedableiteratorisdefinedbyahandleplaceholderanditsstructure.We

#couldusethe`output_types`and`output_shapes`propertiesofeither

#`training_dataset`or`validation_dataset`here,becausetheyhave

#identicalstructure.

handle=tf.placeholder(tf.string,shape=[])

iterator=tf.data.Iterator.from_string_handle(

  handle,training_dataset.output_types,training_dataset.output_shapes)

next_element=iterator.get_next()

#Youcanusefeedableiteratorswithavarietyofdifferentkindsofiterator

#(suchasone-shotandinitializableiterators).

training_iterator=training_dataset.make_one_shot_iterator()

validation_iterator=validation_dataset.make_initializable_iterator()

#The`Iterator.string_handle()`methodreturnsatensorthatcanbeevaluated

#andusedtofeedthe`handle`placeholder.

training_handle=sess.run(training_iterator.string_handle())

validation_handle=sess.run(validation_iterator.string_handle())

#Loopforever,alternatingbetweentrainingandvalidation.

whileTrue:

 #Run200stepsusingthetrainingdataset.Notethatthetrainingdatasetis

 #infinite,andweresumefromwhereweleftoffintheprevious`while`loop

 #iteration.

 for_inrange(200):

  sess.run(next_element,feed_dict={handle:

training_handle})

 #Runonepassoverthevalidationdataset.

 sess.run(validation_iterator.initializer)

 for_inrange(50):

  sess.run(next_element,feed_dict={handle:

validation_handle})

消耗迭代器中的值

Iterator.get_next() 方法返回一个或多个 tf.Tensor 对象,这些对象对应于迭代器有符号的下一个元素。

每次评估这些张量时,它们都会获取底层数据集中下一个元素的值。

(请注意,与TensorFlow中的其他有状态对象一样,调用 Iterator.get_next() 并不会立即使迭代器进入下个状态。

您必须使用TensorFlow表达式中返回的 tf.Tensor 对象,并将该表达式的结果传递到 tf.Session.run(),以获取后续元素并使迭代器进入下个状态。

如果迭代器到达数据集的末尾,则执行 Iterator.get_next() 操作会产生 tf.errors.OutOfRangeError。

在此之后,迭代器将处于不可用状态;如果需要继续使用,则必须对其重新初始化。

dataset=tf.data.Dataset.range(5)

iterator=dataset.make_initializable_iterator()

next_element=iterator.get_next()

#Typically`result`willbetheoutputofamodel,oranoptimizer's

#trainingoperation.

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)

excepttf.errors.OutOfRangeError:

 print("Endofdataset") #==>"Endofdataset"

一种常见模式是将“训练循环”封装在 try-except 块中:

sess.run(iterator.initializer)

whileTrue:

 try:

  sess.run(result)

 excepttf.errors.OutOfRangeError:

  break

如果数据集的每个元素都具有嵌套结构,则 Iterator.get_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)=iterator.get_next()

请注意,next1、next2 和 next3 是由同一个操作/节点(通过 Iterator.get_next() 创建)生成的张量。

因此,评估其中任何一个张量都会使所有组件的迭代器进入下个状态。

典型的迭代器消耗方会在一个表达式中包含所有组件。

保存迭代器状态

tf.contrib.data.make_saveable_from_iterator 函数通过迭代器创建一个 SaveableObject,该对象可用于保存和恢复迭代器(实际上是整个输入管道)的当前状态。

这样创建的可保存对象可以添加到 tf.train.Saver 变量列表或 tf.GraphKeys.SAVEABLE_OBJECTS 集合,以便采用与 tf.Variable 相同的方式进行保存和恢复。

请参阅保存和恢复,详细了解如何保存和恢复变量。

#Createsaveableobjectfromiterator.

saveable=tf.contrib.data.make_saveable_from_iterator(iterator)

#Savetheiteratorstatebyaddingittothesaveableobjectscollection.

tf.add_to_collection(tf.GraphKeys.SAVEABLE_OBJECTS,saveable)

saver=tf.train.Saver()

withtf.Session()assess:

 ifshould_checkpoint:

  saver.save(path_to_checkpoint)

#Restoretheiteratorstate.

withtf.Session()assess:

 saver.restore(sess,path_to_checkpoint)

读取输入数据

消耗NumPy数组

如果您的所有输入数据都适合存储在内存中,则根据输入数据创建 Dataset 的最简单方法是将它们转换为 tf.Tensor 对象,并使用 Dataset.from_tensor_slice

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2