【问题标题】:How does reuse option in tf.variable_scope work?tf.variable_scope 中的重用选项如何工作?
【发布时间】:2017-08-23 03:16:50
【问题描述】:
from __future__ import print_function
import tensorflow as tf

def _var_init(name, shape, initializer=tf.contrib.layers.xavier_initializer(),
              trainable=True):
  with tf.device('/cpu:0'):
    var = tf.get_variable(
      name=name,
      shape=shape,
      initializer=initializer,
      trainable=trainable
    )
    return var

def main():
  sess = tf.Session()

  # 1th case, it works
  with tf.variable_scope('test1', reuse=False) as test1:
    with tf.variable_scope('test2', reuse=False) as test2:
      w1 = _var_init('w1', [1, 2])
      sess.run(tf.global_variables_initializer())
      print(sess.run(w1), w1)

  # 2th case, it works
  with tf.variable_scope('test1', reuse=True):
    with tf.variable_scope('test2', reuse=False):
      w2 = _var_init('w1', [1, 2])
      print(sess.run(w2), w2)

  # 3th case, it works
  with tf.variable_scope(test1, reuse=False):
    with tf.variable_scope(test2, reuse=True):
      w3 = _var_init('w1', [1, 2])
      print(sess.run(w3), w3)

  # 4th case, ValueError: Variable test1/test2/w1 already exists.
  with tf.variable_scope(test1, reuse=True):
    with tf.variable_scope(test2, reuse=False):
      w4 = _var_init('w1', [1, 2])
      print(sess.run(w4), w4)

  # 5th case, ValueError: Variable test1/test2/w1 already exists.
  with tf.variable_scope('test1', reuse=False):
    with tf.variable_scope('test2', reuse=False):
      w5 = _var_init('w1', [1, 2])
      print(sess.run(w5), w5)


if __name__ == '__main__':
    main()

第 1-3 种情况输出:

[[ 0.34345531 -0.84748644]] <tf.Variable 'test1/test2/w1:0' shape=(1, 2) dtype=float32_ref>
[[ 0.34345531 -0.84748644]] <tf.Variable 'test1/test2/w1:0' shape=(1, 2) dtype=float32_ref>
[[ 0.34345531 -0.84748644]] <tf.Variable 'test1/test2/w1:0' shape=(1, 2) dtype=float32_ref>

问题:

我很困惑为什么第 2 种情况有效,但第 4 种情况失败。 Tensorflow 不按 scope_name 搜索 variable_scope 吗?第2种情况和第4种情况有什么区别? (即with tf.variable_scope('test1', reuse=True):with tf.variable_scope(test1, reuse=False):有什么区别?)

我认为他们以前是一样的。但现在它们看起来不同了。 tf.variable_scope 中的重用选项如何工作?

类似但不重复的问题:

  1. How does the reuse option in tf.variable_scope work? ;

  2. How do I force tf.variable_scope to reuse name_scope?

【问题讨论】:

    标签: python tensorflow with-statement


    【解决方案1】:

    来自 Tensorflow 的官方文档,这就是对重用选项的全部解释:

    这是一个共享变量的基本示例:

    with tf.variable_scope("foo"):
         v = tf.get_variable("v", [1])
    with tf.variable_scope("foo", reuse=True):
         v1 = tf.get_variable("v", [1])
    assert v1 == v
    

    通过捕获范围和设置重用来共享变量:

    with tf.variable_scope("foo") as scope:
        v = tf.get_variable("v", [1])
        scope.reuse_variables()
        v1 = tf.get_variable("v", [1])
    assert v1 == v
    

    同样,我们在尝试获取重用模式下不存在的变量时引发异常。

    with tf.variable_scope("foo", reuse=True):
        v = tf.get_variable("v", [1])
        #  Raises ValueError("... v does not exists ...").
    

    请注意,重用标志是继承的:如果我们打开一个重用范围,那么它的所有子范围也将成为重用。

    关于名称范围的说明:设置重用不会影响其他操作的命名,例如 mult。见 github#6189 上的相关讨论

    请注意,直到 1.0 版(包括版本),允许(尽管明确不鼓励)将 False 传递给重用参数,从而产生与 None 略有不同的未记录行为。从 1.1.0 开始,传递 None 和 False 作为重用具有完全相同的效果。

    【讨论】:

    • 感谢您的回答。我注意到您说“注意重用标志是继承的:......也是如此”。事实上,test1 范围内的重用选项不控制其子范围 test2 重用选项。正如您所说,test2 范围应继承 test1 范围中的重用选项并忽略其自己的重用选项。如果那样,第 3 种情况将发生 ValueError('w is already exists')。相反,第 3 种情况有效,第 4 种情况是错误的。我认为重用取决于它自己的重用选项,而不是它的父范围。但是第二种情况有效,看起来重用不依赖于它自己的重用选项,而是它的父范围重用选项
    • 这就是我对此感到困惑的原因。我读了 github#6189,他们的问题是不同的。在我的情况下,所有w 值都具有相同的名称和值,它正在重用。我仍然对第 2 种情况和第 4 种情况感到困惑。它们唯一的区别是第 2 种情况通过字符串获取变量 sope,而第 4 种情况通过变量获取变量范围。但是test1variable_scope的名字是'test1',这种方式有什么影响呢?
    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多