TensorFlow基础之变量

一 引入

    当神经网络结构比较简单时,我们可以很好的管理神经网络中的参数。一旦网络结构变得复杂,参数更多,就需要一个好的方式来管理和传递神经网络中的参数了。

    TensorFlow提供了通过变量名称来创建或获取一个变量的机制。在这个机制中,在不同的函数中可以通过变量的名称来使用变量,而不是每次都是将变量通过函数传参的方式来使用变量。TensorFlow中使用变量名称获取变量的机智主要通过tf.get_variable和 tf.variabel_scope函数实现的。

二 tf.Variable函数以及tf.get_variable函数

    tf.get_variable和tf.Variable函数都可以用来创建变量。以下语句是等价的。

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_variable和tf.Variable函数创建变量的过程基本是一样的。TensorFlow中提供的initializer函数一共有七种。分别如下:

1
名称:tf.constant_initializer
功能:将变量初始化为给定常量
主要参数:常量的取值

2 
名称:tf.random_normal_initializer
功能:将变量初始化为满足正太分布的随机值
主要参数:正太分布的均值和标准差

3
名称:tf.truncated_normal_initializer
功能:将变量初始化为满足正太分布的随机值,但如果随机出来的值偏离平均值超过两个标准差,那么这个数将会被重新随机
主要参数:正太分布的均值和标准差

4
名称:tf.random_uniform_initializer
功能:将变量初始化为满足平均分布的随机值
主要参数:最大、最小值

5
名称:tf.uniform_unit_scaling_initializer
功能:将变量初始化为满足平均分布但不影响输出数量级的随机值
主要参数:factor(产生随机数时乘以的系数)

6
名称:tf.zeros_initializer
功能:将变量设置全为0
主要参数:变量维度

7
名称:tf.ones_initializer
功能:将变量设置全为1
主要参数:变量维度

    两个函数最大区别在于指定变量的名称的参数,tf.Variable函数,变量name是一个可选的参数,通过name="v"的形式给出。但是对于tf.get_variable,变量名称是一个必选的参数。它会根据这个名字去创建或获取变量。在以上例程中,它会试图创建一个名字为v的变量,如果创建失败(比如已经存在),程序就会报错。这是变量名复用的结果。

    如果需要tf.get_variable创建一个已经存在的变量,需要通过tf.variable_scope函数来生成一个上下文管理器,并明确指定在这个上下文管理器中,tf.get_variable将直接获取已经生成的变量。

#在名字为foo的命名空间内创建名字为v的变量
with tf.variable_scope("foo"):
    v = tf.get_variable("v",[1],initializer=tf.constant_initializer(1.0))

# 在命名空间已经存在变量v,所以以下代码会报错

with tf.variable_scope("foo"):
    v = tf.get_variable("v",[1])


#在生成上下文管理器时,将参数reuse设置为True。这样tf.get_variable函数将直接获取已经声明的变量
with tf.variable_scope("foo",reuse=True):
    v1 = tf.get_variable("v",[1])
    print (v1 == v)   #输出为true

#在bar命名空间中没有创建变量v,所以下面代码将会报错
with tf.variable_scope("bar",reusue=True):
    v = tf.get_variable("v",[1])

    当tf.variabel_scope函数使用参数reuse=True生成上下文管理器时,这个上下文管理器内所有的tf.get_variable函数将会直接获取已经生成变量,如果不存在,将会报错。相反,如果reuse=False,将会创建新的变量,如果同名变量存在,将会报错。

三 tf.variable_scope函数

    TensorFlow中的tf.variable_scope函数是可以嵌套的,当嵌套时,reuse参数的取值是如何确定的。

with tf.variable_scope("root"):
    #可以通过tf.get_variable_scope().reuse函数来获取当前上下文管理器中的reuse参数
    print tf.get_variable_scope().reuse          #输出为False
    with tf.variable_scope("foo",reuse=True):    #新建一个嵌套的上下文管理器
        print tf.get_variable_scope().reuse      #输出true
        with tf.variable_scope(“bar”):           #不指定reuse
            print tf.get_variable_scope().reuse      #输出True
    print tf.get_variable_scope().reuse             #输出False 退出reuse设置为True的上下文

    tf.variable_scope函数生成的上下文管理器也会创建一个TensorFlow中的命名空间,在命名空间内创建的变量名称都会带上这个命名空间作为前缀。以下代码显示如何通过tf.variable_scope管理变量的名称。

v1 = tf.get_variable("v",[1])

print v1.name    #输出v:0.v为变量的名称,":0"表示这个变量是生成变量这个运算的第一个结果

with tf.variable_scope("foo"):
    v2 = tf.get_variable("v",[1])
    print v2.name   #输出foo/v:0

with tf.variable_scope("foo"):
    with tf.variable_scope("bar"):
        v3 = tf.get_variable("v",[1])
        print v3.name   #输出foo/bar/v:0
    v4 = tf.get_variable("v",[1])
    print v4.name       #输出foo/v1:0


with tf.variable_scope("",reuse=True):      
    v5 = tf.get_variable("foo/bar/v",[1]) #可以直接通过命名空间的变量名来获取其他命名空间下的
                                          #变量
    print v5 == v3                        #True
    v6 = tf.get_variable("foo/v1",[1])
    print v6 = v4                         #True

四 参考

《TensorFlow:实战Google深度学习框架》

猜你喜欢

转载自blog.csdn.net/paopaovae/article/details/81218900