tf中计算图 执行流程学习【转载】

时间:2021-07-05 15:25:50

转自:https://blog.csdn.net/dcrmg/article/details/79028003

https://blog.csdn.net/qian99/article/details/70500166

https://my.oschina.net/u/876354/blog/1930490

1.计算图

Tensorflow是基于图(Graph)的计算框架,图的节点由事先定义的运算(操作、Operation)构成,图的各个节点之间由张量(tensor)来链接,Tensorflow的计算过程就是张量(tensor)在节点之间从前到后的流动传输过程,

tf中计算图 执行流程学习【转载】

有向图中,节点通常代表数学运算,边表示节点之间的某种联系,它负责传输多维数据(Tensors)。

节点可以被分配到多个计算设备上,可以异步和并行地执行操作。因为是有向图,所以只有等到之前的入度节点们的计算状态完成后,其后的节点才能执行操作。推广到神经网络中,同一层之间的不同节点上的运算可以异步或并行的执行,但是前后层之间的执行还是要顺序执行,因为后一层的输入依赖于前一层的输出。

2.上下文环境(Session)

tf的计算必须要在一个Session的上下文中,Session提供了Operation执行和Tensor求值的环境。一个Session可能会拥有一些资源,例如Variable或者Queue。当我们不再需要该session的时候,需要调用sess.close()关闭会话(或使用Python上下文管理器自动关闭),将这些资源释放。

如果在创建Session时没有指定Graph,则该Session会加载默认Graph。如果在一个进程中创建了多个Graph,则需要创建不同的Session来加载每个Graph,而每个Graph则可以加载在多个Session中进行计算,Session与Session之间是相互独立的。

3.执行流程

Tensorflow的执行可以分为三个步骤:

    • 创建Tensor
    • 定义Operations(Operations输入Tensor,然后输出另一个Tensor)
    • 执行计算(也就是运行一个可计算的图)

最简单的,实现一维向量求和:

# -*- coding: utf-8 -*-)
import tensorflow as tf # 1. 创建两个张量(Tensor)
input1 = tf.constant([1.0, 1.0, 1.0, 1.0])
input2 = tf.constant([2.0, 2.0, 2.0, 2.0]) # 2. 定义操作(Operations)
output = tf.add(input1, input2) # 3. 执行计算
with tf.Session() as sess:
result = sess.run(output)
#result = output.eval()
print result
#sess.close() # 使用"with"语句,由python自动管理Session,不再需要显式调用close()

tf中是定义操作(Operations)与执行操作分开的工作模式。上例中定义了一个名称为output的求和操作(也就是图(Graph)上的一个节点),定义操作(Operation)的时候计算不会立即执行,直到在上下文的Session环境中调用run()或eval(),触发了Tensorflow执行计算图,从而获取output计算结点的结果

更一般的情况下,tf中输入数据可能是不确定或随时变化的,针对这种情况,tf提供了feed注入机制,可以临时替代图(Graph)中操作(Operations)的输入张量(tensor),即把这些数据定义为占位变量,直到执行计算图之前才具体给定数据,再把这些数据以feed_dict的形式作为参数提供给sess.run()调用。feed机制按这种思路,上例改为:

import tensorflow as tf

# 1. 创建两个占位变量,只定义数值类型和形状(shape),具体数值在计算图执行前给定
input1 = tf.placeholder(tf.float16,shape=[4])
input2 = tf.placeholder(tf.float16,shape=[4]) # 2. 定义操作(Operations)
output = tf.add(input1, input2) # 3. 执行计算
with tf.Session() as sess: input_1 = [1.0, 1.0, 1.0, 1.0]
input_2 = [2.0, 2.0, 2.0, 2.0] result = sess.run(output,feed_dict = {input1:input_1, input2:input_2})
print result

//placeholder用来占位,在run时feed。

4.Understand

tensorflow的编程和我以往接触的编程方式有很大差异。以前的编程,无论是编译类型的语言还是脚本语言,都是一步一步的,变量计算后,就会得到结果,比如c=a+b,当执行完语句后,就会得到c的值。但tensorflow不是,它首先要通过编程,构建一个计算图出来,然后启用一个会话来把数据作为输入,通过这个图规定的计算步骤计算,最后得到结果。
普通的命令式编程容易理解和调试,命令语句基本没有优化,按原有逻辑执行。tensorflow这种符号式编程有较多的嵌入和优化,不容易理解和调试,但运行速度会有一定的提升。

5.Tesor概念

A Tensor is a symbolic handle to one of the outputs of an Operation. It does not hold the values of that operation’s output, but instead provides a means of computing those values in a TensorFlow tf.Session.

This class has two primary purposes:
A Tensor can be passed as an input to another Operation. This builds a dataflow connection between operations, which enables TensorFlow to execute an entire Graph that represents a large, multi-step computation.
After the graph has been launched in a session, the value of the Tensor can be computed by passing it to tf.Session.run. t.eval() is a shortcut for calling tf.get_default_session().run(t).

Tensor是一个代表计算操作的句柄,它不保存数据,只是提供一个计算数据的方法。使用Tensor主要有两个目的,一个是Tensor可以把不同的操作连接起来,从而去构建一个计算图,支持Tensorflow去进行大规模多步的计算,另一个是当Tensor被一个会话Session启用的时候,就可以计算出该操作对应产出的数据。

6.基础架构

tf中计算图 执行流程学习【转载】

计算图是TensorFlow的核心概念,使用图(Graph)来表示计算任务,由节点和边组成。TensorFlow由前端负责构建计算图,后端负责执行计算图。
为了执行图的计算,图必须在会话(Session)里面启动,会话将图的操作分发到CPU、GPU等设备上执行。

TensorFlow Python库已经有一个默认图 (default graph),如果没有创建新的计算图,则默认情况下是在这个default graph里面创建节点和边。
在图里面添加节点非常方便。例如现在要创建这样的计算图,两个张量相加,如下图:

tf中计算图 执行流程学习【转载】

import tensorflow as tf
a=tf.constant([1.0,2.0], name='a')
b=tf.constant([3.0,4.0], name='b')
result = tf.add(a,b)

现在默认图就有了三个节点,两个constant(),和一个add()。
为了真正使两个张量相加并得到结果,就必须在会话里面启动这个图。

要启动计算图,首先要创建一个Session对象。
使用tf.Session()创建会话,调用run()函数执行计算图。如果没有传入任何创建参数,会话构造器将启动默认图。如果要指定某个计算图,则传入计算图参数(如g1),则创建会话方式为tf.Session(graph=g1)创建会话(Session)主要有以下三种方式:

(1)创建一个会话:

#启动默认图
sess=tf.Session()
result_value = sess.run(result)
print(result_value)
# ==> [4.0 6.0] # 任务完成, 关闭会话.
sess.close()

(2)创建一个会话:

Session在使用完后需要关闭以释放资源,除了显式调用close外,也可以使用“with”代码块 来自动完成关闭动作。代码如下:

with tf.Session() as sess:
result_value = sess.run(result)
print(result_value)
# ==> [4.0 6.0]

(3)创建一个默认的会话

sess=tf.Session()
with sess.as_default():
result_value = result.eval()
print(result_value)

如果没有创建会话直接对tensor进行eval(),

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)`

(4)创建一个交互式会话

在交互式环境下(例如IPython),使用设置默认会话的方式来获取张量的取值更加方便,TensorFlow提供了一种在交互式环境下直接构建默认会话的函数:tf.InteractiveSession,该函数会自动将生成的会话注册为默认会话,使用 tf.Tensor.eval()代替 Session.run(),代码如下:

sess= tf.InteractiveSession()
result_value = result.eval()
print(result_value)
sess.close()

7、构建多个计算图

在TensorFlow中可以构建多个计算图,计算图之间的张量和运算是不会共享的,通过这种方式,可以在同个项目中构建多个网络模型,而相互之间不会受影响。
使用tf.Graph()函数构建图,构建多个计算图的方式如下:

# 构建计算图g1
g1=tf.Graph()
with g1.as_default():
# 在计算图g1中定义变量'v',并设置初始值为0。
v=tf.get_variable('v',initializer=tf.zeros_initializer()(shape = [1])) # 构建计算图g2
g2=tf.Graph()
with g2.as_default():
# 在计算图g2中定义变量'v',并设置初始值微1。
v=tf.get_variable('v',initializer=tf.ones_initializer()(shape = [1])) # 在计算图g1中读取变量'v'的取值
with tf.Session(graph=g1) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope('',reuse=True):
print(sess.run(tf.get_variable('v')))
# 输出结果[0.] # 在计算图g2中读取变量'v'的取值
with tf.Session(graph=g2) as sess:
tf.global_variables_initializer().run()
with tf.variable_scope('',reuse=True):
print(sess.run(tf.get_variable('v')))
# 输出结果[1.]。