在 tf.variable_scope(name) 中创建一个变量,从另一个变量的 initialized_value 初始化

creating a variable within tf.variable_scope(name), initialized from another variable's initialized_value

嘿 tensorflow 社区,

我在以下设置中使用 variable_scope 时遇到意外的命名约定:

with tf.variable_scope("my_scope"):
    var = tf.Variable(initial_value=other_var.initialized_value())

在上面,认为

other_var.name = 'outer_scope/my_scope/other_var_name:0'

因此,我 "reusing" 在代码的这一点上处于相同的范围。直觉上我看不出这有什么问题,但会发生以下情况:

var.name = 'outer_scope/my_scope_1/var_name:0'

显然,tf 对 "my_scope" 不满意,需要附加“_1”。 但是 "outer_scope" 保持不变。

如果我不使用 "other_var" 进行初始化,则不会出现此行为。

如有解释,将不胜感激!谢谢

垫子

您可能想使用 tf.get_variable() 而不是“tf.Variable”。

with tf.variable_scope('var_scope', reuse=False) as var_scope:
    var = tf.get_variable('var', [1])
    var2 = tf.Variable([1], name='var2')
    print var.name # var_scope/var:0 
    print var2.name # var_scope/var2:0

with tf.variable_scope('var_scope', reuse=True) as var_scope:
    var = tf.get_variable('var', [1])
    var2 = tf.Variable([1], name='var2')
    print var.name # var_scope/var:0 
    print var2.name # var_scope_1/var2:0

我认为这背后的原因是,在你的例子中,虽然你已经成功地 "re-entered" 你想要的 variable_scope,但真正影响你的变量名的是另一个名为 name_scope 的范围正如您可能猜到的那样,而不是 variable_scope。从官方文档here可以看出:

when we do with tf.variable_scope("name"), this implicitly opens a tf.name_scope("name").

name_scope本来是用来管理操作名的(比如addmatmul),因为tf.Variable其实就是一个操作,它的操作名会是"inherited" 由它创建的变量,因此 name_scope 而不是 variable_scope 的名称用作前缀。

但是如果要使用tf.Variable,也可以直接在with语句中使用name_scope

with tf.name_scope('n_scope') as n_scope:
    var = tf.Variable([1], name='var')
    print var.name #n_scope/var_1:0

with tf.name_scope(n_scope) as n_scope:
    var = tf.Variable([1], name='var')
    print var.name #n_scope/var_1:0

需要注意的一件事是,当您想要 "re-enter" 名称范围时,您应该将先前从 with 语句捕获的范围变量作为参数传递,而不是使用 str 作用域名称:

  with tf.name_scope('n_scope') as n_scope:
      var = tf.Variable([1], name='var')
      print var.name #n_scope/var_1:0

  with tf.name_scope('n_scope') as n_scope:
      var = tf.Variable([1], name='var')
      print var.name #n_scope_1/var_1:0

注意传递给 tf.name_scope 的参数。此行为在 name_scope:

的文档字符串中再次描述

The name argument will be interpreted as follows:

  1. A string (not ending with ‘/’) will create a new name scope, in which name is appended to the prefix of all operations created in the context. If name has been used before, it will be made unique by calling self.unique_name(name).

  2. A scope previously captured from a with g.name_scope(...) as scope: statement will be treated as an “absolute” name scope, which makes it possible to re-enter existing scopes.

  3. A value of None or the empty string will reset the current name scope to the top-level (empty) name scope.