tf.variable_scope()的认识
def variable_scope(name_or_scope,
default_name=None,
values=None,
initializer=None,
regularizer=None,
caching_device=None,
partitioner=None,
custom_getter=None,
reuse=None,
dtype=None,
use_resource=None):
官方对reuse的解释:
reuse: `True` or `None`; if `True`, we go into reuse mode for this scope as well as all sub-scopes; if `None`, we just inherit the parent scope reuse.
code1:
with tf.variable_scope("foo") as variable_scope:
a = 1
print("variable_scope:", variable_scope)
输出:
variable_scope: <tensorflow.python.ops.variable_scope.VariableScope object at 0x0000020119EC3780>
可以看出:variable_scope是一个VariableScope对象。所以,在代码段code1中,加入下面代码:
print("variable_scope。name:", variable_scope.name)
最终输出为:
variable_scope: <tensorflow.python.ops.variable_scope.VariableScope object at 0x0000020119EC3780>
variable_scope.name: foo
如果嵌套多个tf.variable_scope():
code2:
with tf.variable_scope("foo1") as variable_scope1:
with tf.variable_scope("foo2") as variable_scope2:
with tf.variable_scope("foo3") as variable_scope3:
a = 1
print("variable_scope1:", variable_scope1)
print("variable_scope2:", variable_scope2)
print("variable_scope3:", variable_scope3)
print("variable_scope1.name:", variable_scope1.name)
print("variable_scope2.name:", variable_scope2.name)
print("variable_scope3.name:", variable_scope3.name)
输出:
variable_scope1: <tensorflow.python.ops.variable_scope.VariableScope object at 0x000002B36ABF06A0>
variable_scope2: <tensorflow.python.ops.variable_scope.VariableScope object at 0x000002B36AC31DD8>
variable_scope3: <tensorflow.python.ops.variable_scope.VariableScope object at 0x000002B36AC29048>
variable_scope1.name: foo1
variable_scope2.name: foo1/foo2
variable_scope3.name: foo1/foo2/foo3
总结:tf.variable_scope()产生的类型是一个VairableScope Object.
tf.variable_scope()可以嵌套使用。
tf.name_scope()的认识
def name_scope(name, default_name=None, values=None):
code1:
with tf.name_scope("scope0") as scope0:
with tf.name_scope("scope1") as scope1:
with tf.name_scope("scope2") as scope2:
a = 1
print("scope0:", scope0)
print("scope1:", scope1)
print("scope2:", scope2)
print("type(scope0):", type(scope0))
输出:
scope0: scope0/
scope1: scope0/scope1/
scope2: scope0/scope1/scope2/
type(scope0): <class 'str'>
总结:tf.name_scope()也可以相互嵌套使用,但是,产生的类型是一个str类型。
接下来,看另一段代码:code2
with tf.name_scope("scope0") as scope0:
with tf.name_scope("scope1") as scope1:
with tf.name_scope("scope2") as scope2:
with tf.name_scope(scope1) as scope11:
with tf.name_scope(None) as scope00:
with tf.name_scope("xxx") as scopexxx:
print("scope0:", scope0)
print("scope1:", scope1)
print("scope2:", scope2)
print("scope11:", scope11)
print("scope00:", scope00)
print("scopexxx:", scopexxx)
输出:
scope0: scope0/
scope1: scope0/scope1/
scope2: scope0/scope1/scope2/
scope11: scope0/scope1/
scope00:
scopexxx: xxx/
说明:
name:
*A string (not ending with '/') will create a new name scope, in which
`name` is appended to the prefix of all operations created in the
context. If `name` has been used before, it will be made unique by
calling `self.unique_name(name)`.
* A scope previously captured from a `with g.name_scope(...) as
scope:` statement will be treated as an "absolute" name scope, which
makes it possible to re-enter existing scopes.
* A value of `None` or the empty string will reset the current name scope
to the top-level (empty) name scope.
tf.get_variable()的认识(&tf.variable_scope())
def get_variable(name,
shape=None,
dtype=None,
initializer=None,
regularizer=None,
trainable=True,
collections=None,
caching_device=None,
partitioner=None,
validate_shape=True,
use_resource=None,
custom_getter=None):
说明:tf.get_variable()里面的attribute 与 tf.variable_scope里面的attribute同名相对应。
tf.get_variable()返回一个已经存在或者新创建的variable.
tf.get_variable()会把当前的variable scope 的 name当作前缀,并且执行reuse 检查.
code1:
with tf.variable_scope("firstScope") as firstScope:
with tf.variable_scope("secondScope0") as secondScope0:
x = tf.get_variable("x", [1])
with tf.variable_scope("secondScope1") as secondScope1:
y = tf.get_variable("y", [1])
with tf.variable_scope("thirdScope") as thirdScope:
z = tf.get_variable("z", [1])
print("firstScope name:", firstScope.name)
print("secondScope0 name:", secondScope0.name)
print("secondScope1 name:", secondScope1.name)
print("x:", x.name)
print("y:", y.name)
print("z:", z.name)
输出:
firstScope name: firstScope
secondScope0 name: firstScope/secondScope0
secondScope1 name: firstScope/secondScope1
x: firstScope/secondScope0/x:0
y: firstScope/secondScope1/y:0
z: firstScope/secondScope1/thirdScope/z:0
总结:tf.get_variable()生成的variable的name包含了tf.variable_scope()的name.
code2: 修改code1
这里写代码片
with tf.variable_scope("firstScope") as firstScope:
with tf.variable_scope("secondScope0") as secondScope0:
x = tf.get_variable("x", [1])
with tf.variable_scope("secondScope1") as secondScope1:
y = tf.get_variable("y", [1])
# yy = tf.get_variable("y", [1])
with tf.variable_scope("secondScope1", reuse=True) as thirdScope:
z = tf.get_variable("y", [1])
print("firstScope name:", firstScope.name)
print("secondScope0 name:", secondScope0.name)
print("secondScope1 name:", secondScope1.name)
print("x:", x.name)
print("y:", y.name)
print("z:", z.name)
输出:
firstScope name: firstScope
secondScope0 name: firstScope/secondScope0
secondScope1 name: firstScope/secondScope1
x: firstScope/secondScope0/x:0
y: firstScope/secondScope1/y:0
z: firstScope/secondScope1/y:0
说明:variable y和 variable z 是同一个variable.当reuse=True,而又不存在对应的variable,则会出错。
tf.get_variable()的认识(&tf.name_scope())
code1:
with tf.name_scope("scope0") as scope0:
a = tf.get_variable("a", [1])
with tf.name_scope("scope1") as scope1:
b = tf.get_variable("b", [1])
with tf.name_scope("scope2") as scope2:
c = tf.get_variable("c", [1])
print("scope0:", scope0)
print("scope1:", scope1)
print("scope2:", scope2)
print("a name:", a.name)
print("b name:", b.name)
print("c name:", c.name)
输出:
scope0: scope0/
scope1: scope0/scope1/
scope2: scope0/scope1/scope2/
a name: a:0
b name: b:0
c name: c:0
说明:当使用tf.name_scope()时,tf.get_variable()不会把tf.name_scope()的name作为前缀。这是因为在tf.get_variable()函数中,无论有没有name_scope,在函数实现过程中,都会使得name_scope=None.部分实现代码如下:
这里写代码片
# Variable names only depend on variable_scope (full_name here),
# not name_scope, so we reset it below for the time of variable creation.
with ops.name_scope(None):
......
tf.variable_scope()&tf.name_scope()&tf.get_variable()
code:
这里写代码片
with tf.variable_scope("scope0") as scope0:
a = tf.get_variable("a", [1])
with tf.name_scope("scope1") as scope1:
b = tf.get_variable("b", [1])
with tf.variable_scope("scope2") as scope2:
c = tf.get_variable("c", [1])
print("scope0:", scope0.name)
print("scope1:", scope1)
print("scope2:", scope2.name)
print("a name:", a.name)
print("b name:", b.name)
print("c name:", c.name)
输出:
scope0: scope0
scope1: scope0/scope1/
scope2: scope0/scope2
a name: scope0/a:0
b name: scope0/b:0
c name: scope0/scope2/c:0
说明:tf.variable_scope()和tf.name_scope()可以相互嵌套使用。具体根据自己需要。
tf.variable_scope(),tf.name_scope(),tf.get_variable()的认识(补充)