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

Dim*_*ims 9 python assign tensorflow

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

我假设这个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)
Run Code Online (Sandbox Code Playgroud)

这段代码有效.

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

这是非推荐的操作吗?

mrr*_*rry 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.
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

在您的代码示例中,数据流依赖关系强制执行顺序[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)
# ...
Run Code Online (Sandbox Code Playgroud)

  • 我们运行第一个代码片段,我们只观察到输出只能是5或15. (4认同)