####1变量(Variable):创建

当训练模型时,用变量来存储和更新参数。变量包含张量(Tensor)存放于内存的缓存区。建模时它们需要被明确地初始化,模型训练后它们必须被存储到磁盘。这些变量的值可以之后模型训练和分析时被加载。

创建
当创建一个变量时,你讲一个张量作为初始值传入构造函数Variable()。
在TensorFlow中,变量(tf.Variable)的作用就是保存和更新神经网络中的参数。和其他编程语言类似,TensorFlow中的变量也需要指定初始值。TensorFlow提供了一系列操作符来初始化张量,初始值是常量或者随机值。因为在神经网络中,给参数赋予随机初始值最为常见,所以一般也使用随机数给TensorFlow中的变量初始化。


下面代码是在TensorFlow中声明一个2x3矩阵变量的方法:
指定了标准差stddev =2;名称name = “weights”。

weights = tf.Variable(tf.random_normal([2, 3], stddev=2), name="weights")

下面是random_normal()方法的源码:

def random_normal(shape,
                  mean=0.0,
                  stddev=1.0,
                  dtype=dtypes.float32,
                  seed=None,
                  name=None):

参数名

含义

默认值

mean

平均值

0.0

stddev

标准差

1.0

mean 、stddev 、dtype、seed、name都可以自定义初始化自己需要的值。

为了使创建具有常见类型初值的张量更加容易,TensorFlow提供了大量辅助Op,具体如下两个表所示。


表:TensorFlow随机数生成函数

函数名

随机数分布

主要参数

tf.random_normal

正态分布

平均值、标准差、取值类型

tf.truncated_normal

正态分布,但如果随机出来的值偏离平均值超过2个标准差,那么这个数将被重新随机

平均值、标准差、取值类型

tf.random_uniform

平均分布

最小、最大取值,取值类型

tf.random_gamma

Gamma分布

形状参数alpha、尺度参数beta,取值类型


表TensorFlow常数生成函数

函数名

功能

样例

tf.zeros

产生全0的数组

tf.zeros([2,3],dtype=tf.int32)–>[[0 0 0],[0 0 0]]

tf.ones

产生全1的数组

tf.ones([2,3],dtype=tf.int32)–>[[1 1 1],[1 1 1]]

tf.fill

产生一个全部为给定数字的数组

tf.fill([2,3],9)–>[[9 9 9],[9 9 9]]

tf.constant

产生一个给定的常量

tf.constant([1,2,3])–>[1 2 3]

以下代码展示了几个例子

import tensorflow as tf
#为Variable对象传入一个初始值3
my_var = tf.Variable(3,name="my_variable")
add = tf.add(5,my_var)
mul = tf.multiply(8,my_var)
#2x2的零矩阵
zeros = tf.zeros([2,2])

#长度为6的全1向量
ones = tf.ones([6])
#3x3x3的张量,其元素服从0-10的均匀分布
uniform = tf.random_uniform([3,3,3],minval=0,maxval=10)

#3x3x3的张量,其元素服从0均值、标准差为2的正态分布
uniform = tf.random_normal([3,3,3],mean=0,stddev=2.0)

#tf.truncated_normal,因为它不会创建任何偏离均值超过2倍标准差的值,从而可以防止
#有一个或者两个元素与张量中的其他元素显著不同的情况出现
#该Tensor对象不会返回任何小于3.0或大于7.0的值
trunc = tf.truncated_normal([2,2] , mean=5.0 ,stddev=1.0)

#默认均值为0,默认标准差为1.0
random_var = tf.Variable(tf.truncated_normal([2,2]))
def truncated_normal(shape,
                     mean=0.0,
                     stddev=1.0,
                     dtype=dtypes.float32,
                     seed=None,
                     name=None):

####2初始化
变量的初始化必须在模型的其它操作运行之前先明确地完成。最简单的方法就是添加一个给所有变量初始化的操作,并在使用模型之前首先运行那个操作。

Variable对象的初始化通常是通过tf.global_variables_initializer() Op 传给Session.run()完成。
使用**tf.global_variables_initializer()**添加一个操作对变量做初始化。记得在完全构建好模型并加载之后再运行那个操作。(注:initialize_all_variables已过期)
代码如下:

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

下面看个例子:

import tensorflow as tf
#为Variable对象传入一个初始值3
my_var = tf.Variable(3,name="my_variable")
add = tf.add(5,my_var)
mul = tf.multiply(8,my_var)

# Add an op to initialize the variables.
init = tf.global_variables_initializer()
sess = tf.Session()
# Run the init operation.
sess.run(init)

print(sess.run(add))
print(sess.run(mul))

输出:

8
24

如果没有初始化肯定会报错,如下:

FailedPreconditionError: Attempting to use uninitialized value my_variable_6

由另一个变量初始化

你有时候会需要用另一个变量的初始化值给当前变量初始化。由于tf.global_variables_initializer()是并行地初始化所有变量,所以在有这种需求的情况下需要小心。

用其它变量的值初始化一个新的变量时,使用其它变量的initialized_value()属性。你可以直接把已初始化的值作为新变量的初始值,或者把它当做tensor计算得到一个值赋予新变量。

import tensorflow as tf
# Create a variable with a random value.
# weights = tf.Variable(tf.random_normal([2, 2], stddev=0.35),name="weights")
weights = tf.Variable(tf.ones([3]),name="weights")
# Create another variable with the same value as 'weights'.
w2 = tf.Variable(weights.initialized_value(), name="w2")
# Create another variable with twice the value of 'weights'
w_twice = tf.Variable(weights.initialized_value() * 0.2, name="w_twice")

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print(sess.run(weights))
print(sess.run(w2))
print(sess.run(w_twice))

输出

[ 1.  1.  1.]
[ 1.  1.  1.]
[ 0.2  0.2  0.2]

接下来看一个如何通过变量实现神经网络的参数并实现前向传播的过程。

import tensorflow as tf

#1.1 定义变量
w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
x = tf.constant([[0.7, 0.9]])

#1.2 定义前向传播的神经网络
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

#1.3 调用会话输出结果
sess = tf.Session()
sess.run(w1.initializer)  
sess.run(w2.initializer)  
print(sess.run(y))  
sess.close()

输出:

[[ 3.95757794]]

3.Variable对象的修改
要修改Variable对象的值,可使用Variable.assign()方法。该方法的作用是为Variable对象赋予新值。请注意,Variable.assign()是一个Op,要使其生效必须在一个Session对象中运行:

import tensorflow as tf
#创建一个初始值为1的Variable对象
my_var = tf.Variable(1)
#创造一个Op,使其在每次运行时都将该Variable对象乘以2
my_var_times_two = my_var.assign(my_var * 2)
#初始化Op
init = tf.global_variables_initializer()
#启动一个会话
sess = tf.Session()
#初始化Variable对象
sess.run(init)
#将Variable对象乘以2,并将其返回
print(sess.run(my_var_times_two))
#再次相称
print(sess.run(my_var_times_two))
#再次相称
print(sess.run(my_var_times_two))

对于Variable对象的简单自增和自减,TensorFlow提供了Variable.assign_add()和Variable.assign_sub()方法

#自增1
print(sess.run(my_var.assign_add(1)))
#自减1
print(sess.run(my_var.assign_add(1)))

输出

9
10

参考:http://wiki.jikexueyuan.com/project/tensorflow-zh/how_tos/variables.html