Tensorflow有一套完善的变量管理机制,能够让开发者在使用时条理清晰。
1. Variable & get_variable:
下面两个对v的定义是等价的。
import tensorflow as tf
v = tf.Variable(tf.constant(1.0,shape=[1]),name='v')
v = tf.get_variable('v',shape=[1],initializer=tf.constant_initializer(1.0))
get_variable 中,name 是必须要初始化的,而且命名必须是唯一(变量管理更加严格):
v = tf.get_variable('v',shape=[1,2],initializer=tf.truncated_normal_initializer(stddev=0.1))
#则执行下面语句会报错
v1 = tf.get_variable('v',shape=[1,2],initializer=tf.constant_initializer([1.0,2.0])))
尽管v与v1变量名不同,并且初始化方式也不同,但依然报错:variable already exists. 原因是v和v1被命名为'v';
但是使用Variable定义却不会有问题。
v = tf.Variable(tf.constant([1.0,2.0]),name='v')
v1 = tf.Variable(tf.constant([1.0,2.0]),name='v')
#以上语句不会报错。
上面说到,使用get_variable时,如果两个变量的name如果相同,则会报错;但是我们如果使用 variable_scope 来定义命名空间,在不同命名空间中,可以使用get_variable定义name相同的变量。
with tf.variable_scope('A'):
v = tf.get_variable('v',[2,2],initializer=tf.truncated_normal_initializer(stddev=0.1,seed=1))
with tf.variable_scope('B'):
v1 = tf.get_variable('v',[2,3],initializer=tf.truncated_normal_initializer(stddev=0.1,seed=2))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print (sess.run(v))
print (sess.run(v1))
如上,定义了“A”,“B”两个命名空间,v和v1的name都为“v”,在使用时不会报错。
另外,命名空间还可以用来赋值:
with tf.variable_scope('A'):
v = tf.get_variable('v',[2,2],initializer=tf.truncated_normal_initializer(stddev=0.1,seed=1))
with tf.variable_scope('B'):
v1 = tf.get_variable('v',[2,3],initializer=tf.truncated_normal_initializer(stddev=0.1,seed=2))
with tf.variable_scope('A',reuse=True):
v2 = tf.get_variable('v',[2,2])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print (sess.run(v))
print (sess.run(v1))
print (sess.run(v2))
如上,在variable_scope中将参数reuse初始化为True,则可以将v2赋值为v。若命名空间中不存在"v",则v2按照默认初始化。