tensorflow之tf.name_scope()与tf.variable_scope()的区别

本文将讲解

tf.name_scope()与

tf.variable_scope()的区别

注:若文中有不正确的地方还望多多包涵并不吝指正

本文涉及的官方文档链接如下

https://www.tensorflow.org/api_docs/python/tf/Variablewww.tensorflow.org
https://www.tensorflow.org/api_docs/python/tf/get_variablewww.tensorflow.org
https://www.tensorflow.org/api_docs/python/tf/name_scopewww.tensorflow.org
https://www.tensorflow.org/api_docs/python/tf/variable_scopewww.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()的使用也就介绍完了……

    原文作者:JustDoIT
    原文地址: https://zhuanlan.zhihu.com/p/37711713
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞