依赖关系: 对于任意节点A,如果其输出对于某个后继节点B的计算是必需的,则称节点A为节点B的依赖节点。分为直接依赖和间接依赖,这可以直接字面理解。
如果某个节点A和节点B彼此不需要来自对方的任何信息,则称两者是独立的。
若A是B的依赖节点,那么B需要来自A的输入,若A无法进行计算,B也无法执行计算,只能一直等待A的数据的到来。
因此,若产生了循环依赖,两个节点都会无法执行,因为他们都在等待对方计算的完成。
设置初始值:
(1)由于数据流图中存在无限循环,因此程序无法以优雅的方式终止。
(2)依赖节点的数量变为无穷大,在统计依赖节点数量时,每个节点都不会只被统计一次,每当其输出发生变化时,它就会被再次标记为依赖节点。这使得追踪依赖信息变得不可能。
(3)被传递的值趋向于正无穷或负无穷或0。
数据流图的展开
TensorFlow工作模式
1)定义数据流图
2)运行数据流图(在数据上)
在TensorFlow中,数据流图中的每个节点都被称为一个Operation(简称为Op)。各Op可接收0个或多个Tensor对象作为输入,并输出0个或多个Tensor对象。tf.constant()创建了一个“常量”Op,它接收单个常量值,然后把同样的值输出给与其直接连接的节点。另有一个字符串参数name,用于对节点标识:
a= tf.constant(5, name=”input_a”)
tf.multiplyOp接收两个输入,然后把他们的乘积输出。tf.addOp接收两个输入,然后把他们的和输出。对于这些Op,我们均传入了name参数。无需专门对数据流图的边进行定义。
tf.mul,tf.sub and tf.neg are deprecated in favor of tf.multiply, tf.subtractand tf.negative
为运行数据流图,需要创建一个TensorFlowSession对象:
sess= tf.Session()
Session对象在运行时负责对数据流图进行监督,并且是运行数据流图的主要接口。
sess.run(e)
这让我们可以看到节点e的运行结果。
TensorBoard 对数据流图可视化
writer=tf.summary.FileWriter
(‘./my_graph’,sess.graph)
创建了一个TensorFlow的FileWiter
对象,第一个参数是一个字符串输出目录,即数据流图的描述在磁盘中的存放路径,运行Python代码的my——graph路径下。第二个输入是Session对象的graph属性,该属性引用了所要追踪的数据流图。FileWiter
对象会将对该数据流图的描述输出到“my_graph”路径下。
启动一个使用来自“my_graph”目录下的数据的TensorBoard服务器:
$tensorboard –logdir="my_graph"
完成数据流图的构造,需要将Session对象和FileWriter对象关闭,释放资源:
writer.close()
sess.close()
张量:即n维矩阵的抽象。1D张量相当于向量,2D张量相当于矩阵,更高维数的张量,称“N维张量”。
a= tf.constant([5, 3], name="input_a")
b= tf.reduce_prod(a, name="prob_b")
c= tf.reduce_sum(a, name="sum_c")
d= tf.add(b, c, name="add_d")
给定某个张量作为输入,Op接收其所有分量,分别将它们相乘或相加。
TensorFlow有数量及其庞大的数据类型可供使用,但基本的Python类型缺乏对你希望使用的数据类型的种类进行明确声明的能力,因此借助NumPy数组手工定义Tensor对象。
在NumPy中没有与tf.string精确对应的类型,因此在NumPy中使用字符串不要显式指定dtype属性。
不要用tf.int32去初始化一个NumPy数组。
希望检查张量值是否相同:
tf.equal()和tf.not_equal()
TensorFlowSession
sess.run(fetches,feed_dict)
fetches参数要么是Tensor对象要么是一个Op,Tensor对象输出为一个NumPy数组,Op输出为None。
feed_dict参数
a= tf.add(2, 5)
b= tf.mul(a, 3)
sess= tf.Session()
replace_dict= {a: 15}
sees.run(b, feed_dict=replace_dict)
意味着如果有大规模的数据流图,我们希望用一些虚构的值对某些部分进行测试,TensorFlow不会在不必要的地方浪费时间。
占位节点:为运行时即将到来的某个Tensor对象预留位置
a= tf.placeholder(tf.int32, shape=[2], name="my_input")
dtype参数必须指定,shape参数可选,为None时表示可接收任意形状的Tensor对象。
通过sess.run()中的feed_dict参数传入值:
input_dict= {a: np.array([5, 3], dtype=np.int32)}
a= tf.placeholder(tf.int32, shape=[2], name="my_input")
b= tf.reduce_prod(a, name="prod_b")
c= tf.reduce_sum(a, name="sum_c")
d= tf.add(b, c, name="add_d")
sess= tf.Session()
input_dict= {a: np.array([5, 3], dtype=np.int32)}
sess.run(d,feed_dict=input_dict)
placeholder的值无法计算——传入sess.run()会引发异常。
Variable对象
Variable对象的初值通常是全0或者全1或用随机数填充的张量。
#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)
#服从0均值,标准差为2的正态分布
normal= tf.random_normal([3, 3, 3], mean=0.0, stddev=2.0)
#不会返回任何均值超过2倍标准差的值
trunc= tf.truncated_normal([2, 2], mean=5.0, stddev=1.0)
#默认均值为0,标准差为1.0
random_var= tf.Variable(tf.truncated_normal([2, 2]))
Variable是由Session对象管理的,需要对Variable对象初始化,Session对象才会跟踪这个Variable对象的值的变化。
init= tf.global_variables_initializer()
#跟踪一个Variable对象子集
init= tf.variables_initializer([var1], name="init_var1")
Variable.assign()是一个Op,要使其生效必须在一个Session对象中运行
my_var= tf.Variable(1)
my_var_times_two= my_var.assign(my_var * 2)
init= tf.global_variables_initializer()
sess=tf.Session()
sess.run(init)
sess.run(my_var_times_two)