使用"with tf.Session()"的目的是什么?

17

我正在练习keras中的concatenate方法。

而这个例子中使用的with语句让我思考了这个语句的用途。

示例代码如下:

import numpy as np 
import keras.backend as K
import tensorflow as tf

t1 = K.variable(np.array([ [[1, 2], [2, 3]], [[4, 4], [5, 3]]]))
t2 = K.variable(np.array([[[7, 4], [8, 4]], [[2, 10], [15, 11]]]))

d0 = K.concatenate([t1 , t2] , axis=-2)

init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    print(sess.run(d0))

然后我检查了来自:tensorflow 的文档,其指出:

会话可以拥有资源,例如tf.Variable、tf.QueueBase和tf.ReaderBase。 当这些资源不再需要时,释放这些资源非常重要。 为此,可以在会话上调用tf.Session.close方法,也可以将会话用作上下文管理器。

我相信这已经解释得很清楚了,但有没有人能给我更加直观的解释呢?

提前感谢并祝您有美好的一天!


3
我不确定还有什么比这更直观了。关键是,就像打开使用资源的文件一样,你需要记得在结束时再将它们关闭。通过将代码缩进到 with 块中,"关闭" 部分已经为你处理好了。一旦跳出该级别的缩进,所有东西都会自动被拆除并释放所有资源。 - roganjosh
一个荒唐的比喻是记得在离开房间时关闭灯光。现在你不必这样做了,with上下文管理器会为你完成它 :) - roganjosh
@roganjosh 但是即使我们离开了这个代码块,t1、t2和d0都不会受到任何影响,对吧? - Pro_gram_mer
2个回答

18

tf.Session()初始化一个 TensorFlow 的 Graph 对象,其中张量通过操作(或 ops)进行处理。使用 with 块在操作完成后终止会话。因此,不需要调用 Session.close。另外,一个会话包含变量、全局变量、占位符和操作。这些需要在创建会话后初始化。因此,我们调用 tf.global_variables_initializer().run()

图包含张量和操作。要初始化一个图,需要创建一个会话来运行图。换句话说,图提供了架构,而会话处理图以计算值(张量)。


1
谢谢!你为我理解这个问题开了一个好头,但它仍然让我深思!那么无论会话是否已关闭,变量都不会受到影响,对吗?那么使用with语句有什么意义呢? - Pro_gram_mer
变量也可以在其他会话中初始化。with语句会自动关闭会话,因此无需调用session.close - user9477964
那么整个意思就是跳过一个步骤,即session.close吗?与某些资源释放无关? - Pro_gram_mer
session.close 会停用图形(graph),但它可以再次被实例化。变量仍然留在图中并保持不变。该图可以在另一个 Session 中被实例化。 - user9477964

7

关于这一点,TensorFlow的文档非常明确。

由于tf.Session拥有物理资源(例如GPU和网络连接),因此通常使用上下文管理器(在with块中)自动关闭会话。

也可以创建一个不使用with块的会话,但是在完成后应显式调用tf.Session.close以释放资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接