数据流图是每个TensorFlow程序的核心,数据流图是一种特殊类型的有向图,在TensorFlow中,数据流图本质上是一组链接在一起的函数。
两个基础构件:节点和边
节点:在数据流图中,节点通常以圆圈、椭圆和方框表示,代表了对数据所做的运算或某种操作。
边:通常以箭头表示,不同Opetation之间的连接,将信息从一个节点传输到另一个节点,对应向Operation传入和从Operation传出的实际数值。
TensorFlow的核心工作流:
1.定义数据流图
2.运行数据流图(在数据上)
import tensorflow as tf
a = tf.constant(5,name="input_a")
b = tf.constant(3,name="input_b")
c = tf.multiply (a,b,name="mul_c")
d = tf.add(a,b,name="add_d")
e = tf.add(c,d,name="add_e")
sess = tf.Session()
sess.close()
张量即n维矩阵的抽象,1D张量等价于向量,2D张量等价于矩阵,对于更高维数的张量,可称“N维张量”或者“N阶张量”
TensorFlow有数量庞大的数据类型可供使用,但基本的Python类型缺乏对你希望使用的数据类型的种类进行明确声明的能力,例如在Python中,所有整数都具有相同的类型,但TensorFlow却有8位,16位,32位和64位整数类型之分,因此借助numpy数组手工定义Tensor对象。
Session类负责数据流图的执行。创建完Session对象,可利用其主要的方法run()来计算所期望的Tensor对象的输出
Session.run()方法接收一个参数fetches,以及其他三个可选参数:feed_dict,options和run_medadata
1.fetches参数:接收任意的数据流图元素(Op或Tensor对象),如果请求对象为Tensor对象,则run()的输出将为一Numpy数组,如果请求对象为一个Op,则输出将为None.
2.feed_dict用于覆盖数据流图中的Tensor对象值,需要Python字典对象作为输入。字典中的“键”为指向应当被覆盖的Tensor对象的句柄,
而字典的“值”可以是数字、字符创、列表或Numpy数组。值的类型必须与键相同。
import tensorflow as tf
#创建Op、Tensor对象
a = tf.add(2,5)
b = tf.mul(a,3)
#利用默认的数据流图启动一个Session对象
sess = tf.Session()
#定义一个字典,比如将a的值替换为15
replace_dict = {a:15}
#运行Session对象,将replace_dict赋给feed_dict
sess,run(b,feed_dict=replace_dict)
占位符:我们希望从客户那里接收输入值,这样便可对数据流图中所描述的变换以各种不同类型的数值进行复用。创建时无须为它们指定具体的数值,作用是为运行时即将到来的某个Tensor对象预留位置。
import tensorflow as tf
i,mport numpy as np
#创建一个长度为2,数据类型为int32的占位向量
a = tf.placeholder(tf.int32,shape=[2],name="my_input")
#将该占位向量视为其他任意的Tensor对象,加以使用
b = tf.reduce_prob(a,name="prob_b")
c = tf.reduce_sum(a,name="sum_c")
#完成数据流图的定义
d = tf.add(b,c,name="add_d")
调用tf.placeholder()时,dtype参数是必须指定的,而shape参数可选
Variable对象:Tensor对象和Op对象都是不可变的,但机器学习任务的本质决定了需要一种机制保存随时间变化的值。借助Tensorflow中的variable对象,可达到这个目的。Variable对象包含了在对Session.run()多次调用中可持久化的可变张量值。Variable对象的创建
可通过Variable类的构造方法tf.Variable()完成。
import tensorflow as tf
#为Variable对象传入一个初始值3
my_var = tf.Varible(3,name="my_variable")
#Variable对象可用于任何可能会使用Tensor对象的TensorFlow函数或Op中,其当前值将传给使用它的Op
add = tf.add(5,my_var)
mul = tf.multiply(8,my_var)
#Variable对象的初始通常是全0、全1或用随机数填充的阶数较高的张量。为使创建具有这些常见类型初值的张量更加容易,TensorFlow提供了大量辅助的Op
#2*2的零矩阵
zeros = tf.zeros([2,2])
#长度为6的全1向量
ones = tf.ones([6])
#3*3*3的张量,其元素服从0~10的均匀分布
uniform = tf.random_uniform([3,3,3],minval=0,maxval=10)
#3*3*3的张量,其元素服从0均值,标准差为2的正态分布
normal = tf.random_normal([3,3,3],mean=0.0,stddev=2.0)
import tensorflow as tf
#创建一个初始值为1的可变对象
my_var = tf.Variable(1)
#创建一个Op,使其在每次运行时都将该Variable对象乘以2
my_var_times_two = my_var.assign(my_var * 2)
#初始化Op
init = tf.initialize_all_variables()
#启动一个会话
sess = tf.Session()
#初始化Variable对象
sess.run(init)
print(sess.run(my_var_times_two))
print(sess.run(my_var_times_two))
名称作用域:真实世界中的模型往往会包含几十或上百个节点, 以及数以百万计的参数。 为使这种级别的复杂性可控, TensorFlow当前提供了一种帮助用户组织数据流图的机制——名称作用域(name scope)
本质上, 名称作用域允许将Op划分到一些较大的、 有名称的语句块中。 当以
后用TensorBoard加载数据流图时, 每个名称作用域都将对其自己的Op进行封装, 从而获得更好的可视化效果。 名称作用域的基本用法是将Op添加到with tf.name_scope(<name>) 语句块中
import tensorflow as tf
with tf.name_scope("Scope_A"):
a = tf.add(1,2,name="A_add")
b = tf.multiply(a,3,name="A_mul")
with tf.name_scope("Scope_B"):
c = tf.add(4,5,name="B_add")
d = tf.multiply(c,6,name="B_mul")
e = tf.add(b,d,name="output")