【问题标题】:Assign op in TensorFlow: what is the return value?在 TensorFlow 中分配 op:返回值是多少?
【发布时间】:2016-05-10 22:37:05
【问题描述】:

我试图在 TensorFlow 中构建一个自动增量图。我认为assign 操作可能适用于此,但没有找到它的文档。

我假设这个操作返回它的值——就像在类 C 语言中一样——并编写了以下代码:

import tensorflow as tf

counter = tf.Variable(0, name="counter")

one = tf.constant(1)
ten = tf.constant(10)

new_counter = tf.add(counter, one)
assign = tf.assign(counter, new_counter)
result = tf.add(assign, ten)

init_op = tf.initialize_all_variables()

with tf.Session() as sess:

  sess.run(init_op)

  for _ in range(3):

    print sess.run(result)

这段代码有效。

问题是:这是预期的行为吗?为什么这里没有记录分配操作:https://www.tensorflow.org/versions/0.6.0/api_docs/index.html

这是一个不推荐的操作吗?

【问题讨论】:

    标签: python assign tensorflow


    【解决方案1】:

    tf.assign()documented in the latest versions 很好,在项目中经常使用。

    这个操作在赋值完成后输出“ref”。这使得 更容易链接需要使用重置值的操作。

    简单地说,它需要你原来的张量和一个新的张量。它使用新值更新张量的原始值并返回原始张量的引用。

    【讨论】:

      【解决方案2】:

      tf.assign() 运算符是实现Variable.assign() 方法的底层机制。它接受一个可变张量(类型为tf.*_ref)和一个新值,并返回一个已用新值更新的可变张量。提供返回值是为了更容易在后续读取之前对分配进行排序,但此功能没有很好的文档记录。一个例子有望说明:

      v = tf.Variable(0)
      new_v = v.assign(10)
      output = v + 5  # `v` is evaluated before or after the assignment.
      
      sess.run(v.initializer)
      
      result, _ = sess.run([output, new_v.op])
      print result  # ==> 10 or 15, depending on the order of execution.
      

      v = tf.Variable(0)
      new_v = v.assign(10)
      output = new_v + 5  # `new_v` is evaluated after the assignment.
      
      sess.run(v.initializer)
      
      result = sess.run([output])
      print result  # ==> 15
      

      在您的代码示例中,数据流依赖项强制执行[read counter] -> new_counter = tf.add(...) -> tf.assign(...) -> [read output of assign] -> result = tf.add(...) 的顺序,这意味着语义是明确的。 但是,更新计数器的读取-修改-写入步骤效率较低,并且在同时运行多个步骤时可能会出现意外行为。例如,访问同一个变量的多个线程可以观察到计数器向后移动(在较旧值在较新值之后写回的情况下)。

      我建议你使用Variable.assign_add()来更新计数器,如下:

      counter = tf.Variable(0, name="counter")
      
      one = tf.constant(1)
      ten = tf.constant(10)
      
      # assign_add ensures that the counter always moves forward.
      updated_counter = counter.assign_add(one, use_locking=True)
      
      result = tf.add(updated_counter, ten)
      # ...
      

      【讨论】:

      • 我们运行第一个代码sn-p,我们只观察到输出只能是5或15。
      • 谢谢,这阐明了 tensorflow 是如何做分配的,这似乎与 Theano 是如何做的有点不同。还有一种方法可以安全地引用 before 更新的值吗?在上面的示例中,我希望结果为 5,同时在通话后仍将 v 更新为 10。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      • 2017-01-06
      • 2010-12-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2013-09-18
      相关资源
      最近更新 更多