TensorFlow的运行模型—session(会话),用来执行定义好的运算,会话拥有并管理TensorFlow程序运行时的所有资源,所以当运算结束后需要对资源回收,否则可能会出现资源泄漏的问题。当然我们是可以通过关闭会话的方式回收资源,还有一种更为简便的方式就是使用Python的上下文管理器。 在说明TensorFlow的会话操作之前,先介绍上下文管理器和它的一个其他使用。 在使用Python编程中,可以会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作(如打开文本);当语句块执行完成后,需要继续执行一些收尾动作(如收回资源)。这就好比OpenCV1.0版本时,我们在开头定义了一个IplImage类型的变量,总要在程序结束前 cvReleaseImage它,不然就会造成内存的泄漏,而这也是1.0版本的一个很大的诟病,直到2.0版之后引入了Mat类型,而Python的上下文管理器就相当于Mat类型,不需要在最后手动收回,不需要考虑代码异常情况下的资源收回。(这个例子可能并不准确,但是可以直观的说明上下文管理器的最大优点:简便的内存管理,异常下的内存回收)
下面举一个简单的例子,比如我们想要完成一个文件写入的任务: 1.用手动收回的方式:
logger = open("log.txt", "w")
logger.write('Hello ')
logger.close()
print logger.closed
就像这样,当代码执行到logger.close()
时会关闭之前打开着的txt文件,但是这样就会出现一个问题,如果代在logger.close()
前就出现了异常,那么就没办法完成回收工作,所以我们也可以考虑用try-finally语句。
2.加入try-finally并手动收回
logger = open("log.txt", "w")
try:
logger.write('Hello ')
finally:
logger.close()
print logger.closed
try-finally就像C++中的try/catch异常捕获机制一样,即使出现异常,也能保证关闭文件句柄。但是这样的方式还是要麻烦一些。
3.使用上下文管理器
with open("log.txt", "w") as logger:
logger.write('Hello ')
logger.write('World')
print logger.closed
是的,只需要在程序块前加上with,就可以实现上下文管理器的功能,比方法2简洁了很多。但是需要说明的是with仅能工作于支持上下文管理协议(context management protocol)的对象。
我们可以通过可以直接通过内建函数dir()来查看对象支持的方法和属性,如果其中包含了'__enter__', '__exit__',
即支持上下文管理协议。
最后说回TensorFlow的会话操作,手动收回资源的方式就是关闭会话:
sess = tf.Senssion()
sess.run()
sess.close()
而使用上下文管理器后:
with tf.Senssion() as sess:
sess.run()