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

时间:2016-05-09 09:15:12

标签: tensorflow

嘿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'

因此,我在代码中“重用”相同的范围。直觉上我没有看到这个问题,但会发生以下情况:

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

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

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

非常感谢您的解释! THX

1 个答案:

答案 0 :(得分:3)

您可能希望使用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

我认为这背后的原因是,在您的示例中,尽管您已成功“重新输入”您想要的variable_scope,但真正影响您的变量名称的另一个范围是名为name_scope intead {{1}正如你猜的那样。从官方文档here您可以看到:

  

当我们使用tf.variable_scope(“name”)时,这会隐式打开一个   tf.name_scope( “名称”)。

variable_scope最初用于管理操作名称(例如name_scopeadd),因为matmul实际上是一个操作,其操作名称将被“继承”由它创建的变量,因此tf.Variable而不是name_scope的名称被用作前缀。

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

with

要注意的一点是,当您想要“重新输入”名称范围而不是使用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 时,您应该将先前从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参数将解释如下:

     
      
  1. 字符串(不以'/'结尾)将创建一个新的名称范围,其中   name附加到在。中创建的所有操作的前缀   上下文。如果以前使用过名称,那么它将是唯一的   调用self.unique_name(name)。

  2.   
  3. 以前使用g.name_scope(...)捕获的范围   scope:语句将被视为“绝对”名称范围,   这使得重新输入现有范围成为可能。

  4.   
  5. 值为None或空字符串将重置当前名称   范围到顶级(空)名称范围。

  6.