Tensorflow Note

tf.contrib.tpu.TPUEstimator:TPU上运行模型

Estimator是tensorflow的模型级抽象层。
标准Estimators可以在CPU和GPU上运行模型。

维护可在 CPU/GPU 或 Cloud TPU 上运行的模型:最简单的方式是将模型的推理阶段(从输入到预测)定义在 model_fn 之外。确保 Estimator 设置和 model_fn 的单独实现,二者均包含此推理步骤。

在本地运行 TPUEstimator

创建标准 Estimator

调用构造函数,然后将它传递给 model_fn

my_estimator = tf.estimator.Estimator(
  model_fn=my_model_fn)

本地计算机上使用TPUEstimator

构造函数需要两个额外的参数:use_tpu = False,并将 tf.contrib.tpu.RunConfig 以 config 参数的形式传递。

my_tpu_estimator = tf.contrib.tpu.TPUEstimator(
    model_fn=my_model_fn,
    config=tf.contrib.tpu.RunConfig()
    use_tpu=False)

设置命令行标记

python mnist_tpu.py --use_tpu=false --master=''

tf.estimator.Estimator

封装了训练、评估、预测、导出以供使用等操作。

advantage

  1. 在本地主机上或分布式多服务器环境中运行基于 Estimator 的模型,而无需更改模型。
  2. 简化了在模型开发者之间共享实现的过程。
  3. 在 tf.layers 之上构建而成,可以简化自定义过程。
  4. 构建图
  5. 安全的分布式训练循环,以及控制构建图、初始化变量、开始排队、处理异常、创建检查点文件并从故障中恢复、保存TensorBoard的摘要。

使用 Estimator 编写应用时,您必须将数据输入管道从模型中分离出来。这种分离简化了不同数据集的实验流程。

预创建的Estimator

  1. 为您创建和管理 Graph 和 Session 对象
  2. 借助预创建的 Estimator,只需稍微更改下代码,就可以尝试不同的模型架构。
    eg. DNNClassifier 是一个预创建的 Estimator 类,它根据密集的前馈神经网络训练分类模型。

预创建的Estimator程序结构

  1. 编写一个或多个数据集导入函数
    1.1. 可以创建一个函数来导入训练集,并创建另一个函数来导入测试集。
    1.2. 每个数据集导入函数都必须返回两个对象
    一个字典:键(特征名称),值(相应特征数据的张量、Sparse Tensor)
    一个tensor(包含一个或多个标签的tensor)

tf.data

可根据简单的可重用片段构建复杂的输入管道。
可以轻松处理大量数据、不同的数据格式以及复杂的转换。

tf.data.Dataset

  1. 表示一系列元素,其中每个元素包含一个或多个 Tensor 对象
    eg. 在图像管道中,元素可能是单个训练样本,具有一对表示图像数据和标签的张量。
  2. 可以通过两种不同的方式来创建数据集:
    2.1. 创建来源:通过一个或多个tf.Tensor对象构建数据集(eg. Dataset.from_tensor_slices)
    2.2. 转换:以通过一个或多个tf.data.Dataset对象构建数据集(eg. Dataset.batch)

tf.data.Iterator

  1. 数据集中提取元素的主要方法。
  2. Iterator.get_next() 返回的操作会在执行时生成 Dataset 的下一个元素,并且此操作通常充当输入管道代码和模型之间的接口。
  3. 最简单的迭代器:“one-shot iterator”,它与特定的 Dataset 相关联,并对其进行一次迭代。
  4. 要实现更复杂的用途:Iterator.initializer

基本机制(创建Dataset\Iterator对象,及提取数据)

定义数据源source(启动输入管道前)

1.Dataset对象
1.1. 通过内存中某些tensor构建Dataset:tf.data.Dataset.from_tensors() 或 tf.data.Dataset.from_tensor_slices()
1.2. TFRecord格式存储:构建tf.data.TFRecordDataset
2.可以将Dataset 对象转换为新的 Dataset:tf.data.Dataset 对象上的方法调用。
eg.单元素转换: 逐元素变换(Dataset.map());多元素转换(Dataset.batch())
3. 构建迭代器对象

数据集结构

  1. 每个元素包含一个或多个 tf.Tensor 对象:组件
    tf.DType:元素的类型
    tf.TensorShape:每个元素(可能部分指定)的静态形状。(Dataset.output_typesDataset.output_shapes 属性:数据集元素各个组件的推理类型和形状。)
	# Dataset.from_tensor_slices()通过一个或多个tf.Tensor对象构建数据集
	# tf.random_uniform()随机值函数

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

属性的嵌套结构映射到元素(单个张量、张量元组、张量的嵌套元组)的结构。
2. 组件命名
除了元组之外,使用 collections.namedtuple 或将字符串映射到张量的字典表示Dataset 的单个元素。

dataset4 = tf.data.Dataset.from_tensor_slices({
		"a": tf.random_uniform([4]), 
		"b": tf.random_uniform([4,100], maxval=100, dtype=tf.int32)
})

problem: tensor长度不一致??

  1. Dataset转换其他结构数据集:Dataset.map()、Dataset.flat_map()、Dataset.filter()
    Argument destructuring is not available in Python 3

创建迭代器Iterator: 访问数据集中元素

单次迭代器

  1. 不需要显式初始化。
  2. 处理基于队列的现有输入管道支持的几乎所有情况。
  3. 不支持参数化,在程序运行之前确认大小。
  4. 唯一易于与 Estimator 搭配使用的类型
dataset6 = tf.data.Dataset.range(100)
	iterator = dataset6.make_one_shot_iterator()
	next_element = iterator.get_next()

	with tf.Session() as sess:
		sess.run(tf.global_variables_initializer())
		for i in range(100):
			value = sess.run(next_element)
			print(value)
			assert i==value

可初始化迭代器:先运行iterator.initializer。

  1. 允许使用一个或多个tf.placeholder()张量(初始化迭代器时馈送)参数化数据集定义。
  2. feeding机制
  3. iterator.initializer:使用不同的数据集重新初始化和参数化迭代器,可在同一个程序中对训练和验证数据进行多次迭代。
  4. Iterator.get_next():返回对应于有符号下一个元素的 tf.Tensor 对象
	max_value = tf.placeholder(tf.int64, shape=[])
	dataset7=tf.data.Dataset.range(max_value)
	iterator = dataset7.make_initializable_iterator()
	next_element = iterator.get_next()
	
	with tf.Session() as sess:
		# Initialize an iterator over a dataset with 10 elements.
		# tf.placeholder()参数化数据集
		sess.run(iterator.initializer, feed_dict = {max_value: 10})  
		for i in range(10):
			value = sess.run(next_element)

		# 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)

可重新初始化迭代器

通过多个不同的 Dataset 对象进行初始化。
eg:一个训练输入管道,对输入图片进行随机扰动来改善泛化;还有一个验证输入管道,评估对未修改数据的预测。这些管道通常会使用不同的 Dataset 对象(具有相同的结构:即每个组件具有相同类型和兼容形状)。

# 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)  # 均匀分布[min,max)
	)  # dataset转换(对每个元素应用一个函数)
	validation_dataset = tf.data.Dataset.range(50)

	# A reinitializable iterator is defined by its structure.
	# use 'output_types' and 'output_shapes' properties of either 'training_dataset' or 'validation_dataset' here
	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)

	# Run 20 epochs in which the training dataset is traversed, followed by the validation dataset
	with tf.Session() as sess: 
		for _ in range(20):
			# Initialize an iterator over the training dataset. 
			sess.run(training_init_op)
			for _ in range(100):
				print(sess.run(next_element))

			# Initialize an iterator over the validation dataset
			sess.run(validation_init_op)
			for _ in range(50):
				print(sess.run(next_element))

可馈送迭代器

  1. 与tf.placeholder一起使用,选择Iterator(调用tf.Session.run时,feed_dict机制)。
  2. 不需要从数据集开头初始化迭代器,使用tf.data.Iterator.from_string_handle:可在数据集之间切换
  3. Iterator.string_handle() : returns a tensor that can be evaluated and used to feed the handle placeholder.
# a variety of different kinds of iterator
training_iterator = training_dataset.make_one_shot_iterator()
validation_iterator = validation_dataset.make_initializable_iterator()

with tf.Session() as sess:
	# Iterator.string_handle(): 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())
	
	# alternating between training and validation
	for _ in range(2):
		for _ in range(200):
			print(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):
			print(sess.run(next_element, feed_dict = {handle: validation_handle}))

消耗迭代器中的值

调用 Iterator.get_next() 并不会立即使迭代器进入下个状态。您必须在 TensorFlow 表达式中使用此函数返回的 tf.Tensor 对象,并将该表达式的结果传递到 tf.Session.run(),以获取下一个元素并使迭代器进入下个状态。

TF随机数

tf.random_normal() 正态分布
tf.truncated_normal() 截断的正态分布,偏离大于2倍标准差的数会被丢弃再重新选择
tf.random_uniform() 均匀分布[min,max)
tf.random_shuffle() 第一维随机排列
tf.multinomial() 从输入数据value中随机剪切大小为size的部分数据
tf.random_gamma() 伽马分布

sess.run()

feed_dict

  1. 给使用placeholder创建出来的tensor赋值
  2. feed 使用一个 ‘值’ 临时替换一个 op 的输出结果。提供 feed 数据作为 run() 调用的参数。feed 只在调用它的方法内有效,方法结束,feed 就会消失。
import tensorflow as tf
y = tf.Variable(1)
b = tf.identity(y)
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    print(sess.run(b,feed_dict={y:3})) #使用3 替换掉
    #tf.Variable(1)的输出结果,所以打印出来3 
    #feed_dict{y.name:3} 和上面写法等价
    print(sess.run(b))  #由于feed只在调用他的方法范围内有效,所以这个打印的结果是 1

tf.gfile模块:文件操作

基本操作

  1. 该模块有两个类:FastGFile、Gfile
  2. `tf.gfile.Copy(oldpath, newpath, overwrite=False)
  3. tf.gfile.DeleteRecursively(dirname) 删除目录下所有内容
  4. tf.gfile.Exists(filename)
  5. tf.gfile.IsDirectory(dirname)
  6. tf.gfile.ListDirectory(dirname) 返回形式: [filename1, filename2, … filenameN]
  7. tf.gfile.MkDir(dirname) 上层目录必须存在; tf.gfile.MakeDirs(dirname) 上层目录可以不存在
  8. tf.gfile.Remove(filename)
  9. tf.gfile.Rename()
  10. tf.gfile.Stat(filename) 返回目录的统计数据(FileStatistics数据结构)
  11. tf.gfile.Walk(top, in_order=True) 返回一生成器,用于递归目录树,top为顶层目录。
    输出格式:(dirname, [subdirname, subdirname, …], [filename, filename, …])
  12. `tf.gfile.FastGFile(filename, mode)` "无阻塞",以较快方式获取文件操作句柄
    

tf.gfile.FastGFile(filename, mode) & tf.gfile.GFile(filename, mode)

mode: ‘r’, ‘w’, ‘a’, ‘r+’, ‘w+’, ‘a+’. Append ‘b’ for bytes mode.
class FileIO(object):
def init(self, name, mode):
def name(self):
def mode(self):
def size(self):
def write(self, file_content):
def read(self, n=-1): Read ‘n’ bytes if n != -1. If n = -1, reads to end of file.
def readline(self): Reads the next line from the file. Leaves the ‘\n’ at the end.
def readlines(self): Returns all lines from the file in a list.
def tell(self): Returns the current position in the file.
def next(self):
def flush(self): Flushes the Writable file.
def close(self):

角色

C ++ FileSystem API支持多种文件系统实现,包括本地文件,谷歌云存储(以gs://开头)和HDFS(以hdfs:/开头)。 TensorFlow将它们导出为tf.gfile,以便使用这些实现来保存和加载检查点,编写TensorBoard log以及访问训练数据(以及其他用途)。

猜你喜欢

转载自blog.csdn.net/qq_21980099/article/details/84679205