tf.name_scope与tf.variable_scope

1.scope(作用域)

  在TensorFlow中有两个作用域 (scope),一个是variable_scope,另一个是name_scope。它们究竟有什么区别呢?简而言之,variable_scope主要是给variable_name加前缀,也可以给op_name加前缀;name_scope是给op_name加前缀。下面我们就来分别介绍。

2. variable_scope示例

2.1 reuse=False/True

variable_scope变量作用域机制在TensorFlow中主要由两部分组成:

v = tf.get_variable(name, shape, dtype, initializer) # 通过所给的名字创建或是返回一个变量
tf.variable_scope(<scope_name>) # 为变量指定命名空间

当tf.get_variable_scope().reuse == False时,variable_scope作用域只能用来创建新变量:

with tf.variable_scope("foo"):
    v = tf.get_variable("v", [1])
    v2 = tf.get_variable("v", [1])
assert v.name == "foo/v:0"

note:
    上述程序会抛出V alueError错误,因为v这个变量已经被定义过了,但tf.get_variable_scope().reuse默认为False,所以不能重用。

当tf.get_variable_scope().reuse == True时,作用域可以共享变量:

with tf.variable_scope("foo") as scope:
    v = tf.get_variable("v", [1])
with tf.variable_scope("foo", reuse=True):
    #也可以写成:
    #scope.reuse_variables()
    v1 = tf.get_variable("v", [1])
assert v1 == v

2.2 获取变量作用域

可以直接通过tf.variable_scope()来获取变量作用域:

with tf.variable_scope("foo") as foo_scope:    
	v = tf.get_variable("v", [1])
with tf.variable_scope(foo_scope)    
	w = tf.get_variable("w", [1])

如果在开启的一个变量作用域里使用之前预先定义的一个作用域,则会跳过当前变量的作用域,保持预先存在的作用域不变。

with tf.variable_scope("foo") as foo_scope:
    assert foo_scope.name == "foo"
with tf.variable_scope("bar")
    with tf.variable_scope("baz") as other_scope:
        assert other_scope.name == "bar/baz"
        with tf.variable_scope(foo_scope) as foo_scope2:
            assert foo_scope2.name == "foo"  # 保持不变

2.3 变量作用域的初始化

变量作用域可以默认携带一个初始化器,在这个作用域中的子作用域或变量都可以继承或者重写父作用域初始化器中的值。方法如下:

with tf.variable_scope("foo", initializer=tf.constant_initializer(0.4)):
    v = tf.get_variable("v", [1])
    assert v.eval() == 0.4  # 被作用域初始化
    w = tf.get_variable("w", [1], initializer=tf.constant_initializer(0.3)):
    assert w.eval() == 0.3  # 重写初始化器的值
    with tf.variable_scope("bar"):
        v = tf.get_variable("v", [1])
        assert v.eval() == 0.4  # 继承默认的初始化器
    with tf.variable_scope("baz", initializer=tf.constant_initializer(0.2)):
        v = tf.get_variable("v", [1])
        assert v.eval() == 0.2  # 重写父作用域的初始化器的值

上面讲的是variable_name,那对于op_name呢?在variable_scope作用域下的操作,也会被加上前缀:

with tf.variable_scope("foo"):
    x = 1.0 + tf.get_variable("v", [1])
assert x.op.name == "foo/add"

3.name_scope示例

name_scope会影响op_name,不会影响用get_variable()创建的变量,而会影响通过V ariable()创建的变量。因此:

with tf.variable_scope("foo"):
    with tf.name_scope("bar"):
        v = tf.get_variable("v", [1])
        b = tf.Variable(tf.zeros([1]), name='b')
        x = 1.0 + v
assert v.name == "foo/v:0"
assert b.name == "foo/bar/b:0"
assert x.op.name == "foo/bar/add"

可以看出,tf.name_scope()返回的是一个字符串,如上述的"bar"。name_scope对用get_variable()创建的变量的名字不会有任何影响,而V ariable()创建的操作会被加上前缀,并且会给操作加上名字前缀。

4.参考

https://blog.csdn.net/scotthuang1989/article/details/77477026
https://blog.csdn.net/lucky7213/article/details/78967306

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值