Tensorflow Session graph Op 的理解

Session

官方给出的定义:

TensorFlow uses the tf.Session class to represent a connection between the client program—typically a Python program, although a similar interface is available in other languages—and the C++ runtime. A tf.Session object provides access to devices in the local machine, and remote devices using the distributed TensorFlow runtime. It also caches information about your tf.Graph so that you can efficiently run the same computation multiple times.

Session提供了计算图和本地代码之间的关联和Operation执行、Tensor求值的环境。

import tensorflow as tf

# Build a graph.
a = tf.constant([1.0, 2.0])
b = tf.constant([3.0, 4.0])
c = a * b

# Launch the graph in a session.
sess = tf.Session()

# Evaluate the tensor 'c'.
print sess.run(c)
sess.close()

# result: [3., 8.]

一个Session可能会拥有一些资源,例如Variable或者Queue。当我们不再需要该session的时候,需要将这些资源进行释放。
有两种方式,
1. session.close()直接释放;
1. 使用with tf.Session()创建上下文,退出时自动释放;
例如:

import tensorflow as tf
with tf.Session() as sess:
    print sess.run(op)

Session类的构造函数如下所示:
tf.Session.init(target=”, graph=None, config=None)
如果在创建Session时没有指定Graph,则该Session会加载默认Graph。如果在一个进程中创建了多个Graph,则需要创建不同的Session来加载每个Graph,而每个Graph则可以加载在多个Session中进行计算。
执行Operation或者求值Tensor有两种方式:
1. 调用Session.run()方法: 该方法的定义如下所示,参数fetches便是一个或者多个Operation或者Tensor。
tf.Session.run(fetches, feed_dict=None)
2. 调用Operation.run()或则Tensor.eval()方法: 这两个方法都接收参数session,用于指定在哪个session中计算。但该参数是可选的,默认为None,此时表示在进程默认session中计算。
设置默认session的两种方式:
使用with:

import tensorflow as tf

# Build a graph.

with tf.Session() as sess:
   print sess.run(op)

在with语句中调用Session.as_default()方法:

import tensorflow as tf

# Build a graph.

sess = tf.Session()
with sess.as_default():
    sess.run(op)
sess.close()

所有的op都应该在session内被显式的run调用或者隐式的被其他op调用。

Graph

TF官方的定义:

What is a tf.Graph? A tf.Graph contains two relevant kinds of information:
1. Graph structure. The nodes and edges of the graph, indicating how individual operations are composed together, but not prescribing how they should be used. The graph structure is like assembly code: inspecting it can convey some useful information, but it does not contain all of the useful context that source code conveys.
1. Graph collections. TensorFlow provides a general mechanism for storing collections of metadata in a tf.Graph. The tf.add_to_collection function enables you to associate a list of objects with a key (where tf.GraphKeysdefines some of the standard keys), and tf.get_collection enables you to look up all objects associated with a key. Many parts of the TensorFlow library use this facility: for example, when you create a tf.Variable, it is added by default to collections representing “global variables” and “trainable variables”. When you later come to create a tf.train.Saver or tf.train.Optimizer, the variables in these collections are used as the default arguments.

Tensorflow中graph中包含了各种op的定义(节点)和tensor的流动(边)。
在Tensorflow中,始终存在一个默认的Graph。如果要将Operation添加到默认Graph中,只需要调用定义Operation的函数(例如tf.add())。如果我们需要定义多个Graph,则需要在with语句中调用Graph.as_default()方法将某个graph设置成默认Graph,于是with语句块中调用的Operation或Tensor将会添加到该Graph中。所有op默认添加到default graph中!
例如:

import tensorflow as tf
g1 = tf.Graph()
with g1.as_default():
    c1 = tf.constant([1.0])
with tf.Graph().as_default() as g2:
    c2 = tf.constant([2.0])

with tf.Session(graph=g1) as sess1:
    print sess1.run(c1)
with tf.Session(graph=g2) as sess2:
    print sess2.run(c2)

result:
[ 1.0 ]
[ 2.0 ]

如果将上面例子的sess1.run(c1)和sess2.run(c2)中的c1和c2交换一下位置,运行会报错。因为sess1加载的g1中没有c2这个Tensor,同样地,sess2加载的g2中也没有c1这个Tensor。

Operation

一个Operation就是Tensorflow Graph中的一个计算节点。其接收零个或者多个Tensor对象作为输入,然后产生零个或者多个Tensor对象作为输出。
例如c = tf.matmul(a, b)表示创建了一个类型为MatMul的Operation,该Operation接收Tensor a和Tensor b作为输入,而产生Tensor c作为输出。
当一个Graph加载到一个Session中,则可以调用Session.run(op)来执行op,或者调用op.run()来执行(op.run()是tf.get_default_session().run()的缩写)。

变量/常量的定义也是图中的operation(创建变量的operation),相当于在图中添加节点,如:
a = tf.constant([1.0, 2.0])

Tensor

Tensor表示的是Operation的输出结果。不过,Tensor只是一个符号句柄,其并没有保存Operation输出结果的值。通过调用Session.run(tensor)或者tensor.eval()方可获取该Tensor的值。
关于Tensorflow的图计算过程
我们通过下面的代码来看一下Tensorflow的图计算过程:

import tensorflow as tf
a = tf.constant(1)
b = tf.constant(2)
c = tf.constant(3)
d = tf.constant(4)
add1 = tf.add(a, b)
mul1 = tf.mul(b, c)
add2 = tf.add(c, d)
output = tf.add(add1, mul1)
with tf.Session() as sess:
    print sess.run(output)

result: 9

上面的代码构成的Graph如下图所示,当Session加载Graph的时候,Graph里面的计算节点都不会被触发执行.当运行sess.run(output)的时候,会沿着指定的Tensor output来进图路径往回触发相对应的节点进行计算。
当我们需要output的值时,触发Operation tf.add(add1, mul1)被执行,而该节点则需要Tensor add1和Tensor mul1的值,则往回触发Operation tf.add(a, b)和Operation tf.mul(b, c)。以此类推。
所以在计算Graph时,并不一定是Graph中的所有节点都被计算了,而是指定的计算节点或者该节点的输出结果被需要时。

几组试验:

exp1:

grapy_session_test2.py:
import tensorflow as tf
import  graph_session_test as test_sess
sess= tf.Session()
test_sess.build_graph(sess)
sess.close()
grapy_session_test.py:
import tensorflow as tf

x = tf.constant([[37.0, -23.0], [1.0, 4.0]], name='x')
w = tf.Variable(tf.random_uniform([2, 2]), name='y')
y = tf.matmul(x, w, name='matmul')
output = tf.nn.softmax(y, name='softmax')
init_op = w.initializer

def build_graph(sess):
    sess.run(init_op)
    print sess.run(x)

输出:
[[ 37. -23.]
[ 1. 4.]]
程序可以正常执行,试验说明session和graph无需定义在一起,session初始化后可以外部传入执行graph中的op(此时session关联default graph),只要graph中的op对session可见,就可以执行。

exp2:

grapy_session_test2.py:
import tensorflow as tf
import  graph_session_test as test_sess
sess= tf.Session()
test_sess.init(sess)
with sess:
    test_sess.build_graph2(sess)
test_sess.build_graph2(sess)
sess.close()
grapy_session_test.py:
import tensorflow as tf

x = tf.constant([[37.0, -23.0], [1.0, 4.0]], name='x')
w = tf.Variable(tf.random_uniform([2, 2]), name='y')
y = tf.matmul(x, w, name='matmul')
output = tf.nn.softmax(y, name='softmax')
init_op = w.initializer

def init(sess):
    sess.run(init_op)

def build_graph(sess):

    sess.run(init_op)
    print sess.run(x)

def build_graph2(sess):
    print sess.run(w)

程序出错:抛出:Attempted to use a closed Session异常。说明 with sess:在执行完成后会关闭session。
修改 with sess: 为 with sess.as_default():程序ok。
试验说明with sess.as_default():不会关闭session,可以临时调用sess中对op。

exp3:

grapy_session_test2.py:
import tensorflow as tf
import  graph_session_test as test_sess
sess= tf.Session()
test_sess.init(sess)
test_sess.outer_exec(sess)
sess.close()
grapy_session_test.py:
import tensorflow as tf
import graph_session_test3 as test3
x = tf.constant([[37.0, -23.0], [1.0, 4.0]], name='x')
w = tf.Variable(tf.random_uniform([2, 2]), name='y')
y = tf.matmul(x, w, name='matmul')
output = tf.nn.softmax(y, name='softmax')
init_op = w.initializer

def init(sess):
    sess.run(init_op)

def build_graph(sess):

    sess.run(init_op)
    print sess.run(x)

def build_graph2(sess):
    print sess.run(w)

def outer_exec(sess):
    test3.outer_executeion(sess,w)
graph_session_test3.py
def outer_executeion(sess,op):
    print sess.run(op)

输出:
[[ 0.6408478 0.01811564]
[ 0.93541765 0.69141591]]

试验说明是要op对session是可见对就可以执行,执行的op都是default graph中的op

exp4:

grapy_session_test2.py:
import tensorflow as tf
import  graph_session_test as test_sess
import graph_session_test3 as test_sess3
sess= tf.Session()
test_sess.init(sess)
test_sess3.get_tensor_by_name(sess)
sess.close()
grapy_session_test.py:
import tensorflow as tf
import graph_session_test3 as test3
x = tf.constant([[37.0, -23.0], [1.0, 4.0]], name='x')
w = tf.Variable(tf.random_uniform([2, 2]), name='w')
y = tf.matmul(x, w, name='matmul')
output = tf.nn.softmax(y, name='softmax')
init_op = w.initializer

def init(sess):
    sess.run(init_op)

def build_graph(sess):

    sess.run(init_op)
    print sess.run(x)

def build_graph2(sess):
    print sess.run(w)

def outer_exec(sess):
    test3.outer_executeion(sess,w)
graph_session_test3.py
import tensorflow as tf
def outer_executeion(sess,op):
    print sess.run(op)

def get_tensor_by_name(sess):
    tensor=tf.get_default_graph().get_tensor_by_name("w:0")
    print sess.run(tensor)

输出:
[[ 0.12869608 0.36519158]
[ 0.29446971 0.72513545]]

说明只要得到op或者tensor的name在任意位置可以执行,因为default graph是全局可见的。

exp5:

graph_session_test3.py中添加新的方法:
def get_op_by_name(sess):
    op=tf.get_default_graph().get_operation_by_name("w")
    print sess.run(op)
    tensor = tf.get_default_graph().get_tensor_by_name("w:0")
    print sess.run(tensor)

输出

None
[[ 0.28851759 0.47715592]
[ 0.06406116 0.17102659]]

graph_session_test.py中直接执行
test3.outer_executeion(sess,w)
输出:

[[ 0.28851759 0.47715592]
[ 0.06406116 0.17102659]]

说明
1. sess.run(w)和op=tf.get_default_graph().get_operation_by_name(“w”) ;print sess.run(op)运行结果不一样,前者除了执行op还返回相应的tensor::,后者仅仅执行op
2. graph中的所有定义都是op(如:tf.Variable()),如果使用get_tensorflow_by_name的形式获取tensor需要以:的形式执行。


参考资料:
1. https://www.tensorflow.org/programmers_guide/graphs
2. http://www.cnblogs.com/lienhua34/p/5998853.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值