《深入了解TensorFlow》笔记——Chapter 3.4 运行环境:会话


TF数据流图描述了计算的拓扑结构和所需的数据属性,但数据流图本身只是一个“壳”。只有图feed数据、选择带求解的张量,并执行了相应计算之后,才能够获取到最终的结果。 TF.Session()为用户提供了上述计算过程的运行环境,它本质上是在维护一段运行时上下文。Session通过提取和切分数据流图、调度并执行操作节点,将抽象的计算拓扑转化为设备上的执行流,最终完成计算任务。

普通会话

TF会话提供了求解张量和执行操作的运行环境。他是发放计算任务的客户端,所有计算任务都由它发到其连接的执行引擎完成。TF session的典型流程分为三步:创建会话->运行会话->关闭会话

创建会话

Session为TF数据流图提供运行环境,一般通过调用Session类的constructor来创建session实例。其主要属性包括:

  • target:会话连接的执行引擎
  • graph:会话加载的数据流图
  • config:会话启动时的配置项

target参数默认指向进程内引擎(in-process engine),因此用户执行单机任务是无需显式给出。本节仅考虑单机运行场景,分布式运行模式将在chapter 5.2介绍。

graph参数默认指向当前代码中的唯一一幅默认数据流图。当用户没有设置graph参数时,session会加载默认数据流图。当用户定义了多幅数据流图是,则需要通过graph显式指定待加载的数据流图。

config参数给出了session的各项配置信息,通过ConfigProto类的constructor创建config参数。 Session的主要config参数如下表所示

参数名称功能说明数据类型
device_count设备数量字典,如<设备类型,最大使用数量>map<string, int32>
intra_op_parallelism_threads独立操作并行计算线程数int32
inter_op_parallelism_threads阻塞操作并行计算线程数int32
use_per_session_threads是否使用一套独立线程池代替全局线程池bool
session_inter_op_thread_pool线程池配置参数ThreadPoolOptionProto
placement_period重新计算分配节点到设备的周期int32
device_filters过滤掉不使用的设备string
gpu_optionsGPU配置参数GPUOptions
allows_soft_placement在没有GPU可用时,是否将操作放置到CPU执行bool
log_device_placement是否打印设备放置日志bool
graph_options数据流图的配置参数GraphOptions
operation_timeout_in_ms阻塞操作的最长时限int64
rpc_options分布式任务运行时的RPC配置参数RPCOptions

例如:如果用户希望在没有GPU是,TF能够自动将计算任务转移到CPU上进行,并希望通过日志验证放置情况,那么可以使用如下参数创建session:

configure = tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)
sess = tf.Session(config=configure)

运行会话

运行会话是指基于数据流图和输入数据,求解张量或执行操作的过程。Session类用于运行会话的方法是run()。其输入参数包括:

  • fetches:带求解的张量或操作
  • feed_dict:数据填充字典,如<数据节点,填充数据>
  • options:RunOptions对象,用于设置会话运行时的可选特性开关
  • run_metadata:RunMetadata对象,用于收集会话运行时的非张量元信息输出
  1. 对于没有数据依赖的张量,无需指定数据填充字典。
    import tensorflow as tf
    a = tf.constant(5.0, name='a')
    b = tf.constant(6.0, name='b')
    c = a * b
    with tf.Session() as sess:
    	print(sess.run(c))
    # 输出
    """
    30.0
    """
    
  2. 对于存在数据依赖的张量,需要指定数据填充字典。
    import tensorflow as tf
    x = tf.placeholder(tf.float32)
    y = tf.placeholder(tf.float32)
    z = x * y
    with tf.Session() as sess:
    	print(sess.run(z, feed_dict={x: 5.0, y: 2}))
    # 输出
    """
    10.0
    """
    

除了Session.run()方法求解张量之外,还可以通过Tensor.eval()以及Operation.run()
Tensor.eval()调用栈Operation.run()调用栈相比Session.run()方法,Tensor.eval() & Operation.run()都增加了输入参数session,它用来指定执行操作的会话实例。如果用户没有显式设置session参数,TF不会自动使用之前创建的会话实例。如果这时直接调用Tensor.eval()或Operation.run(),程序就会抛出找不到默认会话实例的错误。

错误示例:

import tensorflow as tf

x = tf.placeholder(tf.float32, name='x')
y = tf.Varibale(1.0, name='y')
z = x + y
sess = tf.Session()
# Operation.run()
tf.global_variables_initializer().run()
# Tensor.eval()
fetch = z.eval(feed_dict={x: 3.0})
# 输出
"""
ValueError: Cannot evaluate tensor using `eval()`: No default session is registered. Use `with sess.as_default()` or pass an explicit session to `eval(session=sess)`

ValueError: Cannot execute operation using `run()`: No default session is registered. Use `with sess.as_default():` or pass an explicit session to `run(session=sess)`
"""

上述两种方式都没有直接指定session参数,因此都会报错没有注册default session。正如错误信息所提出的,我们通过with语句或者直接指定session参数,便可以避免错误。

正确示例1

import tensorflow as tf

x = tf.placeholder(tf.float32, name='x')
y = tf.Varibale(1.0, name='y')
z = x + y

with tf.Session() as sess:
	# Operation.run()
	tf.global_variables_initializer().run()
	# Tensor.eval()
	fetch = z.eval(feed_dict={x: 3.0})
	print(fetch)
# 输出
"""
4.0
"""

with语句会隐式地调用新建的Session对象的__enter__()方法,将当前的会话实例注册为default session。因此,在with tf.Session() as sess: 语句块中,可以使用更简单的参数来调用Tensor.eval()Operation.run()方法。

正确示例2

import tensorflow as tf

x = tf.placeholder(tf.float32, name='x')
y = tf.Varibale(1.0, name='y')
z = x + y

sess = tf.Session()
# Operation.run()
tf.global_variables_initializer().run(session=sess)
# Tensor.eval()
fetch = z.eval(feed_dict={x: 3.0}, session=sess)
print(fetch)
# 输出
"""
4.0
"""

关闭会话

会话提供了TensorFlow数据流图的运行环境,它同时也拥有变量、队列和文件句柄等资源,当执行完计算任务之后,应该主动关闭会话,以便释放这些资源。用户一般可以通过一下两种方式关闭Session。

  1. 使用close()方法显示关闭会话:
    sess.close() # sess是tf.Session()实例
  2. 使用with 语句隐式关闭会话:
    with tf.Session() as sess:
    	sess.run()
    
    with语句结束后,Session.__exit__()方法被隐式调用,进而调用Session.close()方法关闭会话。

交互式会话:InteractiveSession

TF交互式会话为用户提供类似shell的交互式编程环境,它由InteractiveSession类实现。该类的构造方法不仅完成了交互式会话实例的创建,同时将该实例注册为默认会话,这是interactive session 和 session的重要区别。因此,如果用户使用交互式会话作为数据流图的运行环境,便可以不借助with上下文语句块,直接调用Tensor.eval()Operation.run()方法执行操作。

示例

import tensorflow as tf
a = tf.constant(5.0)
b = tf.constant(6.0)
c = a * b
sess = tf.InteractiveSession()
print(c.eval())
sess.close()
# 输出
"""
30.0
"""

InteractiveSession的意义

上面说明了InteractiveSession和Session的区别,但是不太好理解,为什么要用InteractiveSession?我觉得下面一段话非常明白地解释了InteractiveSession的意义。

在我们使用tf.InteractiveSession()来构建会话的时候,我们可以先构建一个session然后再定义操作(operation)。但是如果我们使用tf.Session()来构建会话,我们便需要在会话构建之前定义好全部的操作(operation)然后再构建会话。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dongz__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值