前文Name Scope vs Variable Scope in TensorFlow比较了作用域variable_scopename_scope在TensorFlow中如何共享变量,但是它们需要分别和tf.get_variabletf.Variable搭配使用。一般情况下,tf.variable_scopetf.get_variable和搭配使用,tf.name_scopetf.Variable搭配使用。

但是tf.Variable()tf.get_variable()两个方法都可以创建变量[在TensorFlow v1.x中],不过它们还是有区别:

tf.Variable()要求必须指定初始化值,但是可以不指定name。tf.get_variable()可以用各种初始化方法,不用明确指定值,但是必须显式的制定name。这是因为,tf.Variable()每次都在创建新的对象,都会给一个新的name[如果检测到命名冲突,系统会自己处理],所以指定不指定name没有关系,但是一定要明确初始化值。相反,tf.get_variable()的本质目的获得变量而不是创建变量[虽然在没有找到的时候也会创建一个],对于已经创建的同样name的变量对象,就直接获得那个变量对象[类似于共享变量],tf.get_variable()会检查当前命名空间下是否存在同样name的变量[系统不会处理冲突,而会报错],可以方便共享变量,所以name在tf.get_variable()里就格外重要。

import tensorflow as tf
w_1 = tf.Variable(3,name="w_1")
w_2 = tf.Variable(1,name="w_1")
print w_1.name
print w_2.name
#Output:
#w_1:0
#w_1_1:0

import tensorflow as tf
w_1 = tf.get_variable(name="w_1",initializer=1)
w_2 = tf.get_variable(name="w_1",initializer=2)
#Error:
#ValueError: Variable w_1 already exists, disallowed. Did
#you mean to set reuse=True in VarScope?

总体来说,更推荐使用tf.get_variable(),因为:

  1. 当变量名称重复,系统不会处理冲突,而会显式报错,这有可能避免一些隐藏bug。
  2. 因为tf.get_variable()会检查当前命名空间下是否存在同样name的变量,可以方便共享变量。而tf.Variable每次都会新建一个变量。
  3. tf.get_variable()不需要指定初始值,而只要指定初始化方法,比如xavier_initializer