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
- 在本地主机上或分布式多服务器环境中运行基于 Estimator 的模型,而无需更改模型。
- 简化了在模型开发者之间共享实现的过程。
- 在 tf.layers 之上构建而成,可以简化自定义过程。
- 构建图
- 安全的分布式训练循环,以及控制构建图、初始化变量、开始排队、处理异常、创建检查点文件并从故障中恢复、保存TensorBoard的摘要。
使用 Estimator 编写应用时,您必须将数据输入管道从模型中分离出来。这种分离简化了不同数据集的实验流程。
预创建的Estimator
- 为您创建和管理 Graph 和 Session 对象。
- 借助预创建的 Estimator,只需稍微更改下代码,就可以尝试不同的模型架构。
eg. DNNClassifier 是一个预创建的 Estimator 类,它根据密集的前馈神经网络训练分类模型。
预创建的Estimator程序结构
- 编写一个或多个数据集导入函数
1.1. 可以创建一个函数来导入训练集,并创建另一个函数来导入测试集。
1.2. 每个数据集导入函数都必须返回两个对象:
一个字典:键(特征名称),值(相应特征数据的张量、Sparse Tensor)
一个tensor(包含一个或多个标签的tensor)
tf.data
可根据简单的可重用片段构建复杂的输入管道。
可以轻松处理大量数据、不同的数据格式以及复杂的转换。
tf.data.Dataset
- 表示一系列元素,其中每个元素包含一个或多个 Tensor 对象。
eg. 在图像管道中,元素可能是单个训练样本,具有一对表示图像数据和标签的张量。 - 可以通过两种不同的方式来创建数据集:
2.1. 创建来源:通过一个或多个tf.Tensor对象构建数据集(eg. Dataset.from_tensor_slices)
2.2. 转换:以通过一个或多个tf.data.Dataset对象构建数据集(eg. Dataset.batch)
tf.data.Iterator
- 从数据集中提取元素的主要方法。
- Iterator.get_next() 返回的操作会在执行时生成 Dataset 的下一个元素,并且此操作通常充当输入管道代码和模型之间的接口。
- 最简单的迭代器:“one-shot iterator”,它与特定的 Dataset 相关联,并对其进行一次迭代。
- 要实现更复杂的用途: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. 构建迭代器对象。
数据集结构
- 每个元素包含一个或多个 tf.Tensor 对象:组件。
tf.DType:元素的类型
tf.TensorShape:每个元素(可能部分指定)的静态形状。(Dataset.output_types 和 Dataset.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长度不一致??
- Dataset转换其他结构数据集:Dataset.map()、Dataset.flat_map()、Dataset.filter()
Argument destructuring is not available in Python 3
创建迭代器Iterator: 访问数据集中元素
单次迭代器
- 不需要显式初始化。
- 处理基于队列的现有输入管道支持的几乎所有情况。
- 不支持参数化,在程序运行之前确认大小。
- 唯一易于与 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。
- 允许使用一个或多个tf.placeholder()张量(初始化迭代器时馈送)参数化数据集定义。
- feeding机制。
- iterator.initializer:使用不同的数据集重新初始化和参数化迭代器,可在同一个程序中对训练和验证数据进行多次迭代。
- 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))
可馈送迭代器
- 与tf.placeholder一起使用,选择Iterator(调用tf.Session.run时,feed_dict机制)。
- 不需要从数据集开头初始化迭代器,使用tf.data.Iterator.from_string_handle:可在数据集之间切换
- 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
- 给使用placeholder创建出来的tensor赋值
- 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模块:文件操作
基本操作
- 该模块有两个类:FastGFile、Gfile
- `tf.gfile.Copy(oldpath, newpath, overwrite=False)
tf.gfile.DeleteRecursively(dirname)
删除目录下所有内容tf.gfile.Exists(filename)
tf.gfile.IsDirectory(dirname)
tf.gfile.ListDirectory(dirname)
返回形式: [filename1, filename2, … filenameN]tf.gfile.MkDir(dirname)
上层目录必须存在;tf.gfile.MakeDirs(dirname)
上层目录可以不存在tf.gfile.Remove(filename)
tf.gfile.Rename()
tf.gfile.Stat(filename)
返回目录的统计数据(FileStatistics数据结构)tf.gfile.Walk(top, in_order=True)
返回一生成器,用于递归目录树,top为顶层目录。
输出格式:(dirname, [subdirname, subdirname, …], [filename, filename, …])-
`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以及访问训练数据(以及其他用途)。