文章目录
变量
tf.Variable
是一个Python类,它返回的是一个Python实例,这个实例提供若干操作(Op,operation)。
调用tf.Variable()
将添加一些操作(Op, operation)到计算图(graph)中:
- 一个Variable操作存放变量的值
- 一个初始化op将变量设置为初始值。这事实上是一个tf.assign操作
- 初始化值的操作,例如:
tf.zeros(shape=None) - float32
,tf.ones(shape=None) - float32
1.1 创建,使用变量
我们可以直接调用tf.Variable()
进行变量创建,例如我们只需要简单的给出初始化的数值和变量名:
import tensorflow as tf
# int32 shape=[1]
a = tf.Variable(1, name='a')
# float32 shape=[1]
b = tf.Variable(2.0, name='b')
# int32 shape=[2]
c = tf.Variable([1, 2], name='c')
# float32 shape=[1]
d = tf.Variable(tf.ones(shape=[1]), 'd')
可以看到,可以是任意类型和维度的张量用来初始化一个变量。
另外,对于一个张量的相关操作,同样可以用于对一个变量进行操作(这些操作在Variable
中被重载(Overloaded)了):
import tensorflow as tf
# 创建一个变量
w = tf.Variable(<initial-value>, name=<optional-name>)
# 向量(矩阵)乘法,可以是和另外一个变量或者是一个张量相乘
y = tf.matmul(w, ...another variable or tensor...)
# 操作符重载 +
# sigmoid为tensorflow的一个激活函数
z = tf.sigmoid(w + b)
# 用assign相关的方法可以用来给一个变量赋一个新的值
# 加1
w.assign(w + 1.0)
# 加1
w.assign_add(1.0)
# 减1
w.assign_sub(1.0)
我们可以用下面的方法在一个会话中来获得一个变量的值:
with tf.Session() as sess:
sess.run(w.initializer())
w.eval(session=sess)
我们在调用eval(session)
方法之前,先运行了变量w
的初始化Op。每当我们希望使用一个变量的时候,必须先对这个变量进行初始化!事实上,这个初始化操作是把我们预先给出的初始化值赋给这个变量,其实就是一个assign的操作,相当于:
w.assign(w.initialized_value())
initialized_value()
返回的是我们在创建这个变量的时候给出的初始化值。
tf.Variable()的参数列表:
参数名 | 说明 |
---|---|
initialized_value | 初始化值 |
name | 变量名 |
collections | 指明所在的变量集合的键,可以是: tf.GraphKeys.GLOBAL_VARIABLES tf.GraphKeys.LOCAL_VARIABLES tf.GraphKeys.MODEL_VARIABLES tf.GraphKeys.TRAINABLE_VARIABLES |
1.3 初始化方法
1.3.1 initialize_all_variables()
这个方法会返回一个op,我们可以这样使用:
with tf.Session() as sess:
tf.initialize_all_variables().run()
# use variables
当然你也可以在Session外面先对它进行引用:
init_op = tf.initialize_all_variables()
with tf.Session() as sess
sess.run(init_op)
这样会对所有的变量进行初始化,然后我们就可以使用这些变量了。
1.3.2 initialize_variables(var_list, name=‘init’)
如果你打算指定一系列变量进行初始化的话,可以使用:
tf.initialize_variables(var_list, name=‘init’)
这个函数同样会返回一个Op,用法与tf.initialize_all_variables()
相同。如果var_list
为空的话,这个Op一样可以运行,当然,它不会起到任何作用。name
是这个Op的名字:
init_op = tf.initialize_variables()
with tf.Session() as sess
# no effect
sess.run(init_op)
1.3.3 global_variables_initializer()
你可能会发现,当我们使用tf.initialize_all_variables()
这个方法的时候,Python会提示我们:这个方法已经被废弃(Deprecated)了!然后建议我们使用这个方法:
tf.global_variables_initializer()
其实这个方法功能是一样的(或许只是换了个名字?),同样会返回一个Op,这个方法会调用两个Op:
global_variables
返回一个variables_list
,里面包含global variables
,也就是我们定义的所有变量variable_initializer()
取出variables_list
中所有变量的初始化Opinitializer
,组合成一个Op group
所以事实上,当我们运行这个函数返回的Op时,就是将所有的global variables
的初始化器运行了一遍,简化了我们的初始化工作。
P.S. 个人猜测,可能这个修改是为了明确的指出:这个方法所初始化的是针对全局变量进行初始化,而不会针对任何的局部变量!例如,在一个函数中定义的变量,这时我们则需要采用 initialize_variables(var_list)
指定局部变量列表进行初始化,如果直接采用 initialize_all_variables()
将不会初始化任何局部变量,可能导致后续对局部变量的使用出现错误。废弃initialize_all_variables()
,取而代之将名字修改为 tf.global_variables_initializer()
可以减少对使用者的误导
1.4 变量作用域 variable scope
变量作用域,可以理解为变量起作用的地方,也就是这个变量在这个上下文中有效,这个变量是定义在这个空间之中。
我们用tf.variable_scope()
来创建一个变量作用域。在变量作用域中,我们可以重复使用已经创建好的变量,或者是创建一个新的变量(可以通过设置参数reuse
来做到)
1.4.1 tf.variable_scope
(name_or_scope, reuse=None, initializer=None)
一个简单的例子:
with tf.variable_scope('foo'):# 'foo/'
with tf.variable_scope('bar'): # 'foo/bar'
var = tf.get_variable('var', [1]) #'foo/bar/var:0'
assert var.name == 'foo/bar/var:0'
我们使用了assert
进行断言,运行例子,将不会抛出AssertionError
。
可以看到,我们在一个变量空间中创建一个变量时,变量名前面会加上当前所在的变量作作用域的前缀,并且我们看到,这个变量作用域是可以嵌套的
再看下面的例子:
with tf.variable_scope('foo'):
var = tf.get_variable('var', [1])
with tf.variable_scope('foo', reuse=True):
var = tf.get_variable('var')
with tf.variable_scope('foo', reuse=False):
var = tf.get_variable('var')
运行,将会看到在第6行,也就是reuse
为False
的变量作用域中,抛出了ValueError
,提示变量foo/var
已经存在。当reuse
为True
时,tf.get_variable
返回了上面已经在这个变量作用域中创建的变量var
;当reuse
为False
时,我们打算在这个变量作用域中创建一个相同的变量,因此抛出了错误。
参数列表:
参数名 | 说明 |
---|---|
name_or_scope | 一个名字(字符串)或者是一个已经存在的变量作用域的名字 |
reuse - tf.bool | True: 将重用已经创建的变量(例如,tf.get_variable将会返回已经存在的变量) False:将新建一个变量,即使这个变量名已经存在 |
initializer | 在这个变量作用域中创建变量的默认初始化器,一般不会用到 |
1.4.2 tf.get_variable
(name, shape=None, dtype=float32, initializer=None, trainable=True, collections=None)
这个方法会创建一个变量,或者是返回一个已经存在的变量(当reuse为True的时候)。
参数列表:
参数名 | 说明 |
---|---|
name | 一个名字(字符串) |
shape | 变量的唯独 |
dtype | 数据类型 |
initializer | 这个变量的初始化器,当我们打算运行一个计算图时,使用到这个变量之前进行初始化的时候用到 |
trainable | 如果为True,还会把这个变量添加到计算图的集合(graph collections)中,添加到集合:tf.GraphKeys.TRAINABLE_VARIABLES |
collections | 计算图集合的键(keys)的链表,例如指定局部变量集合:tf.GraphKeys.LOCAL_VARIABLES |
一般都会结合variable_scope
进行使用,联系前面的举的例子