TensorFlow变量管理
TensorFlow的变量作用域机制通过tf.get_variale()和tf.variable_scope()这两个函数组合完成
共享变量
在定义构建神经层的过程中,我们需要使用诸如
def create_layer(filter_shape, bias_shape):
conv1_wight = tf.Variable(tf.random_normal(filter_shape, name='conv1_weight'))
conv1_bias = tf.Varibale(tf.zero(bias_shape), name='conv1_biases')
reurn
如果我们使用了两次create_layer(),则会产生两组[weights,biases]变量,这样就存在一个问题,实际上我们是想要拥有同样参数的神经网络处理这个问题的,需要变量的共享
TensorFlow提供了变量作用域机制来处理这个问题
变量作用域
变量作用域由两部分组成
tf.get_variale(, , )
tf.variable_scope(,reuse=None)
- tf.get_variable(): 基于结构shape通过初始化initializer方法,创建或者返回一个命名为name的变量,initialier
- tf.constant_initializer(value)常值分布
- tf.random_uniform_initialize(mean,stddev)一致分布
- tf.random_normal_initializer(mean, stddev)高斯分布
- tf.variable_scope(): 简单地可以理解为get_variable()函数的控制器,其定义一个作用域空间,在该空间下,通过get_variable()获得的变量的variable_name都加一个命名空间的前缀,即namespace/variable_name;reuse参数可以有三种取值
- True:使用已经存在的变量
- False:创建新的变量
- None:继承上一层reuse属性
使用共享变量
- tf.get_variale()是为了创建变量并在随后使用,为了达到共享变量的目的,需要在使用前添加作用域tf.variable_scope,目的是为了控制变量的创建与使用
def create_layer(input_tensor,reuse):
with tf.variable_scope('layer1',reuse=reuse):
#第一层神经层
weights= tf.get_variable("weights",[INPUT_NODE,LAYER1_NODE],initializer=tf.truncated_normal_initializer(stddev=0.1))
biases= tf.get_variable("biases",[LAYER1_NODE],initializer=tf.constant_initializer(0.0))
layer1 = tf.nn.relu(tf.matmul(input_tensor,weights)+biases)
with tf.variable_scope('layer2',reuse=reuse):
weights=tf.get_variable("weights",[LAYER1_NODE,OUTPUT_NODE],initializer=tf.truncated_normal_initializer(stddev=0.1))
biases=tf.get_variable("biases",[OUTPUT_NODE],initializer=tf.constant_initializer(0.0))
layer2=tf.matmul(layer1,weights)+biases
return layer2
函数create_layer()的功能是用于创建两层神经网络,对于每一层的权值weight和偏置bias,采用共享变量的方式。
- 第一次调用create_layer()函数时,我们需要设定传进来的reuse参数为false,表示需要创建新变量;以后再次调用create_layer()时,需要设定reuse=True,表示直接共享使用第一次创建的变量即可
x=tf.placeholder(tf.float32,[None,20])
#第一次调用
y=create_layer(x,reuse=False)
#利用已经训练好的神经网络进行预测时,即第二次调用时时
y=create_layer(x,reuse=True)
解析
设定tf.variable_scope()中的参数reuse=True
此时该作用域下的tf.get_varible()会被设定为寻找名称为name且已经存在的变量,即寻找变量模式,当然寻找的区域不局限于该tf.variable_scope()的范围,如果没有寻找到则报错;假设第一次调用create_layer()时,设定reuse=True,由于事先并没有name=’layer1/weight’等的标量,则程序必定会报错当参数reuse=False
此时tf.get_varible()则会创建名称为name的变量,即创建变量模式,并会在变量的varibale_name前加入scope的作用域名称namespace作为前缀,即namespace/variable_name;假设第二次调用create_layer()时,设定reuse=False,由于事先已经创建了name=’layer1/weight’等的标量,则程序必定会报错
tf.Variable()与tf.get_variable()对比
采用tf.Variable()
v11=tf.Variable(tf.zeros([1]),name='one')
v21=tf.Variable(tf.zeros([1]),name='one')
print (v11.name)
print (v21.name)
输出结果
one:0
one_1:0
结果表明采用Variable建立变量时,即使name相同,TersorFlow也会自动的生成两个不同的name的变量