张量流:变量赋值何时完成sess.运行有单子吗?

2024-06-01 03:51:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我认为变量赋值是在列表中的所有操作之后完成的sess.运行,但以下代码在不同的执行过程中返回不同的结果。它似乎随机运行列表中的操作,并在运行列表中的操作之后分配变量。在

a = tf.Variable(0)
b = tf.Variable(1)
c = tf.Variable(1)
update_a = tf.assign(a, b + c)
update_b = tf.assign(b, c + a)
update_c = tf.assign(c, a + b)

with tf.Session() as sess:
  sess.run(initialize_all_variables)
  for i in range(5):
    a_, b_, c_ = sess.run([update_a, update_b, update_c])

我想知道变量赋值的时间。 以下是正确的:“update_x->;assign x->。。。->;udpate_z->;assign z“或“update_x->;udpate_y->;udpate_z->;assign a,b,c”?(其中(x,y,z)是(a,b,c)的置换) 另外,如果有实现后一个任务的方法(在列表中的所有操作完成后完成任务),请告诉我如何实现它。在


Tags: run代码gt列表过程sessiontfas
2条回答

根据你的这个例子

v = tf.Variable(0)
c = tf.constant(3)
add = tf.add(v, c)
update = tf.assign(v, add)
mul = tf.mul(add, update)

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    res = sess.run([mul, mul])
    print(res)

输出:[9,9]

你得到[9, 9],这实际上是我们要求它做的。这样想:

在运行期间,一旦从列表中取出mul,它就会查找这个的定义并找到tf.mul(add, update)。现在,它需要add的值,这将导致tf.add(v, c)。因此,它插入vc,得到{}的值为3。在

现在我们需要update的值,它被定义为tf.assign(v, add)。我们有两个值add(它刚才计算为3)&v。因此,它将v的值更新为3,这也是update的值。在

现在,add和{}的值都是3。因此,乘法得到mul中的9。在

根据我们得到的结果,我认为,对于列表中的下一项(操作),它只返回刚刚计算的值mul。我不确定它是再次执行这些步骤还是返回相同的(缓存?)为mul计算的值,它意识到我们得到了结果,或者这些操作是并行进行的(对于列表中的每个元素)。也许@mry或@YaroslavBulatov可以对这一部分发表评论吗?在


引用@mry的评论:

When you call sess.run([x, y, z]) once, TensorFlow executes each op that those tensors depend on one time only (unless there's a tf.while_loop() in your graph). If a tensor appears twice in the list (like mul in your example), TensorFlow will execute it once and return two copies of the result. To run the assignment more than once, you must either call sess.run() multiple times, or use tf.while_loop() to put a loop in your graph.

三个操作update_aupdate_b,和{}在数据流图中没有相互依赖关系,因此TensorFlow可以选择以任何顺序执行它们。(在当前的实现中,这三个变量可能在不同的线程上并行执行。)第二个要点是默认情况下缓存变量的读取,因此在程序中,update_b(即c + a)中分配的值可以使用a的原始值或更新值,取决于首次读取变量的时间。在

如果要确保操作按特定顺序发生,可以使用^{}块来强制在块中创建的操作发生在列表中命名的操作之后。您可以在with tf.control_dependencies([...]):块中使用^{}使变量的读取点显式。在

因此,要确保update_a发生在update_b之前,update_b发生在update_c之前,可以执行以下操作:

update_a = tf.assign(a, b + c)

with tf.control_dependencies([update_a]):
  update_b = tf.assign(b, c + a.read_value())

with tf.control_dependencies([update_b]):
  update_c = tf.assign(c, a.read_value() + b.read_value())

相关问题 更多 >