【译】Effective TensorFlow Chapter3——理解变量域Scope以及什么时候应该使用它们

本文翻译自: 《Scopes and when to use them》, 若有侵权请联系删除,仅限于学术交流,请勿商用。若有谬误,请联系指出。python

在TensorFlow中,变量(Variables)和张量(tensors)有一个名字(name)属性,用于在符号图中标识它们。若是在建立变量或张量时未指定名称,TensorFlow会自动为您指定名称:git

a = tf.constant(1)
print(a.name)  # prints "Const:0"

b = tf.Variable(1)
print(b.name)  # prints "Variable:0"
复制代码

您能够经过显式指定来覆盖默认名称:github

a = tf.constant(1, name="a")
print(a.name)  # prints "a:0"

b = tf.Variable(1, name="b")
print(b.name)  # prints "b:0"
复制代码

TensorFlow引入了两个不一样的上下文管理器来改变张量和变量的名称。第一个是tf.name_scopebash

with tf.name_scope("scope"):
  a = tf.constant(1, name="a")
  print(a.name)  # prints "scope/a:0"

  b = tf.Variable(1, name="b")
  print(b.name)  # prints "scope/b:0"

  c = tf.get_variable(name="c", shape=[])
  print(c.name)  # prints "c:0"
复制代码

请注意,有两种方法能够在TensorFlow中定义新变量,一是建立tf.Variable对象或是调用tf.get_variable方法。使用新名称调用tf.get_variable会致使建立新变量,但若是存在具备相同名称的变量,则会引起ValueError异常,告诉咱们不容许从新声明变量。网络

tf.name_scope影响使用tf.Variable建立的张量和变量的名称,但不影响使用tf.get_variable建立的变量。函数

tf.name_scope不一样,tf.variable_scope也修改了使用tf.get_variable建立的变量的名称:ui

with tf.variable_scope("scope"):
  a = tf.constant(1, name="a")
  print(a.name)  # prints "scope/a:0"

  b = tf.Variable(1, name="b")
  print(b.name)  # prints "scope/b:0"

  c = tf.get_variable(name="c", shape=[])
  print(c.name)  # prints "scope/c:0"
with tf.variable_scope("scope"):
  a1 = tf.get_variable(name="a", shape=[])
  a2 = tf.get_variable(name="a", shape=[])  # Disallowed
复制代码

可是,若是咱们真的想要复用先前声明的变量呢?变量范围还提供了执行此操做的功能:spa

with tf.variable_scope("scope"):
  a1 = tf.get_variable(name="a", shape=[])
with tf.variable_scope("scope", reuse=True):
  a2 = tf.get_variable(name="a", shape=[])  # OK
复制代码

这在使用内置神经网络层时变得很方便:翻译

with tf.variable_scope('my_scope'):
  features1 = tf.layers.conv2d(image1, filters=32, kernel_size=3)
# Use the same convolution weights to process the second image:
with tf.variable_scope('my_scope', reuse=True):
  features2 = tf.layers.conv2d(image2, filters=32, kernel_size=3)
复制代码

或者,您能够将reuse属性设置为tf.AUTO_REUSE,这种操做告诉TensorFlow若是不存在具备相同名称的变量,就建立新变量,不然就复用:code

with tf.variable_scope("scope", reuse=tf.AUTO_REUSE):
  features1 = tf.layers.conv2d(image1, filters=32, kernel_size=3)
  
with tf.variable_scope("scope", reuse=tf.AUTO_REUSE):
  features2 = tf.layers.conv2d(image2, filters=32, kernel_size=3)
复制代码

若是你想共享不少变量,跟踪定义新变量以及复用这些变量的时候可能很麻烦且容易出错。tf.AUTO_REUSE则简化了此任务,但增长了共享不该共享的变量的风险。TensorFlow模板是解决这一问题的另外一种方法,它没有这种风险:

conv3x32 = tf.make_template("conv3x32", lambda x: tf.layers.conv2d(x, 32, 3))
features1 = conv3x32(image1)
features2 = conv3x32(image2)  # Will reuse the convolution weights.
复制代码

您能够将任何功能转换为TensorFlow模板。在第一次调用模板时,在函数内部定义的变量会被声明,而且在连续调用中,它们将被自动复用。

相关文章
相关标签/搜索