计算图 和 默认计算图
想在计算图里定义Variable、Tensor、Option等节点的话,必须要先将该计算图设置为“默认计算图”。
注意,这里的设置只是临时的,离开上下文环境后便不再是“默认计算图”了!
# 如果去掉 as_default() 就会报错
with tf.Graph().as_default() as graph:
...
会话 和 默认会话
会话运行计算图的三种情况:
- 默认运行“默认计算图”
- 显示指定“新的计算图”
with tf.Graph().as_default() as graph: # 临时设置为默认计算图
[...]
with tf.Session(graph=graph) as sess: # 显示指定计算图名
[...]
- 在新的计算图上下文环境中运行的是该计算图
with tf.Graph().as_default() as new:
[...]
with tf.Session() as sess: # 这里运行的是计算图 new
[...]
想执行计算图,有两种方法:
- 用会话的
run
方法, - 用节点自己的
run
或eval
方法。
想调用节点自己的 run
或 eval
方法,必须在会话的上下文环境中。
a = tf.constant(1)
with tf.Session() as sess:
sess.run(a) # 正确
a.eval() # 正确
sess = tf.Session()
sess.run(a) # 正确
a.eval() # 报错
sess.close()
节点调用自己的 run
或 eval
方法,实质是用的“默认会话”的 run
方法。
在交互式环境中,因为 tf.InteractiveSession()
可以将创建的会话自动设置为默认会话,自然就可以用节点自己的方法了。
>>> sess = tf.InteractiveSession()
>>> sess.run(a) # 正确
>>> a.eval(a) # 正确
>>> sess.close()
计算机制
a = tf.constant(1)
b = a + 1
c = b + 1
with tf.Session() as sess:
b.eval()
c.eval()
在执行时,tensorflow会自动找所求节点所依赖的节点,即在计算张量 b
时,会先计算 a
。
同理,计算张量 c
时,tensorflow会发现 c
依赖 b
,b
依赖 a
,于是先去计算 ‘a’ ,再去计算 ‘b’ 。是的,tensorflow会重新计算!
像这种情况,会耽误时间,解决方案就是下面这种写法:
with tf.Session() as sess:
sess.run([b, c])