在 TensorFlow 中分配操作:返回值是什么? [英] Assign op in TensorFlow: what is the return value?

查看:29
本文介绍了在 TensorFlow 中分配操作:返回值是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was trying to build an autoincrementing graph in TensorFlow. I thought that the assign op might be suitable for that, but found no documentation for it.

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

I assumed that this op returns its value—like in C-like languages—and wrote the following code:

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

The question is: is this the expected behavior? Why is the assign op not documented here: https://www.tensorflow.org/versions/0.6.0/api_docs/index.html

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

Is it a non-recommended op?

推荐答案

tf.assign() 操作符是实现 Variable.assign() 方法.它接受一个可变张量(具有tf.*_ref 类型)和一个新值,并返回一个可变张量,该张量已更新为新值.提供返回值是为了在后续读取之前更轻松地对赋值进行排序,但此功能没有很好的文档记录.一个例子有望说明:

The tf.assign() operator is the underlying mechanism that implements the Variable.assign() method. It takes a mutable tensor (with tf.*_ref type) and a new value, and returns a mutable tensor that has been updated with the new value. The return value is provided to make it easier to order an assignment before a subsequent read, but this feature is not well documented. An example will hopefully illustrate:

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(...) ->[读取赋值的输出] ->result = tf.add(...),这意味着语义是明确的.然而,用于更新计数器的读取-修改-写入步骤有些低效,并且当多个步骤同时运行时可能会出现意外行为.例如,访问同一个变量的多个线程可以观察到计数器向后移动(在较新值之后写回旧值的情况下).

In your code example the dataflow dependencies enforce the order of execution [read counter] -> new_counter = tf.add(...) -> tf.assign(...) -> [read output of assign] -> result = tf.add(...), which means that the semantics are unambiguous. However, the read-modify-write steps to update the counter are somewhat inefficient, and can have unexpected behavior when there are multiple steps running concurrently. For example, multiple threads accessing the same variable could observe the counter moving backwards (in the case that an older value was written back after a newer value).

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

I would recommend that you use Variable.assign_add() to update the counter, as follows:

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

这篇关于在 TensorFlow 中分配操作:返回值是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆