在gpu并行训练网络时,往往需要共享已创建的变量,tensorflow中为了使这些变量名和操作名唯一并且不重复,用了几个函数来应对这种情况。于是就有了tf.Variable()
, tf.get_variable()
, tf.Variable_scope()
, tf.name_scope()
这四个最常见的函数。下面来进行逐对比较和分析。
**
一、tf.Variable() 和 tf.get_variable()
**
首先,两者是用于在一个 scope(空间/域) 下创建或者获取一个变量的两种不同方式。
区别在于,tf.Variable()
在创建变量的时候,会自动检测准备创建的变量的变量名是否已经存在了,如果已经存在,则会创建一个名字不一样的变量。就像你在桌面创建了一个“新建文件夹”,再想创建一个文件夹,系统会自动帮你命名为“新建文件夹(1)”。tf.Variable()
也是同样的意思。若果已经存在一个叫 “var1” 的变量,你再想用tf.Variable()
创建一个叫 “var1” 的变量,是不允许的,tf.Variable()
会自动把你想创建的命名成 “var1_1”。代码实现见下。
import tensorflow as tf
with tf.name_scope( 'name1' ):
var_a = tf.Variable(name='var1', initial_value=[6], dtype=tf.float32)
var_b = tf.Variable(name='var1', initial_value=[6], dtype=tf.float32)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print( var_a.name, sess.run(var_a) )
print( var_b.name, sess.run(var_b) )
# 输出结果:
# var1: 0 [6.]
# var1_1: 0 [6.] 自动处理重名变量,避免冲突
而 tf.get_variable()
遇到重名变量要创建时,会检测该变量有没有被设置成共享变量,如果没有,则会报错。
也就是说 tf.Variable()
允许你创建相同名字的变量,但是吧,底层实现时会自动引入别名机制,实际上产生两个不同的变量。
tf.get_variable()
会首先去找有没有相同名字的,并且不受 name_scope
约束,进行全局搜索,如果这个变量已经存在,且reuse=Ture
,则获取该变量。如果不存在,则自动创建一个变量。
就创建变量这个问题,Google搞出了 tf.variable_scope()
函数。
二、tf.name_scope() 和 tf.variable_scope()
可以把 name_scope
理解为‘命名空间’,把 variable_scope
理解为‘变量作用域’
代码实现如下。
with tf.variable_scope('aa') as a_scope:
x = tf.get_variable('x', [2])
with tf.variable_scope('aa', reuse=True): #或with tf.variable_scope(a_scope, reuse=True):
x1 = tf.get_variabel('x') #不但拥有‘x’这个名字,还拥有2这个值。
总的来说,首先要先创建一个空间,name_scope
或者 variable_scope
, 然后你就可以用tf.get_variable()
和 tf.variable()
去创建得到变量了。 tf.name_scope()
主要用于管理graph里面的各个op(节点),每个name_scope
下面可以定义各种op或者子name_scope
,达到层次化管理目的,避免各个op之间命名冲突。tf.variable()
可以与 tf.name_scope()
相互嵌套配合使用,用于管理一个graph中变量的名字,避免变量命名冲突。tf.variable_scope()
允许在一个varibale_scope
下面共享变量。
另外,创建一个新的variable_scope
时默认 reuse
属性是 False
,只需要在使用的时候设置为True
就可以了。
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"
-end
参考资料:
1、http://www.cnblogs.com/Charles-Wan/p/6200446.html
2、https://www.zhihu.com/question/54513728/answer/177901159