TensorFlow程序分为两个独立的部分:
1. 构建任何拟创建神经网络的蓝图
2. 计算图的定义及其执行
计算图:
计算图是包含节点和边的网络。本节定义所有要使用的数据,也就是张量(tensor)对象(常量、变量和占位符),同时定义要执行的所有计算,都是运算操作对象(Operation Object,简称 OP)。
计算图中的节点就是操作
- 一次加法是一个操作
- 一次乘法也是一个操作
- 构建一些变量的初始值也是一个操作
网络中的节点表示对象(张量和运算操作),边表示运算操作之间流动的张量
TensorFlow有两种边:
常规边(实线):代表数据依赖关系。一个节点的运算输出成为另一个节点的输入,两个节点之间有tensor流动(值传递))
特殊边(虚线):不携带值,表示两个节点之间的控制相关性。比如,happens-before关系,表明源节点必须在目的节点执行前完执行
计算图的执行:
使用会话对象来实现计算图的执行。会话对象封装了评估张量和操作对象的环境。这里真正实现了运算操作并将信息从网络的一层传递到另外一层。不同张量对象的值仅在会话对象中被初始化、访问和保存。在此之前张量对象只被抽象定义,在会话中才被赋予实际的意义。
简单实例–向量相加
程序模版
# -*- coding:utf-8 -*-
import tensorflow as tf
def main():
pass
if __name__=='__main__':
main()
# -*- coding:utf-8 -*-
import tensorflow as tf
def add_test():
a=tf.constant([1,2,3,4],name='a')
b=tf.constant([1,2,3,4],name='b')
Sum=tf.add(a,b,name='Sum')
with tf.Session() as sess,tf.summary.FileWriter('./log',sess.graph) as writer:
#打印计算结果
print(sess.run(Sum))
#显示计算图:tensorboard --logdir=log --host=127.0.0.1
# writer=tf.summary.FileWriter('./log',sess.graph)
writer.flush()
# writer.close()
def main():
add_test()
if __name__=='__main__':
main()
结果
分析:
在实例中,计算图由三个节点组成, a 和 b表示这两个向量,add 是要对它们执行的操作。
为了使这个图生效,首先需要使用 tf.Session() 定义一个会话对象 sess,然后使用 Session 类中定义的 run 方法运行它
run(fetches,feed_dict=None,options=None,run_metadata)
#运算结果的值在 fetches 中提取
在示例中,提取的张量为 Sum。
run ()方法将导致在每次执行该计算图的时候,都将对与 Sum相关的张量和操作进行赋值。如果抽取的不是 Sum而是 a,那么最后给出的是向量 a的运行结果为:[1,2,3,4];
此外一次也可以提取一个或多个张量或操作对象[a,b,Sum];在同一段代码中也可以有多个会话对象。
with语法:
with expression [as target]:
with-body
expression是任意表达式,获取上下文管理器,as target可选,with-body是with语句的语句体
with通过__enter__方法初始化,然后在__exit__中做善后以及处理异常。所以使用with处理的对象必须有__enter__()和__exit__()这两个方法。其中__ enter__()方法在语句体(with语句包裹起来的代码块)执行之前进入运行,__ exit __()方法在语句体执行完毕退出后运行。
expression 要返回一个上下文管理器对象,该对象并不赋值给 as 子句中的 target ,如果指定了 as 子句的话,会将上下文管理器的 __enter__方法的返回值赋值给 target。target 可以是单个变量,或者由“()”括起来的元组。不管执行体语句中是否有异常,with语句都能保证执行完毕后关闭打开的句柄。
with tf.Session() as sess,tf.summary.FileWriter('./log',sess.graph) as writer:
expression可以有多个,相同效果可以用嵌套with语句来实现
with tf.Session() as sess:
#打印计算结果
print(sess.run(Sum))
#显示计算图:tensorboard --logdir=log --host=127.0.0.1
with tf.summary.FileWriter('./log',sess.graph) as writer:
writer.flush()
InteractiveSession 和 Session的区别:
tf.InteractiveSession():是一种交替式的会话方式,它让自己成为了默认的会话,也就是说用户在单一会话的情境下,不需要指明用哪个会话也不需要更改会话运行的情况下,就可以运行起来,结果就是运行run和eval()函数可以不指明session
tf.Session():运行run和eval()函数需要指明session。
tf.InteractiveSession():它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。
tf.Session():需要在启动session之前构建整个计算图,然后启动该计算图
sess=tf.InteractiveSession()
print(Sum.eval())
与下面等价
sess=tf.Session()
with sess as default:
print (Sum.eval())