摘要
tf.name_scope
和tf.variable_scope
在Tensorflow
里都是关于变量的管理的操作, 字面理解就是指定了变量的不同作用域:命名域(name_scope)和变量域(variable_scope).两者对应的创建/调用变量的函数分别是tf.variable()
和tf.get_variable()
,而关于这两种使用的差别也决定了tf.name_scope()
和tf.variable_scope()
的作用不同.
主要作用有:
- 共享变量:是
tf.variable_scope
与tf.get_variable()
结合使用特有的. - 方便变量命令管理:这两者都可以,但两者有区别.
- tensorboard画流程图时为了可视化封装变量:这两者都可以
具体描述见下面:
tf.name_scope() 与 tf.variable()
tf.name_scope 主要结合 tf.Variable() 来使用,方便参数命名管理。
在tf.Variable
里每次都会检查变量名称是否重复,如果重复会进行处理创建一个新的变量,故也不实现共享变量功能,实现的是变量名称自动修改.
同时在 tf.name_scope下时,tf.get_variable()创建的变量名不受 name_scope 的影响,而且在未指定共享变量时,如果重名会报错.
import tensorflow as tf
with tf.name_scope('name_scope_x'):
var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32)
var3 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
var4 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(var1.name, sess.run(var1))
print(var3.name, sess.run(var3))
print(var4.name, sess.run(var4))
# 输出结果:
# var1:0 [-0.30036557] 可以看到前面不含有指定的'name_scope_x'
# name_scope_x/var2:0 [ 2.]
# name_scope_x/var2_1:0 [ 2.] 可以看到变量名自行变成了'var2_1',避免了和'var2'冲突
tf.variable_scope 与 tf.get_variable()
tf.variable_scope()
主要结合tf.get_variable()
来使用,通过resuse
参数的设置实现变量共享。
import tensorflow as tf
with tf.variable_scope('v_scope') as scope1:
Weights1 = tf.get_variable('Weights', shape=[2,3])
bias1 = tf.get_variable('bias', shape=[3])
# 下面来共享上面已经定义好的变量
# note: 在下面的 scope 中的变量必须已经定义过了,才能设置 reuse=True,否则会报错
with tf.variable_scope('v_scope', reuse=True) as scope2:
Weights2 = tf.get_variable('Weights')
print(Weights1.name)
print(Weights2.name)
# 可以看到这两个引用名称指向的是同一个内存对象
#v_scope/Weights:0
#v_scope/Weights:0
也可以结合 tf.Variable() 一块使用,但它并不能实现变量共享:
import tensorflow as tf
# 注意, bias1 的定义方式
with tf.variable_scope('v_scope') as scope1:
Weights1 = tf.get_variable('Weights', shape=[2,3])
bias1 = tf.Variable([0.52], name='bias')
print Weights1.name
print bias1.name
# 下面来共享上面已经定义好的变量
# note: 在下面的 scope 中的get_variable()变量必须已经定义过了,才能设置 reuse=True,否则会报错
with tf.variable_scope('v_scope', reuse=True) as scope2:
Weights2 = tf.get_variable('Weights')
bias2 = tf.get_variable('bias', [1]) # ‘bias
print Weights2.name
print bias2.name
# 这样子的话就会报错
# Variable v_scope/bias does not exist, or was not created with tf.get_variable()
后记
最近在用修改一个Tensorflow模型解决了一个关于变量初始化问题,也记载在这里吧:
我想实现在一个子函数里用tensorlow的变量随机生成数据然后传给主函数,然而在主函数里会话运行之前也初始化了,但还是报未初始化的错误…后来发现写的姿势不对,详情见下面代码:
import tensorflow as tf
def function():
with tf.variable_scope('test'):
v = tf.get_variable("v",[1],initializer=tf.constant_initializer(1.0))
return v
if __name__ == '__main__':
with tf.Session() as sess:
v = function()
tf.global_variables_initializer().run()
print(sess.run(v))
#print(sess.run(function())) 直接run这个函数返回值并不能完成初始化操作...这句话报错让我纠结一下午