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>
问题:
我很困惑为什么第二个案例有效但第四个案例失败了。 Tensorflow是否通过scope_name搜索variable_scope?第2例和第4例之间的区别是什么? (即with tf.variable_scope('test1', reuse=True):
和with tf.variable_scope(test1, reuse=False):
之间的区别是什么?)
我认为他们之前是一样的。但现在他们看起来不同了。 tf.variable_scope中的重用选项如何工作?
类似但不重复的问题:
答案 0 :(得分: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,因为重用具有完全相同的效果。