一. 函数的作用
tf.variable_scape() & tf.name_scope()这两个函数的主要作用是结合上下文管理器(with)生成一个变量空间,进而实现变量的高效管理。但是二者也存在区别:
*name_scope*: 为了更好的管理变量的命名空间,但一般对get_variable()函数生成的变量不起作用
*variable_scope*:绝大部分情况下会和tf.get_variable()配合使用,并实现在同一空间中的变量共享
二. 函数的参数说明
1. tf.variable_scope()函数的整体结构如下:
tf.variable_scope(name_or_scope, default_name, values,initializer, regularize, caching_device, partitioner,
custom_getter, reuse, dtype, use_resource, constraint, auxiliary_name_scope)
函数的各个参数说明如下:
-
name_or_scope:生成的变量空间的名称
-
default_name:若name_or_scope为None,则使用该默认的变量空间名称
-
values:传递给操作函数的Tensor参数列表
-
initializer:此范围内变量的默认初始化方式,一般传递一个初始化函数对象
-
regularizer:此范围内变量的默认正规化器,一般传递一个正则化函数对象
-
caching_device:此范围内变量的默认缓存设备
-
partitioner:此范围内变量的默认分区程序。
-
reuse:若为True,则进入该变量空间的重用模式,此时可以重用该变量空间中已经创建过的变量;如果其取值是tf.AUTO_REUSE,则该变量不存在时进行创建,否则重用
-
dtype:在此范围中创建的变量类型(默认为传入范围中的类型,或从父范围继承)。
-
use_resource:如果为False,则所有变量都将是常规变量;如果为true,则将使用具有明确定义的语义的实验性
-
ResourceVariables:默认为false
-
constraint:一个可选的投影函数,在被Optimizer(例如用于实现层权重的范数约束或值约束)更新之后应用于该变量。该函数必须将代表变量值的未投影张量作为输入,并返回投影值的张量(它必须具有相同的形状)。进行异步分布式培训时,约束条件的使用是不安全的
-
auxiliary_name_scope:如果为True,则我们用范围创建一个辅助名称范围;如果为False,则我们不接触名称范围。
2. tf.name_scope()函数的整体结构如下:
tf.name_scope(name, default_name, values)
函数的各个参数说明如下:
-
name:生成的变量空间的名称
-
default_name:若name_or_scope为None,则使用该默认的变量空间名称
-
values:传递给操作函数的Tensor参数列表
三. 函数的使用
1. 在形同的变量空间内使用tf.get_variable()函数创建name属性相同的两个变量时会报错:
#*******************************导入相关模块***********************************#
import tensorflow as tf
#*****************************声明一个变量空间*********************************#
with tf.variable_scope('one'):
a = tf.get_variable('a', [1], initializer=tf.constant_initializer(1.0))
#由于变量空间‘one’中已经创建了一个name属性为‘a’的变量,故一下代码报错
with tf.variable_scope('one'):
a2 = tf.get_variable('a', [1])
2. 当reuse=True,同一变量空间中的变量可以进行重用:
#*******************************导入相关模块***********************************#
import tensorflow as tf
#*****************************声明一个变量空间*********************************#
with tf.variable_scope('one'):
a = tf.get_variable('a', [1], initializer=tf.constant_initializer(1.0))
#通过设置reuse为True,则可以直接获得已经创建的变量(而且只能获取已经声明的变量)
with tf.variable_scope('one', reuse=True):
a2 = tf.get_variable('a', [1])
print(a.name, a2.name)
#--------------------模型的输出
输出为:one/a:0 one/a:0
注:若变量空间中尚未创建相关name属性的变量,则重用的时候会报错!
3. 使用variable_scope()函数时,其变量空间可以嵌套
#*******************************导入相关模块***********************************#
import tensorflow as tf
#***************************声明一个外部变量空间********************************#
a = tf.get_variable('a', [1], initializer=tf.constant_initializer(1.0))
print(a.name)
#***************************声明一个单层变量空间********************************#
with tf.variable_scope('one'):
a2 = tf.get_variable('a', [1], initializer=tf.constant_initializer(1.0))
print(a2.name)
#***************************声明一个嵌套变量空间********************************#
with tf.variable_scope('one'):
with tf.variable_scope('two'):
a4 = tf.get_variable('a', [1], initializer=tf.constant_initializer(1.0))
print(a4.name)
#**********************通过变量空间名称获取相应的变量****************************#
with tf.variable_scope('', reuse=True):
a5 = tf.get_variable('one/two/a', [1])
print(a5 == a4)
#--------------------模型的输出
输出依次为:
a:0
one/a:0
one/two/a:0
True
注:在一个嵌套的变量空间中如果不指定reuse参数,则该变量空间会默认与外层最近的一层保持一致
4. tf.name_scope()仅在搭配get_variable()函数时存在区别:
#*******************************导入相关模块***********************************#
import tensorflow as tf
#*******************************声明变量空间***********************************#
with tf.name_scope('a'):
a = tf.Variable([1], name='a')
print(a.name)
#区别
a = tf.get_variable('b', [1])
print(a.name)
#--------------------模型的输出
输出依次为:
a/a:0
b:0