Skip to main content
 首页 » 编程设计

python之Tensorflow 使用 Context Manager 与使用 Session

2024年12月31日28davidwang456

我试图了解 with block 在上述情况下的行为方式。我假设总是只有一张图和一个 session 。我知道我有(至少?)2 种方法可以在 with block 中使用 session :

示例 1: 使用 as_default()创建一个上下文管理器:
Same documentation说:

Use with the with keyword to specify that calls to tf.Operation.run or tf.Tensor.eval should 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 ,但这主要是我想的个人品味问题。