名称范围和张量streamvariables范围有什么区别?
这些function有什么区别?
tf.variable_op_scope(values, name, default_name, initializer=None)
返回一个用于定义创buildvariables的op的上下文pipe理器。 此上下文pipe理器validation给定的值来自同一个图,确保该图是默认图,并推送一个名称范围和一个variables范围。
tf.op_scope(values, name, default_name=None)
返回定义Python操作时使用的上下文pipe理器。 这个上下文pipe理器validation给定的值是来自同一个图,确保该图是默认图,并推送一个名称范围。
tf.name_scope(name)
使用默认graphics封装
Graph.name_scope()
。 有关更多详细信息,请参阅Graph.name_scope()
。
tf.variable_scope(name_or_scope, reuse=None, initializer=None)
返回variables作用域的上下文。 可变范围允许创build新variables并共享已创build的variables,同时提供检查而不会意外创build或共享。 有关详细信息,请参阅variables范围如何,这里我们只提供几个基本示例。
我们先简单介绍一下variables共享。 这是TensorFlow中的一种机制,它允许共享代码不同部分中访问的variables,而无需将引用传递给variables。 tf.get_variable
方法可以和variables名作为参数一起使用,用这样的名字创build一个新的variables或者检索之前创build的variables。 这与使用tf.Variable
构造函数不同,后者将在每次调用时创build一个新variables(如果已经存在具有该名称的variables,则可能会为variables名添加后缀)。 就variables共享机制而言,引入了一个单独的范围(variables范围)。
结果,我们最终得到两种不同types的范围:
- 名称范围 ,使用
tf.name_scope
创build - variables作用域 ,使用
tf.variable_scope
创build
两个作用域对所有操作以及使用tf.Variable
创build的variables都具有相同的效果,即范围将作为操作或variables名称的前缀添加。
但是,名称作用域被tf.get_variable
忽略。 我们可以看到,在下面的例子中:
with tf.name_scope("my_scope"): v1 = tf.get_variable("var1", [1], dtype=tf.float32) v2 = tf.Variable(1, name="var2", dtype=tf.float32) a = tf.add(v1, v2) print(v1.name) # var1:0 print(v2.name) # my_scope/var2:0 print(a.name) # my_scope/Add:0
在一个作用域中放置一个使用tf.get_variable
访问的variables的唯一方法是使用一个variables作用域,如下例所示:
with tf.variable_scope("my_scope"): v1 = tf.get_variable("var1", [1], dtype=tf.float32) v2 = tf.Variable(1, name="var2", dtype=tf.float32) a = tf.add(v1, v2) print(v1.name) # my_scope/var1:0 print(v2.name) # my_scope/var2:0 print(a.name) # my_scope/Add:0
这使我们可以轻松地在程序的不同部分共享variables,甚至在不同的名称范围内:
with tf.name_scope("foo"): with tf.variable_scope("var_scope"): v = tf.get_variable("var", [1]) with tf.name_scope("bar"): with tf.variable_scope("var_scope", reuse=True): v1 = tf.get_variable("var", [1]) assert v1 == v print(v.name) # var_scope/var:0 print(v1.name) # var_scope/var:0
更新:op_scope / variable_op_scope已弃用!
从版本r0.11开始, op_scope
和variable_op_scope
都被弃用 ,并被name_scope
和variable_scope
所取代。
命名空间是一种以层次方式组织variables和运算符名称的方法(例如“scopeA / scopeB / scopeC / op1”)
-
tf.name_scope
在默认图中为运算符创build名称空间。 -
tf.variable_scope
为默认图中的variables和运算符创build名称空间。 -
tf.op_scope
与tf.op_scope
相同,但是用于创build指定variables的graphics。 -
tf.variable_op_scope
与tf.variable_op_scope
相同,但是用于创build指定variables的graphics。
链接到上面的来源有助于消除这个文档问题。
这个例子显示了所有types的作用域都为variables和运算符定义了命名空间,但有以下不同:
- 由
tf.variable_op_scope
或tf.variable_scope
定义的作用域与tf.get_variable
兼容(它忽略了另外两个作用域) -
tf.op_scope
和tf.variable_op_scope
只是从指定的variables列表中select一个graphics来创build一个范围。 除了它们的行为相当于tf.name_scope
和tf.variable_scope
-
tf.variable_scope
和variable_op_scope
添加指定或默认的初始值设定项。
现在已经废弃了variable_op_scope和op_scope ,根本不应该使用。
关于另外两个问题,在我尝试通过创build一个简单的例子来想象所有的东西之前,我也有理解variable_scope和name_scope之间的区别(他们看起来差不多)
import tensorflow as tf def scoping(fn, scope1, scope2, vals): with fn(scope1): a = tf.Variable(vals[0], name='a') b = tf.get_variable('b', initializer=vals[1]) c = tf.constant(vals[2], name='c') with fn(scope2): d = tf.add(a * b, c, name='res') print '\n '.join([scope1, a.name, b.name, c.name, d.name]), '\n' return d d1 = scoping(tf.variable_scope, 'scope_vars', 'res', [1, 2, 3]) d2 = scoping(tf.name_scope, 'scope_name', 'res', [1, 2, 3]) with tf.Session() as sess: writer = tf.summary.FileWriter('logs', sess.graph) sess.run(tf.global_variables_initializer()) print sess.run([d1, d2]) writer.close()
这里我创build了一个函数来创build一些variables和常量,并将它们分组在范围中(取决于我提供的types)。 在这个函数中,我也打印所有variables的名字。 之后,我执行graphics来获取结果值的值,并保存事件文件在TensorBoard中进行调查。 如果你运行这个,你会得到以下结果:
scope_vars scope_vars/a:0 scope_vars/b:0 scope_vars/c:0 scope_vars/res/res:0 scope_name scope_name/a:0 b:0 scope_name/c:0 scope_name/res/res:0
如果您打开TensorBoard,则会看到类似的模式(因为您看到b
在scope_name
矩形之外):
这给你答案 :
现在你看到tf.variable_scope()
为所有variables的名称(不pipe你如何创build它们),操作tf.variable_scope()
, tf.variable_scope()
添加一个前缀。 另一方面, tf.name_scope()
忽略使用tf.get_variable()
创build的variables,因为它假定您知道哪个variables以及您想要在哪个范围内使用。
关于共享variables的一个很好的文档告诉你
tf.variable_scope()
:pipe理传递给tf.get_variable()
名称的名称空间。
相同的文档提供了更多的细节,variables作用域如何工作以及何时有用。
至于API r0.11, op_scope
和variable_op_scope
都被弃用 。 name_scope
和variable_scope
可以嵌套:
with tf.name_scope('ns'): with tf.variable_scope('vs'): v1 = tf.get_variable("v1",[1.0]) #v1.name = 'vs/v1:0' v2 = tf.Variable([2.0],name = 'v2') #v2.name= 'ns/vs/v2:0' v3 = v1 + v2 #v3.name = 'ns/vs/add:0'
你可以把它们看作两组: variable_op_scope
和op_scope
以一组variables作为input,并且被devise来创build操作。 区别在于它们如何影响使用tf.get_variable
创buildvariables:
def mysum(a,b,name=None): with tf.op_scope([a,b],name,"mysum") as scope: v = tf.get_variable("v", 1) v2 = tf.Variable([0], name="v2") assert v.name == "v:0", v.name assert v2.name == "mysum/v2:0", v2.name return tf.add(a,b) def mysum2(a,b,name=None): with tf.variable_op_scope([a,b],name,"mysum2") as scope: v = tf.get_variable("v", 1) v2 = tf.Variable([0], name="v2") assert v.name == "mysum2/v:0", v.name assert v2.name == "mysum2/v2:0", v2.name return tf.add(a,b) with tf.Graph().as_default(): op = mysum(tf.Variable(1), tf.Variable(2)) op2 = mysum2(tf.Variable(1), tf.Variable(2)) assert op.name == 'mysum/Add:0', op.name assert op2.name == 'mysum2/Add:0', op2.name
注意两个例子中variablesv
的名字。
同样的tf.name_scope
和tf.variable_scope
:
with tf.Graph().as_default(): with tf.name_scope("name_scope") as scope: v = tf.get_variable("v", [1]) op = tf.add(v, v) v2 = tf.Variable([0], name="v2") assert v.name == "v:0", v.name assert op.name == "name_scope/Add:0", op.name assert v2.name == "name_scope/v2:0", v2.name with tf.Graph().as_default(): with tf.variable_scope("name_scope") as scope: v = tf.get_variable("v", [1]) op = tf.add(v, v) v2 = tf.Variable([0], name="v2") assert v.name == "name_scope/v:0", v.name assert op.name == "name_scope/Add:0", op.name assert v2.name == "name_scope/v2:0", v2.name
你可以在教程中阅读关于variables作用域的更多信息。 Stack Overflow 之前也有类似的问题。
从tensorflow文档的这个页面的最后一节: tf.variable_scope()
中ops的tf.variable_scope()
当我们
with tf.variable_scope("name")
,这隐式地打开了一个tf.name_scope("name")
。 例如:
with tf.variable_scope("foo"): x = 1.0 + tf.get_variable("v", [1]) assert x.op.name == "foo/add"
除了variables作用域之外,可以打开名称作用域,然后它们将只影响作用域的名称,而不影响variables的名称。
with tf.variable_scope("foo"): with tf.name_scope("bar"): v = tf.get_variable("v", [1]) x = 1.0 + v assert v.name == "foo/v:0" assert x.op.name == "foo/bar/add"
使用捕获的对象而不是string打开variables作用域时,我们不会更改ops的当前名称范围。
- 如何将张量转换为TensorFlow中的一个numpy数组?
- 如何*实际*在TensorFlow中读取CSV数据?
- TensorFlow中tf.app.flags的用途是什么?
- 有没有关于如何生成保存经过训练的Tensorflow图的protobuf文件的例子
- 如何防止张量stream分配整个GPU内存?
- 我可以使用TensorFlow来测量单个操作的执行时间吗?
- 如何构build和使用Google TensorFlow C ++ api
- Tensorflow:ImportError:libcusolver.so.8.0:无法打开共享对象文件:没有这样的文件或目录
- 如何使用张量stream中的自定义python函数预取数据