在TensoFlow中有两个作用域(Scope),一个时name_scope ,另一个是variable_scope。variable_scope主要给variable_name
加前缀,也可以给op_name
加前缀;name_scope给op_name
加前缀。
variable_scope
通过所给的名字创建或返回一个变量,并为变量指定命名空间,在Tensorflow 1.0版本示例代码如下:
var=tf.compat.v1.get_variable(name,shape,dtype,initializer) 通过所给的的名字name创建或返回一个变量
tf.compat.v1.variable_scope(<scope_name>) 为变量指定命名空间
当tf.compat.v1.get_variable_scope().resuse==False
时,variable_scope作用域只能用于创建新变量,示例代码如下:
with tf.compat.v1.variable_scope("foo"):
var1=tf.compat.v1.get_variable("var",[1])
var2=tf.compat.v1.get_variable("var",[1])
assert var1.name=="foo/var:0"
导致上述程序的错误原因是:
ValueError: Variable foo/var already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?
变量foo/var已经存在了,但tf.compat.v1.get_variable_scope().resuse默认为False,所以不能重用。
当tf.compat.v1.get_variable_scope().resuse==True
时,作用域可以共享变量。示例代码如下:
with tf.compat.v1.variable_scope("foo") as scope:
var1=tf.compat.v1.get_variable("var4",[1])
with tf.compat.v1.variable_scope("foo",reuse=True):
var2=tf.compat.v1.get_variable("var4",[1])
assert var1==var2
如果在开启的一个变量作用域里使用之前预先定义的一个作用域,则会跳过当前变量的作用域,保持预先存在的作用域不变,示例如下:
with tf.compat.v1.variable_scope("foo") as foo_scope:
assert foo_scope.name=="foo"
with tf.compat.v1.variable_scope("wel") as wel_scope:
with tf.compat.v1.variable_scope("we0") as we0_scope:
assert we0_scope.name=="wel/we0"
with tf.compat.v1.variable_scope(foo_scope) as foo_scope2:
assert foo_scope2.name=="foo"
foo_scope2.name
变量作用域可以默认携带一个初始化器,在这个作用域中的子作用域或变量
都可以继承或者重写
父作用域初始化中的值,示例代码如下:
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
with tf.compat.v1.variable_scope("foo",initializer=tf.compat.v1.constant_initializer(0.4)) :
wel_1=tf.compat.v1.get_variable("wel",[1])
with tf.compat.v1.Session() as sess:
sess.run(tf.compat.v1.global_variables_initializer())
assert wel_1.eval()==0.4
wel_2=tf.compat.v1.get_variable("wel2",[1], initializer=tf.constant_initializer(0.3))
with tf.compat.v1.Session() as sess:
sess.run(tf.compat.v1.global_variables_initializer())
assert wel_2.eval()==0.3
with tf.compat.v1.variable_scope("two"):
wel_1=tf.compat.v1.get_variable("wel",[1])
with tf.compat.v1.Session() as sess:
sess.run(tf.compat.v1.global_variables_initializer())
assert wel_1.eval()==0.4
with tf.compat.v1.variable_scope("three",initializer=tf.constant_initializer(0.2)):
wel_1=tf.compat.v1.get_variable("wel",[1])
with tf.compat.v1.Session() as sess:
sess.run(tf.compat.v1.global_variables_initializer())
assert wel_1.eval(session = sess)==0.2
把最后一个断言值调整错误,验证程序执行情况:
对于op_name,在variable_scope作用域下的操作,也会被加上前缀,示例代码如下:
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
with tf.compat.v1.variable_scope("four"):
wel_x=1.0+tf.compat.v1.get_variable("wel",[1])
assert wel_x.op.name=="four/add"
name_scope
TensorFlow中节点数非常多,在可视化的过程中很难全部展示出来,常 name_scope
作为变量划分范围,在可视化中,这表示计算图中的一个层级
。name_scope会影响op_name,但 不会影响get_variable()
创建的变量,而会影响通过Variable()
创建的变量,示例代码如下:
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
with tf.compat.v1.variable_scope("five"):
with tf.compat.v1.name_scope("one"):
wel_x=tf.compat.v1.get_variable("wel",[1])
var1=tf.Variable(tf.zeros([1]),name='var1')
ops=1.0+ var1
assert wel_x.name=="five/wel:0"
assert var1.name=="five/one/var1:0"
assert ops.op.name=="five/one/add"