我试图了解 with block 在上述情况下的行为方式。我假设总是只有一张图和一个 session 。我知道我有(至少?)2 种方法可以在 with block 中使用 session :
示例 1: 使用 as_default()创建一个上下文管理器:
Same documentation说:
Use with the
withkeyword to specify that calls totf.Operation.runortf.Tensor.evalshould be executed in this session.
# Create session
sess = tf.Session()
# Enter with block on a new context manager
with sess.as_default():
# Train: Following line should result calling tf.Operation.run
sess.run([optimizer, loss], feed_dict={x: x_train, y: y_train)
# Eval: Following line should result calling tf.Tensor.eval
sess.run([loss], feed_dict={x: x_eval, y: y_eval)
示例 2: 如 same documentation in a lower section 中所述在 session 中进行阻止:
Alternatively, you can use
with tf.Session():to create a session that is automatically closed on exiting the context, including when an uncaught exception is raised.
# Enter with block on session instead of Context Manager
with tf.Session() as sess:
# Train: Following line seems calling tf.Operation.run as per my test
sess.run([optimizer, loss], feed_dict={x: x_train, y: y_train)
# Eval: Following is unclear
sess.run([loss], feed_dict={x: x_eval, y: y_eval)
我想了解什么是正确的用法,因为我看到了这两种情况的 GitHub 示例,但当然没有结果。在我的测试中,示例 1 和示例 2 都适用于训练。对于评估,似乎存在我无法理解的差异。浏览 Tensorflow 源代码超出了我的知识范围。有人可以解释一下吗?
请您参考如下方法:
它们做的事情略有不同,因此根据用法的不同,它们可能正确也可能不正确。 tf.Session.as_default()只会确保 session 设置为默认 session ,因此调用 eval 和 run 将默认使用该 session :
import tensorflow as tf
sess = tf.Session()
with sess.as_default():
print(sess is tf.get_default_session()) # True
但是,如文档中所述,tf.Session.as_default() 不会在 with block 之后自动关闭 session 。如果需要,您可以使用 session 本身作为上下文管理器:
import tensorflow as tf
with tf.Session() as sess:
# Do something with the session
sess.run([]) # RuntimeError: Attempted to use a closed Session.
然而,尽管(从我的角度来看)没有明确记录,使用 session 作为上下文管理器也使其成为默认 session 。
import tensorflow as tf
with tf.Session() as sess:
print(sess is tf.get_default_session()) # True
tf.Session.as_default() 有什么意义? , 然后?好吧,只是当你想暂时将一个 session 设置为默认 session 但之后又不想关闭它时(在这种情况下你应该稍后手动关闭它,或者将它用作外部上下文管理器)。当您有多个打开的 session 时,这可能是最相关的。考虑以下情况:
import tensorflow as tf
with tf.Session() as sess1, tf.Session() as sess2:
print(sess2 is tf.get_default_session()) # True
这里 sess2 是默认的,因为它的上下文是后来添加的(它可以被认为是 sess1 创建的上下文的“内部”)。但现在您可能想暂时将 sess1 设置为默认值。但是,您不能再次将 sess1 本身用作上下文管理器:
import tensorflow as tf
with tf.Session() as sess1, tf.Session() as sess2:
# Do something with sess2
with sess1:
# RuntimeError: Session context managers are not re-entrant.
# Use `Session.as_default()` if you want to enter
# a session multiple times.
因此您可以使用 tf.Session.as_default() 在一个和其他默认 session 之间切换:
import tensorflow as tf
with tf.Session() as sess1, tf.Session() as sess2:
with sess1.as_default():
# Do something with sess1
with sess2.as_default():
# Do something with sess2
# This is not really needed because sess2 was the default
# in the outer context but you can add it to be explicit
# Both sessions are closed at the end of the outer context
当然,如果你愿意,即使在一次 session 中你也可以更加明确:
import tensorflow as tf
with tf.Session() as sess, sess.as_default():
# ...
就我个人而言,我从未使用过tf.Session.as_default()在我的实际代码中,但话又说回来,我很少需要使用多个 session ,我更喜欢使用 tf.Session.run()而不是依赖默认 session ,但这主要是我想的个人品味问题。
