一 get_variable() 函数 

        get_variable() 函数用于创建或获取变量。 在实现创建变量的功能时,其使用方法和 Variable () 函数基本相同。

   

import tensorflow as tf
# 通过一个常量来初始化一个变量
# a = tf.Variable(tf.constant(1.0,shape=[1],name='a'))

# 使用一个 get_variable()创建一个变量

# 原型 : get_variable(name,shape,dtype,initializer,regularizer,trainable,...)

a = tf.get_variable("a",shape=[1],initializer=tf.constant_initializer(1.0))


init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
print(sess.run(a))
print(a)

从上面的代码中看出,get_variable() 函数调用时提供的形状信息(shape)和 Variable() 函数类似。

    get_variable() 函数通过 initializer 参数提供初始化方法 , 下表为一些初始化函数 :

 

初始化函数

功能

constant_initializer()

将变量初始化为给定的常量

random_normal_initializer()

将变量初始化为满足正态分布的随机值

truncated_normal_initializer()

将变量初始化为满足正态分布的随机值,但如果随机出来的偏离平均值超过2个标准差,那么这个数将重新随机

random_uniform_initializer()

将变量初始化为满足平均分布的随机数值

uniform_uint_scaling_initializer()

将变量初始化为满足平均分布但不影响输出数量级的随机值

zeros_initializer()

将变量初始化全为0 

ones_initializer() 

将变量初始化全为1

 

 

 

   在 get_variable() 中 name 是一个必选的参数 。

二  variable_scope()

   在使用 get_variable() 函数之前,我们要使用函数 variable_scope() 结合上下文管理器(with) 生成一个变量空间。

在相同的变量空间中使用 get_variable() 函数创建name 属性相同的两个变量会导致错位的发生。

import tensorflow as tf

# 在名为 one 的变量空间内创建名字 为 a 的变量

with tf.variable_scope("one") :
a = tf.get_variable("a",[1],initializer=tf.constant_initializer(1.0))

init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
print(a)
#下面会出错

with tf.variable_scope("one") :
a2 = tf.get_variable("a",[1])

     上面的程序简单的说明了variable_scope() 函数影响了get_variable() 函数的使用。在执行创建变量 a2的代码时会由于"one" 这个变量空间中已经存在 name属性为 a 的变量二产生报错信息,提示是否在 variable_scope() 函数中使用reuse= True 参数。

    reuse 参数的默认值为 False , 当variable_scope() 函数使用 reuse = True 参数生成上下文管理器时,这个上下文管理器内所有的get_variable() 函数会直接获取 name 属性相同的已经创建的变量。如果变量不存在,则 get_variable() 函数会报错. 

import tensorflow as tf

# 在名为 one 的变量空间内创建名字 为 a 的变量

with tf.variable_scope("one") :
a = tf.get_variable("a",[1],initializer=tf.constant_initializer(1.0))
with tf.variable_scope("one",reuse=True) :
a2 = tf.get_variable("a",[1])
print(a.name,a2.name)


输出 : one/a:0 one/a:0

如果 使用默认的 resue = False ,创建变量空间,那么 get_variable() 函数将创建新的变量; 如果name属性相同的变量已经存在,get_variable() 函数将会报错。

   使用 variable_scope() 函数创建变量空间时,在变量空间内创建的变量名称都会带上这个变量空间名称作为前缀。上面代码中 

输出 one/a:0 one 就是变量空间。下面展示的是变量空间的嵌套 : 

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])
print(a4.name)
# 输出 one/two/a ,变量空间嵌套之后,
# 变量的名称会加入所有变量的名称作为前缀

b = tf.get_variable("b",[1])
print(b.name)


with tf.variable_scope("",reuse=True) :
# 也可以直接通过变量空间名的前缀的变量名来获取相应的变量
a5 = tf.get_variable("one/two/a",[1])
print(a5 == a4)
#输出 True

下面展示如何确定 reuse 参数的取值 : 

import tensorflow as tf

with tf.variable_scope("one") :
# 使用get_variable_scope() 函数可以获取当前的变量空间
print(tf.get_variable_scope().reuse)
#输出 False

with tf.variable_scope("two",reuse=True):
print(tf.get_variable_scope().reuse)

# 在一个嵌套变量空间中如果不指定 reuse 参数,
# 那么会默认和外面最近的一层保持一致
with tf.variable_scope("three"):
print(tf.get_variable_scope().reuse)
# 输出 True


#回到 reuse 值为默认 False 的最外层变量空间
print(tf.get_variable_scope().reuse)

三 name_scope() 

  name_scope() 函数提供了类似于 variable_scope() 函数的变量空间管理功能,但是在搭配 get_variable() 函数使用时二者会有所差别 。

import tensorflow as tf

with tf.variable_scope("one") :
a = tf.get_variable("var1",[1])
print(a.name)

with tf.variable_scope("two"):
b = tf.get_variable("var2",[1])
print(b.name)

with tf.name_scope("a") :
#使用 Variable() 函数生成变量会受到 name_scope() 的影响

a = tf.Variable([1],name='a')
print(a.name)

a = tf.get_variable("b",[1])
print(a.name)
'''
with tf.name_scope("b") :
#企图创建 name 属性为 b 的变量c ,然而这个变量已经被声明了
c = tf.get_variable("b",[1])
'''

 

    从上面的代码中可以看出, 在 name_scope() 内部使用 get_variable() 函数时,生成的变量名称不会被添加变量空间名称前缀;

而 Variable() 函数在 name_scope() 内部会被添加变量空间名称前缀.使用 variable_scope() 变量空间时 ,无论是 get_variable()

还是 Variable() 都会在生成的变量名称前面添加变量空间名称前缀。