本文共 9886 字,大约阅读时间需要 32 分钟。
作者:chen_h
微信号 & QQ:862251340 微信公众号:coderpai计划现将 tensorflow 中的 Python API 做一个学习,这样方便以后的学习。
class tf.Graph
解释:一个TensorFlow计算是由数据流图表示的。
一个数据流图包含一组操作的对象,它表示每一个计算单元,一组张量的表示,它表示数据之间流动的单元。
一个默认图,总是在一开始就通过tf.get_default_graph()
被创建好了。如果要向默认图中添加一个操作,那么只需要定义一个操作就行了,这个操作会自动被添加到默认图中。比如:
c = tf.constant(4.0)assert c.graph is tf.get_default_graph()
另外一种将操作添加到图中的方法是使用Graph.as_default()
函数,但是这个操作将覆盖当前生命周期的默认图。比如下面的代码,c
是在图g
中,但是第二个with
操作,覆盖了前面的图,所以cf
只在图gg
中。具体如下:
g = tf.Graph()with g.as_default(): # Define operations and tensors in 'g' c = tf.constant(2.) assert c.graph is g print('ok')with tf.Graph().as_default() as gg: cf = tf.constant(3.) assert cf.graph is g print('ok')# output ======================okTraceback (most recent call last): File "c.py", line 15, inassert cf.graph is gAssertionError
重要提醒:这个类不是线程安全的。所以得操作都应该从一个线程中被创建,或者提供外部同步。除非特别的是定制,不然所有的方法都是线程不安全的。
tf.Graph.__init__()
解释:创建一个新的,空的图。
tf.Graph.as_default()
解释:这个函数的作用是返回一个上下文管理的默认数据流图。
如果你想在同一个进程中使用多个图,那么你需要使用这个函数去创建图。为方便起见,如果你没有明确的创建图,那么所有的操作将会被添加到全局的默认图中。当然,你也可以使用with
操作去指定你需要将操作添加到哪个数据流图中。
默认图只存在于当前线程中。如果你创建了一个新的线程,并且想要在这个新的线程中使用默认图,那么你需要在这个线程中明确使用with g.as_default():
函数。
以下例子说明了上面问题:
# 1. Using Graph.as_default():g = tf.Graph()with g.as_default(): c = tf.constant(5.0) assert c.graph is g# 2. Constructing and making default:with tf.Graph().as_default() as g: c = tf.constant(5.0) assert c.graph is g
输出参数:
tf.Graph.as_graph_def(from_version = None, add_shapes = False)
解释:这个函数的作用是返回一个表示默认数据流图的序列 GraphDef
。
如果你想将这个序列图应用到别的图中,那么你需要使用函数 import_graph_def()
去使用。
注意,这个方法是线程安全的。
使用例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf with tf.Graph().as_default(): with tf.name_scope("input"): variables_node = tf.Variable(1.0, name="variables_node") with tf.name_scope("output"): output_node = tf.mul(variables_node, 2.0, name="output_node") with tf.Session() as sess: init = tf.global_variables_initializer() sess.run(init) tf.train.write_graph(sess.graph.as_graph_def(), './runs/', 'model.pbtxt', as_text = True) saver = tf.train.Saver() saver.save(sess, './runs/') print(sess.run(output_node))
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf import numpy as np with tf.Session() as sess: with tf.Graph().as_default(): graph_def = tf.GraphDef() graph_path = './runs/model.pbtxt' graph = tf.import_graph_def(graph_def, name="") print(sess.graph_def)
输入参数:
from_version
: (可选)如果这个值被设置了,那么只返回添加到这个序列图中的节点,因为它的版本号已经具有给定的值add_shapes
: 如果设置成 true
,则向每个节点添加一个_output_shapes
列表 attr
,其中包含每个节点的推断形状。输出参数:
异常:
值错误
:如果 graph_def
太大了,那么将报错。tf.Graph.finalize()
解释:这个函数的作用是锁住一张图,使得这张图只能读,不能写。
在调用 g.finalize()
之后,不能再向图 g
中添加任何操作。这个操作非常有用,当你在多个线程之间使用同一张图时,为了保证没有额外的操作添加到这个图中,你可以使用这个操作。比如,多线程读取队列文件QueueRunner
。
举个例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf G = tf.Graph()with G.as_default() as g: c = tf.constant(1.) assert c.graph is g print('c ok') G.finalize()with G.as_default() as gg: a = tf.constant(2.) assert a.graph is gg print('a ok')# output该操作将报错
tf.Graph.finalized()
解释:这个函数的作用是锁住一张图,使得这张图只能读,不能写。
举个例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf G = tf.Graph()with G.as_default() as g: c = tf.constant(1.) assert c.graph is g print('add c op') G.finalize()if G.finalized: print('已经锁住图')else: print('没有锁住图') with G.as_default() as gg: a = tf.constant(2.) assert a.graph is gg print('add a op')
tf.Graph.control_dependencies(control_inputs)
解释:这个函数的作用是返回一个明确依赖控制的上下文管理器。
我们需要在 control_inputs
中指明所有的控制依赖,并且使用 with
关键字来指明其在上下文管理器内的所有的操作。例如:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf with tf.Graph().as_default() as g: a = tf.constant(1.) b = tf.constant(2.) c = tf.constant(3.) with tf.Session() as sess: with g.control_dependencies([a,b,c]): # 'd' and 'e' will only run after 'a', 'b' and 'c' have executed. d = tf.mul(a, b) e = tf.add(d, a) print(sess.run(e))
control_dependencies()
可以进行多层嵌套调用。在这种情况下,新的操作将对所有活动上下文的 control_inputs
具有控制依赖性。
举个例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf with tf.Graph().as_default() as g: a = tf.constant(1.) b = tf.constant(2.) with tf.Session() as sess: with g.control_dependencies([a,b]): # Ops constructed here run after 'a' and 'b'. c = tf.constant(3.) d = tf.constant(4.) with g.control_dependencies([c, d]): # Ops constructed here run after 'a', 'b', 'c' and 'd'. e = tf.add(tf.add(a, b), tf.add(c, d)) print(sess.run(e))
你可以使用 None
,来清除依赖控制。
举个例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf with tf.Graph().as_default() as g: a = tf.constant(1.) b = tf.constant(2.) with tf.Session() as sess: with g.control_dependencies([a,b]): # Ops constructed here run after 'a' and 'b'. c = tf.constant(3.) d = tf.constant(4.) # delete a,b del a,b with g.control_dependencies(None): # Ops constructed here run normally, not waiting for either 'a' or 'b' with g.control_dependencies([c, d]): # Ops constructed here run after 'c' and 'd', also not waiting for either 'a' or 'b' a = tf.constant(1.) b = tf.constant(2.) e = tf.add(tf.add(a, b), tf.add(c, d)) print(sess.run(e))
注意:只有当实际操作节点在上下文控制器中时,依赖参数才起作用。比如下面的代码:
# WRONGdef my_func(pred, tensor): t = tf.matmul(tensor, tensor) with tf.control_dependencies([pred]): # The matmul op is created outside the context, so no control dependency will be added. return t# RIGHTdef my_func(pred, tensor): with tf.control_dependencies([pred]) # The matmul op is created in the context, so a control dependency will be added. return tf.matmul(tensor, tensor)
输入参数:
control_inputs
: 在运行下文中定义的操作之前,必须先执行或者计算一系列的 Operation
或者 Tensor
。当然,我们也可以将参数设置成 None
,从而去清除前面的控制依赖。输出参数:
异常:
类型错误
:如果 control_inputs
不是 Operation
或 Tensor
对象的列表。tf.Graph.device(device_name_or_function)
解释:设置一个上下文管理器,让指定的设备去使用这个管理器。
其中,device_name_or_function 参数
可以是设备名称字符串,设备函数或者 None
:
device()
进行了覆盖。Operation
对象到设备名的映射函数,并且每次一个新的 Operation
被创建时都会被调用。这个 Operation
将会被指派给这个带有返回名的设备。None
,那么将忽略上下文中所有的 device()
调用。有关设备名字字符串的有效语法信息,请参考文档。
举个例子:
with g.device('/gpu:0'): # All operations constructed in this context will be placed # on GPU 0. with g.device(None): # All operations constructed in this context will have no # assigned device.# Defines a function from `Operation` to device string.def matmul_on_gpu(n): if n.type == "MatMul": return "/gpu:0" else: return "/cpu:0"with g.device(matmul_on_gpu): # All operations of type "MatMul" constructed in this context # will be placed on GPU 0; all other operations will be placed # on CPU 0.
注意:设备名字作用域可能会被操作包装器或者其他的代码覆盖。比如,一个变量赋值操作v.assign()
必须被 tf.Variable
v
所托管(colocated),并且不兼容的设备将会被忽略。
输入参数:
device_name_or_function
: 一个在上下文中使用设备的名字或函数。输出参数:
tf.Graph.name_scope(name)
解释:为节点创建层次化的名称,并且返回一个上下文管理器。
在当前上下文管理器中,TensorFlow会利用一张图去维护一个命名空间栈,并且用 with name_scope(...)
来向命名空间栈中添加新的命名。
关于 name
参数的解释如下:
name
将会附加在所有的操作前面。如果这个 name
已经被使用过了,那么系统会通过调用 self.unique_name(name)
函数来使得这个name
是独一无二的。with g.name_scope(...) as scope:
。那么我们可以通过导入 scope
来获得这个现有的空间。None
或者空字符串,那么将会重置当前命名空间到最高层(空的)命名空间。举个例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf with tf.Graph().as_default() as g: c = tf.constant(5.0, name="c") #print(c.op) assert c.op.name == "c" c_1 = tf.constant(6., name="c") #print(c_1.op) assert c_1.op.name == "c_1" # Creates a scope called "nested" with g.name_scope("nested") as scope: nested_c = tf.constant(10., name="c") #print(nested_c.op) assert nested_c.op.name =="nested/c" # Creates a nested scope called "inner" with g.name_scope("inner"): nested_inner_c = tf.constant(20., name="c") assert nested_inner_c.op.name == "nested/inner/c" # Create a nested scope called "inner_1" with g.name_scope("inner"): nested_inner_12_c = tf.constant(30., name="c") assert nested_inner_12_c.op.name == "nested/inner_1/c" # Treats 'scope' as an absolute name scope, and swithes to the "nested/" scope. with g.name_scope(scope): nested_d = tf.constant(40., name="d") assert nested_d.op.name == "nested/d" with g.name_scope(""): e = tf.constant(50., name="e") assert e.op.name == "e"
空间本身的命名可以被 with g.name_scope(...) as scope:
所捕获,并且把命名空间的名字保存在变量 scope
中。这个变量可以用来对本空间内的操作进行命名。比如:
#!/usr/bin/env python# -*- coding: utf-8 -*-import tensorflow as tf with tf.Graph().as_default() as g: input = tf.constant(2., name="input") assert input.op.name == 'input' with g.name_scope("my_layer") as scope: weights = tf.constant(4., name="weights") biases = tf.constant(1., name="biases") affine = tf.mul(input, weights) + biases output = tf.nn.relu(affine, name=scope) print(output.op.name)
注意:此构造函数验证给定的名称,有效的作用域名称正则匹配如下:
[A-Za-z0-9.][A-Za-z0-9_.\\-/]* (for scopes at the root)[A-Za-z0-9_.\\-/]* (for other scopes)
输入参数:
name
: 一个命名空间的名字。输出参数:
name
设置为这个上下文管理器的名字。异常:
值异常
:如果 name
不是一个有效的命名,那么将抛出值异常。tf.Graph.add_to_collection(name, value)
解释:一个TensorFlow计算是由数据流图表示的。
tf.Graph.add_to_collection(name, value)
解释:一个TensorFlow计算是由数据流图表示的。
转载地址:http://hvdqb.baihongyu.com/