TensorFlow提供Variable Scope机制来控制变量的作用域,一定程度上类似于C++中的namespace,使得相同名称的变量可以同时存在。
tf.variable_scope(<scope_name>)
tf.name_scope(<scope_name>)
tf.get_variable(name, shape=None, dtype=None, initializer=None, regularizer=None,
trainable=True, collections=None, caching_device=None, partitioner=None, validate_shape=True,
custom_getter=None)
tf.Variable(initial_value=None, trainable=True, collections=None, validate_shape=True,
caching_device=None, name=None, variable_def=None, dtype=None, expected_shape=None,
import_scope=None)
如下所示,conv_block中创建了weights和biases两个变量。
def conv_block(input, kernel_shape, bias_shape):
weights = tf.get_variable("weights", kernel_shape,
initializer=tf.random_normal_initializer())
biases = tf.get_variable("biases", bias_shape,
initializer=tf.constant_initializer(0.0))
conv = tf.nn.conv2d(input, weights,
strides=[1, 1, 1, 1], padding='SAME')
return tf.nn.relu(conv + biases)
当使用多个conv_block时,可以使用variable_scope区分不同的作用域。
with tf.variable_scope("conv1"):
conv1 = conv_block(input, [5, 5, 32, 32], [32])
with tf.variable_scope("conv2")
conv2 = conv_block(conv1, [5, 5, 32, 32], [32])
通过variable_scope创建conv1/weights, conv1/biases, conv2/weights, conv2/biases变量。
当需要复用变量时,调用函数reuse_variables()。
with tf.variable_scope("conv1") as conv1_scope:
conv1 = conv_block(input, [5, 5, 32, 32], [32])
conv1_scope.reuse_variables()
conv2 = conv_block(conv1, [5, 5, 32, 32], [32])
当tf.get_variable_scope().reuse == False,调用该函数会创建新的变量
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
assert v.name == "foo/v:0"
当tf.get_variable_scope().reuse == True,调用该函数会重用已经创建的变量
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
with tf.variable_scope("foo", reuse=True):
v1 = tf.get_variable("v", [1])
assert v1 is v
tf.variable_scope适用于tf.get_variable或者tf.Variable生成的变量;
tf.name_scope具有类似的功能,但只限于tf.Variable生成的变量。