在重用变量时,我对子范围有疑问。这个
import tensorflow as tf
def make_bar():
with tf.variable_scope('bar'):
tf.get_variable('baz', ())
with tf.variable_scope('foo') as scope:
make_bar()
scope.reuse_variables()
make_bar()
工作正常,只创建了一个变量foo/bar/baz
。
但是,如果我将make_bar
更改为
def make_bar(scope=None):
with tf.variable_scope(scope, 'bar'):
tf.get_variable('baz', ())
代码现在失败,并显示
ValueError: Variable foo/bar_1/baz does not exist
问题:为什么在使用default name
时变量范围重用失败?如果是有目的的,那么此选择的依据是什么?
编辑
default_name
的{{1}}参数上有一些精度。 From the documentation,
tf.variable_scope
:如果default_name
参数为name_or_scope
时使用的默认名称,该名称将是唯一的。如果提供了None
,则不会使用它,因此它不是必需的,可以是name_or_scope
。
因此,作为其名称的基础,这是提供默认作用域名称的一种方式。
在None
的第一个版本中,作用域名称被强制为make_bar
-函数没有参数可以对其进行更改。
在bar
的第二版中,我增强了此功能以使其可参数化。因此,make_bar
仍然是默认作用域名称(这次提供为bar
的{{1}}参数),但是这次调用者可以通过设置默认参数{{ default_name
中的1}}到tf.variable_scope
以外的任何其他位置。
我认为第二个版本的scope
不带参数时,我认为应该回到第一个版本的行为,而没有。
请注意,在我的示例中,make_bar
是None
的子范围。要重用的变量为 meant 为make_bar
。
答案 0 :(得分:4)
在示例中,您实际上并没有使用范围'foo'。您需要将参数传递给tf.variable_scope('foo', 'bar')
或tf.variable_scope(scope, 'bar')
。
您在任何一种情况下都调用不带参数的方法make_bar
,这意味着在第一个示例name_or_scope='bar'
,第二个示例name_or_scope=scope
(值None
)和{ {1}}。
这可能是您想要的:
default_name='bar'
实际上,我建议不要使用默认参数,因为它们会像您的示例那样降低可读性。 import tensorflow as tf
def make_bar(scope=None):
with tf.variable_scope(scope, 'bar'):
tf.get_variable('baz', ())
with tf.variable_scope('foo') as scope:
make_bar(scope)
scope.reuse_variables()
make_bar(scope)
范围什么时候才是您想要的答案?如果您进行测试,可能会更有意义?
None
但是这会使代码的可读性降低,并且更有可能导致错误
答案 1 :(得分:2)
摘自文档https://www.tensorflow.org/api_docs/python/tf/variable_scope
如果
name_or_scope
不为None,则照原样使用。如果name_or_scope
为无,则使用default_name
。在这种情况下,如果同名 已在同一范围内使用过,它将变为唯一 通过向其附加_N
。
...
为防止意外共享变量,我们在 在非重用范围内获取现有变量。
...
类似地,当我们尝试获取一个 在重用模式下不存在。
通过使用None
范围,您将强制每次对get_variable
的调用来生成唯一的范围/变量,但是通过调用reuse_variables
,您将迫使后续的调用仅返回现有变量。没有要返回的变量,因此引发了ValueError
。这是预期的行为。