tf.Variable与tf.get_variable()
1.使用tf.Variable时,如果检测到命名冲突,系统会自己处理。使用tf.get_variable()时,系统不会处理冲突,而会报错
import tensorflow as tf
w_1 = tf.Variable(3,name="w_1")
w_2 = tf.Variable(1,name="w_1")
print w_1.name
print w_2.name
#输出
#w_1:0
#w_1_1:0
import tensorflow as tf
w_1 = tf.get_variable(name="w_1",initializer=1)
w_2 = tf.get_variable(name="w_1",initializer=2)
#错误信息
#ValueError: Variable w_1 already exists, disallowed. Did
#you mean to set reuse=True in VarScope?
2.基于这两个函数的特性,当我们需要共享变量的时候,需要使用tf.get_variable()。在其他情况下,这两个的用法是一样的
import tensorflow as tf
with tf.variable_scope("scope1"):
w1 = tf.get_variable("w1", shape=[])
w2 = tf.Variable(0.0, name="w2")
with tf.variable_scope("scope1", reuse=True):
w1_p = tf.get_variable("w1", shape=[])
w2_p = tf.Variable(1.0, name="w2")
print(w1 is w1_p, w2 is w2_p)
#输出
#True False
总结:由于tf.Variable() 每次都在创建新对象,所有reuse=True 和它并没有什么关系。对于get_variable(),来说,如果已经创建的变量对象,就把那个对象返回,如果没有创建变量对象的话,就创建一个新的。
tf.name_scope()和tf.variable_scope()
TF中有两种作用域类型:命名域 (name scope),通过tf.name_scope 或 tf.op_scope创建;变量域 (variable scope),通过tf.variable_scope 或 tf.variable_op_scope创建;这两种作用域,对于使用tf.Variable()方式创建的变量,具有相同的效果,都会在变量名称前面,加上域名称。对于通过tf.get_variable()方式创建的变量,只有variable scope名称会加到变量名称前面,而name scope不会作为前缀。
tf.variable_scope有一个参数reuse默认None,当reuse为None或False时,表示在该作用域下tf.get_variable函数只能创建变量,如果创建两个相同名字的变量就会报错
将reuse参数设置为True时,作用域可以共享变量,两个变量相等
with tf.variable_scope("foo",reuse=True):
v1 = tf.get_variable("v",[1])
v2 = tf.get_variable("v",[1])
print(v1.name,v2.name,v1 == v2)
#foo/v:0 foo/v:0 True
总结:
1、name_scope不会作为tf.get_variable变量的前缀,但是会作为tf.Variable的前缀。
2、在variable_scope的作用域下,tf.get_variable()和tf.Variable()都加了scope_name前缀。因此,在tf.variable_scope的作用域下,通过get_variable()可以使用已经创建的变量,实现了变量的共享,即可以通过get_variable()在tf.variable_scope设定的作用域范围内进行变量共享。
3、在重复使用的时候, 一定要在代码中强调 scope.reuse_variables()