本文将讲解
tf.name_scope()与
tf.variable_scope()的区别
注:若文中有不正确的地方还望多多包涵并不吝指正
本文涉及的官方文档链接如下
https://www.tensorflow.org/api_docs/python/tf/Variable www.tensorflow.org
https://www.tensorflow.org/api_docs/python/tf/get_variable www.tensorflow.org
https://www.tensorflow.org/api_docs/python/tf/name_scope www.tensorflow.org
https://www.tensorflow.org/api_docs/python/tf/variable_scope www.tensorflow.org
当神经网络的结构更加复杂、参数更多时,就需要一个更好的方式来传递和管理神经网络中的参数了。TensorFlow提供了通过变量名称(name)来创建或者获取一个变量的机制。通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递。
TensorFlow提供了两种创建变量的方法,一种是tf.Variable(),另一种是tf.get_variable()。
tf.get_variable()除了可以创建变量外,还能获取变量。当tf.get_variable()用于创建变量时,它与tf.Variable()的功能是基本等价的。
#下面这两个定义是等价的
v = tf.get_variable('v', shape=[1], initializer=tf.tf.constant_initializer(1.0))
v = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
- tf.name_scope()
import tensorflow as tf
with tf.name_scope('name_scope_test'):
v1 = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v2 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v3 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print('the name of v1:', v1.name)
print('the name of v2:', v2.name)
print('the name of v3:', v3.name)
#输出为
#the name of v1: v:0
#the name of v2: name_scope_test/v:0
#the name of v3: name_scope_test/v_1:0
上面代码和输出结果表明,tf.name_scope()对tf.get_variable没有影响,但对tf.Variable有影响,会在原有的name上加上命名空间,也就是name_scope_test/v:0,如果在tf.name_scope作用域下有相同的name,则会自动加上命名空间和会重命名name,即name_scope_test/v:0和name_scope_test/v_1:0
- tf.variable_scope()
import tensorflow as tf
with tf.variable_scope('variable_scope_test'):
v1 = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v2 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v3 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print('the name of v1:', v1.name)
print('the name of v2:', v2.name)
print('the name of v3:', v3.name)
#输出为
#the name of v1: variable_scope_test/v:0
#the name of v2: variable_scope_test/v_1:0
#the name of v3: variable_scope_test/v_2:0
上面代码和输出结果表明, tf.variable_scope对tf.get_variable有影响,会在原有的name上加上变量空间,也就是variable_scope_test/v:0。tf.Variable在tf.name_scope和tf.variable_scope作用域下的效果一样
import tensorflow as tf
with tf.variable_scope('variable_scope_test'):
v1 = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v2 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v3 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
with tf.variable_scope('variable_scope_test'):
v4 = tf.get_variable('v', shape=[1])
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print('the name of v1:', v1.name)
print('the name of v2:', v2.name)
print('the name of v3:', v3.name)
print('the name of v4:', v4.name)
上面的代码会报这样的错误:ValueError: Variable variable_scope_test/v already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope?
因为在第二块with tf.variable_scope(‘variable_scope_test’):处又在variable_scope_test变量命名空间下定义了name为v的变量,也就是这里(v4 = tf.get_variable(‘v’, shape=[1]))重新定义了已存在的变量
import tensorflow as tf
with tf.variable_scope('variable_scope_test'):
v1 = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v2 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v3 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
with tf.variable_scope('variable_scope_test', reuse=True):
v4 = tf.get_variable('v', shape=[1])
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print('the name of v1:', v1.name)
print('the name of v2:', v2.name)
print('the name of v3:', v3.name)
print('the name of v4:', v4.name)
#输出为
#the name of v1: variable_scope_test/v:0
#the name of v2: variable_scope_test/v_1:0
#the name of v3: variable_scope_test/v_2:0
#the name of v4: variable_scope_test/v:0
上面的代码能正确运行,是因为在第二块with tf.variable_scope(‘variable_scope_test’, reuse=True)处设置了reuse=True
import tensorflow as tf
with tf.variable_scope('variable_scope_test'):
v1 = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v2 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v3 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
with tf.variable_scope('variable_scope_test', reuse=True):
v4 = tf.get_variable('v1', shape=[1])
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print('the name of v1:', v1.name)
print('the name of v2:', v2.name)
print('the name of v3:', v3.name)
print('the name of v4:', v4.name)
上面的代码会报这样的错:ValueError: Variable variable_scope_test/v1 does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=tf.AUTO_REUSE in VarScope?
之所以报这个错,是因为设置reuse=True之后在该变量命名空间内,tf.get_variable只能获取已存在的变量而不能创建新变量
但如果又想创建变量,又想重用变量即获取变量呢?那可以用下面这个方法
import tensorflow as tf
with tf.variable_scope('variable_scope_test'):
v1 = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v2 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
v3 = tf.Variable(tf.constant(1.0, shape=[1]), name='v')
with tf.variable_scope('variable_scope_test') as scope:
v4 = tf.get_variable('v1', shape=[1], initializer=tf.constant_initializer(1.0))
scope.reuse_variables()
v5 = tf.get_variable('v', shape=[1])
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print('the name of v1:', v1.name)
print('the name of v2:', v2.name)
print('the name of v3:', v3.name)
print('the name of v4:', v4.name)
print('the name of v5:', v5.name)
#输出为
#the name of v1: variable_scope_test/v:0
#the name of v2: variable_scope_test/v_1:0
#the name of v3: variable_scope_test/v_2:0
#the name of v4: variable_scope_test/v1:0
#the name of v5: variable_scope_test/v:0
到此,关于tf.name_scope()和tf.variable_scope()的使用也就介绍完了……