tf.Variable(),tf.get_vriable(),tf.name_scope(),tf.variable_scope()区别与联系
tf.Variable()与tf.get_variable()区别与联系
tensorflow中有两个生成变量的操作:
- tf.Variable()
- tf.get_variable()
这两个方法都可以生成变量,但是用法上还是有点区别:
函数 | 必选参数 | 是否可以获取已有变量 | 变量名冲突处理 |
---|---|---|---|
tf.Variable() |
value | 不可以 | 自动处理 |
tf.get_variable() |
name+shape/initializer(能够给定形状信息即可) | 可以 | 报错 |
tf.Variable()遇到重名变量时,会自动处理
import tensorflow as tf
w_1 = tf.Variable(3,name="var")
w_2 = tf.Variable(1,name="var")
print(w_1.name) # var:0
print(w_2.name) # var_1:0
另外注意reuse的使用方法,variable_scope也存在命名重复的问题
>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): # 这里改成False,即可看到系统询问是否要改为True。
w1_p = tf.get_variable("w1", shape=[])
w2_p = tf.Variable(0.0, name="w2")
print(w2.name, w2_p.name) # scope1/w2:0 scope1_1/w2:0
print(w1.name, w1_p.name) # scope1/w1:0 scope1/w1:0
print(w1 is w1_p, w2 is w2_p) # True False
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter("logs", sess.graph) # 文件写在该.py文件同级
可以看出,同一个tf.variable(),被系统处理成两个scope,并且自动处理命名问题。且
w2
被复用。
tf.name_scope()与tf.varialbe_scope()区别与联系
case1:无scope,仅仅用两种方法生成变量
import tensorflow as tf
# 无上下文管理器tf.get_variable(),tf.Variable() 上下文管理器:含有__enter__,__exit__方法的class
v1 = tf.get_variable("var1", [1])
v2 = tf.Variable(1, name='var2')
print(v1.name) # var1:0
print(v2.name) # var2:0
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter("logs", sess.graph) # 文件写在该.py文件同级logs文件夹下,用 tensorboard --logdir=. 即可
结果就是单纯的生成两个变量
以下两种生成变量的内部操作,均为典型操作,var1
为无初值,var2
为有初值结论:无scope包裹的两种方式,仅仅是单纯的生成变量,名字由name参数给定
case2:两种生成变量的方法用tf.varialbe_scope()包裹
import tensorflow as tf
# 上下文管理器:tf.variable_scope 上下文管理器:含有__enter__,__exit__方法的class
with tf.variable_scope("foo"):
v1 = tf.get_variable("var1", [1])
v2 = tf.Variable(1, name='var2')
print(v1.name) # foo/var1:0
print(v2.name) # foo/var2:0
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter("logs", sess.graph) # 文件写在该.py文件同级logs文件夹下,用 tensorboard --logdir=. 即可
发现,如果使用tf.variable_scope()
这个上下文管理器,则两种方式生成的变量都会被包含在foo
这个变量空间中。
并且很可能比case1仅仅多了一个foo
这个变量空间。
打开看以后,发现确实如此——使用tf.variable_scope()
这个上下文管理器,仅仅比没有上下文管理器时多了个包裹两个变量的变量空间。结论:两种生成变量的方法用tf.varialbe_scope()包裹,两变量在图中被该scope包裹(变量名随之有了该scope名的前缀)
case3:两种生成变量的方法用tf.name_scope()包裹
import tensorflow as tf
# 上下文管理器:tf.name_scope 上下文管理器:含有__enter__,__exit__方法的class
with tf.name_scope("foo"):
v1 = tf.get_variable("var1", [1])
v2 = tf.Variable(1, name='var2')
print(v1.name) # var1:0
print(v2.name) # foo/var2:0
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter("logs", sess.graph) # 文件写在该.py文件同级logs文件夹下,用 tensorboard --logdir=. 即可
结论:两种生成变量的方法用tf.name_scope()包裹时,用tf.Variable()生成的变量同case2,但用tf.get_variable()生成的变量却独立出来,与该scope没关系