在TensorFlow中分配op:返回值是多少?

时间:2016-02-02 08:12:33

标签: python assign tensorflow

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

我假设这个op在类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

这是不推荐的操作吗?

2 个答案:

答案 0 :(得分:16)

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)
# ...

答案 1 :(得分:4)

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

  

分配完成后,此操作输出“ref”。这使得   更容易链接需要使用重置值的操作。

用简单的话来说,它需要你的原始张量和新的张量。它使用新值更新张量的原始值,并返回原始张量的参考值。