因为后续的自然语言项目使用的深度学习框架主要是tensorflow,所以对tensorflow的基本使用方法做了一些总结。
一.了解tensorflow基本原理
1.tensorflow 使用图来表示计算任务;
2.在被称为Session 的上下文中执行图;
3.使用tensor来表示数据;
4.通过变量(variable)来维护状态;
5.使用feed和fetch可以为任意操作(op)赋值和从中获取数据。
二.tensorflow 的简介
tensorflow 是一个编程系统,使用图来表示计算任务,图中的每一个节点表示一个操作(op),操作之间传递的数据类型为tensor,tensor实际上是一个n维(维度)的向量,在python语言中,tensor返回的数据类型是numpy中的ndarray。tensorflow程序主要包括构建阶段和执行阶段两个部分。例如,在构建阶段通常构建一个图来表示和训练神经网络,然后在执行阶段,反复执行图中的训练操作(op)。
三.图的构建阶段
tensorflow 的构建阶段主要是将op作为图中的节点,然后将op的执行过程描述成图,构建图的第一步是创建源op,源op不需要任何的输入,比如常量,源op的输出传递给其他的op构造器作为输入。tensorflow的python库中有一个默认图(default graph)。
和图的构建过程相关的类和函数的详细情况如下:
链接:
https://github.com/jikexueyuanwiki/tensorflow-zh/blob/master/SOURCE/api_docs/python/framework.md#Graph
四.图的执行阶段。
1、在执行阶段,首先需要做的是启动图,启动图的第一步是创建一个Session对象,如果无任何构造参数,会话构造器将启动默认图。
例子:
# 启动默认图.
sess = tf.Session()
# 调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数.
# 上面提到, 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回
# 矩阵乘法 op 的输出.
#
# 整个执行过程是自动化的, 会话负责传递 op 所需的全部输入. op 通常是并发执行的.
#
# 函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行.
#
# 返回值 'result' 是一个 numpy `ndarray` 对象.
result = sess.run(product)
print result
# ==> [[ 12.]]
# 任务完成, 关闭会话.
sess.close()
2、Session对象在使用完后需要关闭以释放资源,除了显示调用close()外,还可以使用with代码块来自动关闭:
with tf.Session() as sess:
result = sess.run([product])
print result
tensorflow中使用session 来启动图,并且调用session.run()方法执行操作。
3、为了便于使用类似于Ipython 之类的python交互式环境,可以使用InteractiveSession 代替Session类,使用tensor.eval()和Operation.run()方法代替Session.run(),这样就可以避免使用一个变量来持有会话。
例子:
#进入一个tensorflow 交互式会话
import tensorflow as tf
session = tf.InteractiveSession()
x = tf.Variable([1.0, 2.0])
a = tf.constant([3.0, 3.0])
# 使用初始化器 initializer op 的 run() 方法初始化 'x'
x.initializer.run()
# 增加一个减法 sub op, 从 'x' 减去 'a'. 运行减法 op, 输出结果
sub = x - a
print sub.eval()
# ==> [-2. -1.]
五.fetch,即从图的op输出中获取数据
为了取回操作的输出内容, 可以在使用 Session 对象的 run() 调用执行图时, 如果传入一些 tensor, 这些 tensor 会帮助你取回结果.如果传入operation,则会执行这个操作。 在之前的例子里, 我们只取回了单个节点 state, 但是你也可以取回多个 tensor:
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)
with tf.Session() as sess:
result = sess.run([mul, intermed])
print result
# 输出:
# [array([ 21.], dtype=float32), array([ 7.], dtype=float32)]
六.feed,即对图中的操作进行赋值。
上述示例在计算图中引入了 tensor, 以常量或变量的形式存储. TensorFlow 还提供了 feed 机制, 该机制 可以临时替代图中的任意操作中的 tensor 可以对图中任何操作提交补丁, 直接插入一个 tensor.
feed 使用一个 tensor 值临时替换一个操作的输出结果. 你可以提供 feed 数据作为 run() 调用的参数. feed 只在调用它的方法内有效, 方法结束, feed 就会消失. 最常见的用例是将某些特殊的操作指定为 "feed" 操作, 标记的方法是使用 tf.placeholder() 为这些操作创建占位符.
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.mul(input1, input2)
with tf.Session() as sess:
print sess.run([output], feed_dict={input1:[7.], input2:[2.]})
# 输出:
# [array([ 14.], dtype=float32)]
for a larger-scale example of feeds. 如果没有正确提供 feed, placeholder() 操作将会产生错误.
七.tensorflow中的变量
变量用来维护图在执行过程中的状态信息。
当训练模型时,使用变量来存储和更新参数.变量(包含张量)存放于内存的缓存区,建模时,它们被明确的初始化,模型训练完后它们必须被存储到磁盘上,这些值可在模型之后的训练和分析时被加载。
1、变量的创建
当创建变量时,你将一个张量作为初始值传入变量的构造函数Variable(),tensorflow 提供了一系列的操作符来初始化张量,初始值一般是常量或随机量。
tf.Variable(init_value, trainable,name,dtype ,collection)
param: init_value :初始化变量的值,可以是常量或者其它变量(都是张量)
param:dtype:变量的数据类型
调用tf.Variable() 时,将会添加一些操作(op)到graph中,这些操作主要包括:
a.一个Variable 操作存放变量的值;
b.一个初始化操作将变量设置为初始值;
c.对初始值的操作。
例子:
# Create two variables.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")
2、变量的初始化
变量的初始化操作(init_op)必须在其他操作之前明确的被完成。一般,使用Session 对象启动图后,一定要先对变量进行初始化(init)操作(op),不然在后续的运行过程中会出现“使用了未初始化的变量”的错误。
变量初始化操作的方式有以下几种:
a、全局初始化,即添加一个给所有变量进行初始化的操作,并在使用模型之前运行这个操作:
例子:
# Create two variables.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")
...
# Add an op to initialize the variables.
init_op = tf.initialize_all_variables() #后面的版本该函数变成tf.global_variables_initializer()
# Later, when launching the model
with tf.Session() as sess:
# Run the init operation.
sess.run(init_op)
...
# Use the model
...
b、由其他变量进行初始化
由于全局初始化变量操作是并行地初始化所有的变量,所以有这种需求时需要小心(具体是为哈我现在还没碰到)。
用其他变量初始化一个新变量时,使用其他变量的initialized_value()属性。
例子:
# Create a variable with a random value.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
name="weights")
# Create another variable with the same value as 'weights'.
w2 = tf.Variable(weights.initialized_value(), name="w2")
# Create another variable with twice the value of 'weights'
w_twice = tf.Variable(weights.initialized_value() * 0.2, name="w_twice")
c、使用checkpoint文件来重新获取变量的值。
注意,当你从文件中恢复变量时,不需要事先对它们做初始化,实际上,恢复过程就相当于重新进行了初始化。
d、自定义初始化
tf.global_variables_initializer()函数便捷地添加一个op来初始化模型的所有变量。你也可以给它传入一组变量进行初始化。详情请见Variables Documentation,包括检查变量是否被初始化。
3、变量的保存和加载
最简单的保存和恢复模型的方法是使用tf.train.Saver对象。构造器给graph的所有变量,或是定义在列表里的变量,添加save和restore操作。saver对象提供了方法来运行这些op,定义检查点文件的读写路径。
什么事检查点文件?
检查点文件是指变量存储在二进制文件里,主要包含从变量名到tensor值的映射关系的文件。
当你创建一个Saver对象时,你可以选择性地为检查点文件中的变量挑选变量名。
默认情况下,检查点文件将存储每个变量Variable.name属性的值。
4、变量的保存
用tf.train.Saver()创建一个Saver来管理模型中的所有变量。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add an op to initialize the variables.
init_op = tf.initialize_all_variables()
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, initialize the variables, do some work, save the
# variables to disk.
with tf.Session() as sess:
sess.run(init_op)
# Do some work with the model.
..
# Save the variables to disk.
save_path = saver.save(sess, "/tmp/model.ckpt")
print "Model saved in file: ", save_path
5、变量的恢复
用同一个Saver对象来恢复变量。注意,当你从文件中恢复变量时,不需要事先对它们做初始化。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session() as sess:
# Restore variables from disk.
saver.restore(sess, "/tmp/model.ckpt")
print "Model restored."
# Do some work with the model
...
*选择存储和恢复哪些变量
如果你不给tf.train.Saver()传入任何参数,那么saver将处理graph中的所有变量。其中每一个变量都以变量创建时传入的名称被保存。
有时候在检查点文件中明确定义变量的名称很有用。举个例子,你也许已经训练得到了一个模型,其中有个变量命名为"weights",你想把它的值恢复到一个新的变量"params"中。
有时候仅保存和恢复模型的一部分变量很有用。再举个例子,你也许训练得到了一个5层神经网络,现在想训练一个6层的新模型,可以将之前5层模型的参数导入到新模型的前5层中。
你可以通过给tf.train.Saver()构造函数传入Python字典,很容易地定义需要保持的变量及对应名称:键对应使用的名称,值对应被管理的变量。
注意:
?如果需要保存和恢复模型变量的不同子集,可以创建任意多个saver对象。同一个变量可被列入多个saver对象中,只有当saver的restore()函数被运行时,它的值才会发生改变。
?如果你仅在session开始时恢复模型变量的一个子集,你需要对剩下的变量执行初始化op。详情请见tf.initialize_variables()。
# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add ops to save and restore only 'v2' using the name "my_v2"
saver = tf.train.Saver({"my_v2": v2})
# Use the saver object normally after that.
八、Tensor
TensorFlow 程序使用 tensor 数据结构来代表所有的数据, 计算图中, 操作间传递的数据都是 tensor. 你可以把 TensorFlow tensor 看作是一个 n 维的数组或列表. 一个 tensor 包含一个静态类型 rank, 和 一个 shape. 想了解 TensorFlow 是如何处理这些概念的, 参见 Rank, Shape, 和 Type.
变量
Variables for more details. 变量维护图执行过程中的状态信息. 下面的例子演示了如何使用变量实现一个简单的计数器. 参见 变量 章节了解更多细节.
# 创建一个变量, 初始化为标量 0.
state = tf.Variable(0, name="counter")
# 创建一个 op, 其作用是使 state 增加 1
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)
# 启动图后, 变量必须先经过`初始化` (init) op 初始化,
# 首先必须增加一个`初始化` op 到图中.
init_op = tf.initialize_all_variables()
# 启动图, 运行 op
with tf.Session() as sess:
# 运行 'init' op
sess.run(init_op)
# 打印 'state' 的初始值
print sess.run(state)
# 运行 op, 更新 'state', 并打印 'state'
for _ in range(3):
sess.run(update)
print sess.run(state)
# 输出:
# 0
# 1
# 2
# 3
代码中 assign() 操作是图所描绘的表达式的一部分, 正如 add() 操作一样. 所以在调用 run() 执行表达式之前, 它并不会真正执行赋值操作.
通常会将一个统计模型中的参数表示为一组变量. 例如, 你可以将一个神经网络的权重作为某个变量存储在一个 tensor 中. 在训练过程中, 通过重复运行训练图, 更新这个 tensor.