计算图
计算图:Tensorflow程序的计算过程表示一个计算图,与流程图相似。计算图中每一个操作视为一个节点,节点之间的边表示数据的流动。
在编写Tensorflow程序时,系统会自动维护一个默认的计算图,Tensorflow会自动将定义的所有计算操作添加到默认的计算图。通过get_default_graph()获取对默认计算图的引用。
使用Graph()函数生成两个新的计算图以及使用as_default()函数将生成的计算图指定为默认:
g1 = tf.Graph()
with g1.as_default():
//包括创建计算图中的变量等等
a = tf.get_variable("a",[2],intializer=tf.ones_initializer())
不同计算图上的张量和运算不会共享,不能再某一计算图中调用其它计算图中的成员。
对于每一个计算图,Tensorflow通过5个默认的集合(collection)管理其中不同类别的个体,包括张量、变量、队列等。函数add_to_collection()可以将个体加入一个或多个集合中,而get_collection()函数用来获取一个集合中的所有个体。
张量
计算图:Tensorflow的计算模型;张量:Tensorfow的数据模型。
张量可以简单理解为不同维度的数组。零阶张量表示标量(Scaler)也就是一个数。张量保存的是运算结果的属性,而不是真正的数字。
import tensorflow as tf
a = tf.constant([1.0,2.0],name="a")
b = tf.constant([3.0,4.0],name="b")
result = a + b
print(result)
//输出Tensor("add:0",shape=(2,),dtype=float32)
//add表示节点名称,0表示这个张量是节点的第几个输出;数据类型不一致会报错
with tf.Session() as sess:
tf.initialize_all_variables().run()
print(sess.run(result))
// 输出[4.0,6.0]
这说明result是一个张量,保存了加法运算结果的3个属性:操作(op)、维度(shape)、数据类型(dtype)。
会话
会话的定义
使用Tensorflow中的会话(Session)来执行定义好的计算。
Tensorflow系统结构:
- 前端系统:提供编程模型,负责构造计算图;
- 后端系统:提供运行时环境,负责执行计算图。
前端系统中的客户端以Session(会话)为接口与后端系统Distributed Runtime中的Master以及多个Worker(包括CPU、GPU)相连,并启动计算图的执行过程。
会话是Tensorflow程序的运行模型,它管理着程序运行时所有资源。在所有计算完成后,通常需要关闭会话以帮助系统回收资源。
Session类提供了run()方法来执行计算图。用户给run()传入需要计算的节点,同时提供输入数据,Tensorflow就会自动寻找所有需要计算的节点并按顺序执行它们。
Session参数配置
在生成会话时,通常会设置构造函数的config参数来配置会话的一些选项,比如并行的线程数、GPU分配策略等。可以使用ConfigProto()配置Session。
//log_device_placement=True:记录日志文件;allow_soft_placement=True:当运算无法在GPU上执行时将运算转移到CPU
config = tf.ConfigProto(log_device_placement=True,allow_soft_placement=True)
sess = tf.Session(config=config)
变量
创建变量
//使用变量声明函数Variable()声明变量时必须提供初始值
weights = tf.Variable(tf.random_normal([3,4],stddev=1))
//通过其他变量的初始值来初始化新的变量
b = tf.Variable(weights.initialized_value())
//定义init_op为初始化全部变量的操作,之后使用会话执行这个op
init_op = tf.global_variables_initializer()
sess.run()
将一个Tensorflow程序分为两个阶段:
- 定义计算图中的运算
- 运算的执行
集合(collection)
Tensorflow程序中的所有变量都会自动的被加入GraphKeys.VARIABLES集合。通过all_variables()获取到当前计算图上的所有变量。并且,变量声明函数中的trainable参数卡哇伊区分变量是否能够被训练,能够被训练的变量通常会作为神经网络的参数。如果trainable=True,那么这个变量就会被加入GraphKeys.TRAINABLE_VARIABLES集合。可以通过trainable_variables()函数得到GraphKeys.TRAINABLE_VARIABLES集合中的全部内容。
管理变量的变量空间
get_variable()函数
在创建变量时使用方法与Variable()函数基本相同:
//对于name属性,在Variable()函数中,它是一个可选的参数,但是在get_variable()函数中,它是一个必须的参数
a = tf.Variable(tf.constant(1.0,shape=[],name="a"))
a = tf.get_variable("a",shape=[],initializer=tf.constant_initializer(1.0))
在相同的变量空间内使用get_variable()函数创建name属性相同的两个变量会导致错误的发生。reuse参数的默认值是False,当variable_scope()函数使用reuse=True参数生成上下文管理器时,这个上下文管理器内的所有get_variable()函数会直接获取name属性相同的已经创建的变量。
with tf.variable_scope("one"):
a = tf.get_variable("a",shape=[1],initializer=tf.constant_initializer(1.0))
print(a.name)
//输出one/a:0,其中one表示a所属的变量空间,:0表示第一个变量
variable_scope()变量空间与name_scope()变量空间大部分情况下是等价的。但是name_scope()没有reuse这个参数,多用于可视化计算图的时候。