https://cloud.tencent.com/developer/ask/142809/answer/250540
你可以通过在名称后添加“/”来强制重用范围,即: tf.variable_scope("foo/", reuse=True):
但是,这不会解决你的问题。
在变量的情况下,调用tf.Variable
将始终创建一个新变量,而调用tf.get_variable
将重用它
但是对于占位符,没有tf.get_placeholder(原作者相对于“tf.get_variable”而言)
。
你可以做的是在foo之外,唯一次地定义你的占位符,并使用tf.get_default_graph().get_tensor_by_name(name)
或直接使用python变量来获取它们。
import tensorflow as tf
with tf.name_scope("scope"):
tf.placeholder(tf.float32,name="a")
tf.placeholder(tf.float32,name="b")
print(a)
print(b)
def foo():
a = tf.get_default_graph().get_tensor_by_name("scope/a:0")
b = tf.get_default_graph().get_tensor_by_name("scope/b:0")
return a,b
a,b = foo()
print(a)
print(b)
“”“”“”“”“”“”“”“”“”“”“”“
Tensor("scope/a:0", dtype=float32)
Tensor("scope/b:0", dtype=float32)
Tensor("scope/a:0", dtype=float32)
Tensor("scope/b:0", dtype=float32)
”“”“”“”“”“”“”“”“”“”“”“”“
错误
def foo():
with tf.variable_scope("foo", reuse=True):
a = tf.placeholder(tf.float32,name="a")
b = tf.placeholder(tf.float32,name="b")
return a,b
with tf.Graph().as_default():
a,b = foo()
print(a) # gives variable name 'foo/a'
print(b) # gives variable name 'foo/b'
c, d = foo()
print(c)
print(d)
“”“
Tensor("foo/a:0", dtype=float32)
Tensor("foo/b:0", dtype=float32)
Tensor("foo_1/a:0", dtype=float32)
Tensor("foo_1/b:0", dtype=float32)
“”“
def foo2():
“”“
其实不是在这里定义reuse=True,就说明这些是可以reuse的
见官方api示例 https://tensorflow.google.cn/versions/r1.10/api_docs/python/tf/variable_scope#__init__
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
第一次定义变量,并没有reuse=True,是在需要reuse的地方加
”“”
with tf.variable_scope("foo2", reuse=True):
a = tf.placeholder(tf.float32,name="a",shape=[1])
b = tf.placeholder(tf.float32,name="b", shape=[1])
return a, b
a, b = foo2()
print(a) #Tensor("foo2/a:0", shape=(1,), dtype=float32)
print(b) #Tensor("foo2/b:0", shape=(1,), dtype=float32)
c, d = foo2()
print(c) #Tensor("foo2_1/a:0", shape=(1,), dtype=float32)
print(d) #Tensor("foo2_1/b:0", shape=(1,), dtype=float32)
def foo3():
“”“
reuse=True报错
“ValueError: Variable foo2/a does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?
”
原因同上,第一次定义时,并不存在该变量,get_variable和reuse矛盾
def foo4():
with tf.variable_scope("foo2", reuse=True):
a = tf.Variable([1], name='a')
return a
a1 = foo4()
print(a1)
<tf.Variable 'foo4/a:0' shape=(1,) dtype=int32_ref> 这样ok
”“”
with tf.variable_scope("foo2", reuse=tf.AUTO_REUSE):
a = tf.get_variable("a", [1])
return a
a1 = foo3()
print(a1) # <tf.Variable 'foo2/a_1:0' shape=(1,) dtype=float32_ref>
a2 = tf.get_default_graph().get_tensor_by_name("foo2/a:0")
print(a2) #Tensor("foo2/a:0", shape=(1,), dtype=float32)
a3 = tf.get_default_graph().get_tensor_by_name('foo2/a_1:0')
print(a3) #Tensor("foo2/a_1:0", shape=(1,), dtype=float32_ref)
state = tf.Variable(0, name="counter")
print(state) #<tf.Variable 'counter:0' shape=() dtype=int32_ref>
e = tf.constant([1], name='e')
print(e) #Tensor("e:0", shape=(1,), dtype=int32)
f = tf.Variable(e, name='f')
print(f) #<tf.Variable 'f:0' shape=(1,) dtype=int32_ref>
g = tf.Variable(e, name='g', dtype=tf.int32)
print(g) #<tf.Variable 'g:0' shape=(1,) dtype=int32_ref>
“”“
Tensor("foo2/a:0", shape=(1,), dtype=float32)
Tensor("foo2/b:0", shape=(1,), dtype=float32)
Tensor("foo2_1/a:0", shape=(1,), dtype=float32)
Tensor("foo2_1/b:0", shape=(1,), dtype=float32)
# 类型为ref reference
<tf.Variable 'foo2/a_1:0' shape=(1,) dtype=float32_ref>
Tensor("foo2/a:0", shape=(1,), dtype=float32)
Tensor("foo2/a_1:0", shape=(1,), dtype=float32_ref)
<tf.Variable 'counter:0' shape=() dtype=int32_ref>
Tensor("e:0", shape=(1,), dtype=int32)
<tf.Variable 'f:0' shape=(1,) dtype=int32_ref>
<tf.Variable 'g:0' shape=(1,) dtype=int32_ref>
”“”
http://www.tensorfly.cn/tfdoc/get_started/basic_usage.html
- 使用 tensor 表示数据.
- 通过
变量 (Variable)
维护状态. - 在 Python 语言中, 返回的 tensor 是 numpy
ndarray
对象; 在 C 和 C++ 语言中, 返回的 tensor 是tensorflow::Tensor
实例.
构建图的第一步, 是创建源 op (source op). 源 op 不需要任何输入, 例如 常量 (Constant)
. 源 op 的输出被传递给其它 op 做运算.
所以tf.placeholder也是一种源op。
http://www.tensorfly.cn/tfdoc/how_tos/variables.html
调用tf.Variable()
会添加一些操作(Op, operation)到graph:
- 一个
Variable
操作(op)存放变量的值。 - 一个初始化op将变量设置为初始值。这事实上是一个
tf.assign
操作. - 初始值的操作,例如示例中对
biases
变量的zeros
操作也被加入了graph。
tf.Variable
的返回值是Python的tf.Variable
类的一个实例。
由上两点可看出tensor和Variable明显的不同。