tensorflow提供了经过变量名称来建立或者获取一个变量的机制。经过这个机制,在不一样的函数中能够直接经过变量的名字来使用变量,而不须要将变量经过参数的形式处处传递。
TensorFlow中经过变量名获取变量的机制主要是经过tf.get_variable和tf.variable_scope实现的。
固然,变量也能够经过tf.Varivale来建立。当tf.get_variable用于变量建立时,和tf.Variable的功能基本等价。python
1
2
3
|
#如下两个定义是等价的
v
=
tf.get_variable(
'v'
, shape
=
[
1
], initializer
=
tf.constant_initializer(
1.0
))
v
=
tf.Variable(tf.constant(
1.0
, shape
=
[
1
], name
=
'v'
)
|
tf.get_varialbe和tf.Variable最大的区别在于:tf.Variable的变量名是一个可选项,经过name=’v’的形式给出。可是tf.get_variable必须指定变量名。函数
上面已经提到过了:TensorFlow中经过变量名获取变量的机制主要是经过tf.get_variable和tf.variable_scope实现的。在这里,我主要解释下你们深恶痛绝的reuse问题。
其实只要记住一件事情就ok了:当reuse为False或者None时(这也是默认值),同一个tf.variable_scope下面的变量名不能相同;当reuse为True时,tf.variable_scope只能获取已经建立过的变量。
下面咱们经过代码来看下:spa
1
2
3
4
5
6
|
#reuse=False时会报错的状况:
with tf.variable_scope(
'foo'
):
v
=
tf.get_variable(
'v'
,[
1
],initializer
=
tf.constant_initializer(
1.0
))
with tf.variable_scope(
'foo'
):
v1
=
tf.get_variable(
'v'
,[
1
])
|
在这种状况下会报错:Variable foo/v already exists, disallowed.Did you mean to set reuse=True in Varscope?
其缘由就是在命名空间foo中建立了相同的变量。若是我要在foo下建立一个变量v1,其name=‘v’,只须要将reuse设置为Ture就ok了。将上面第二部分代码修改成:code
1
2
3
|
with tf.variable_scope(
'foo'
, reuse
=
True
):
v1
=
tf.get_variable(
'v'
,[
1
])
print
(v1.name)
#结果为foo/v
|
当reuse已经设置为True时,tf.variable_scope只能获取已经建立过的变量。这个时候,在命名空间bar中建立name=‘v’的变量v3,将会报错:Variable bar/v dose not exists, diallowed. Did you mean to set reuse=None in VarScope?blog
1
2
|
with tf.variable_scope(
'bar'
, reuse
=
True
):
v3
=
tf.get_variable(
'v'
,[
1
])
|
简而言之,reuse=False时,tf.variable_scope建立变量;reuse=True时,tf.variable_scope获取变量。ci
除了tf.variable_scope,tf.name_scope函数也提供了命名空间管理的功能。这两个函数在大部分状况下是等价的,惟一的区别是在使用tf.get_variable函数时。
tf.get_variable函数不受tf.name_scope的影响。
咱们从代码看下这句话的具体意思。
首先是tf.variable_scope:get
1
2
3
|
with tf.variable_scope(
'foo'
):
a
=
tf.get_variable(
'bar'
,[
1
])
print
(a.name)
#结果为foo/bar:0
|
再看tf.name_scope:string
1
2
3
4
5
6
|
with tf.name_scope(
'a'
):
a
=
tf.Variable([
1
])
print
(a.name)
#结果为a/Variable:0
b
=
tf.get_variable(
'b'
,[
1
])
print
(b.name)
#结果为b:0
|
从这个结果中,咱们能很清晰地看到,tf.get_variable建立的变量并非a/b:0,而是b:0。这就表示了在tf.name_scope函数下,tf.get_variable不受其约束。it