【问题标题】:TensorFlow while_loop converts variable to constant?TensorFlow while_loop 将变量转换为常量?
【发布时间】:2017-07-04 18:15:41
【问题描述】:

我正在尝试更新嵌套 while_loop() 中的二维张量。但是,当将变量传递给第二个循环时,我无法使用 tf.assign() 对其进行更新,因为它会引发此错误:

ValueError: Sliced assignment is only supported for variables

如果我在 while_loop 之外创建变量并仅在第一个循环中使用它,它会以某种方式正常工作。

如何在第二个 while 循环中修改我的 2D tf 变量?
(我使用的是 python 2.7 和 TensorFlow 1.2)

我的代码:

import tensorflow as tf
import numpy as np

tf.reset_default_graph()

BATCH_SIZE = 10
LENGTH_MAX_OUTPUT = 31

it_batch_nr = tf.constant(0)
it_row_nr = tf.Variable(0, dtype=tf.int32)
it_col_nr = tf.constant(0)
cost = tf.constant(0)

it_batch_end = lambda it_batch_nr, cost: tf.less(it_batch_nr, BATCH_SIZE)
it_row_end = lambda it_row_nr, cost_matrix: tf.less(it_row_nr, LENGTH_MAX_OUTPUT+1)

def iterate_batch(it_batch_nr, cost):
    cost_matrix = tf.Variable(np.ones((LENGTH_MAX_OUTPUT+1, LENGTH_MAX_OUTPUT+1)), dtype=tf.float32)
    it_rows, cost_matrix = tf.while_loop(it_row_end, iterate_row, [it_row_nr, cost_matrix])
    cost = cost_matrix[0,0] # IS 1.0, SHOULD BE 100.0
    return tf.add(it_batch_nr,1), cost

def iterate_row(it_row_nr, cost_matrix):
    # THIS THROWS AN ERROR:
    cost_matrix[0,0].assign(100.0)
    return tf.add(it_row_nr,1), cost_matrix

it_batch = tf.while_loop(it_batch_end, iterate_batch, [it_batch_nr, cost])

sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
out = sess.run(it_batch)
print(out)

【问题讨论】:

  • 请将您的解决方案作为答案而不是对问题的编辑,您可以在revisions 3 中找到您的解决方案,只需将其复制并粘贴到答案中即可

标签: python python-2.7 tensorflow


【解决方案1】:

tf.Variable 对象不能用作 while 循环中的循环变量,因为循环变量的实现方式不同。

因此,要么在循环外创建变量并在每次迭代中使用 tf.assign 自行更新它,要么像使用循环变量一样手动跟踪更新(通过从循环 lambdas 中返回它们的更新值,在你的情况下使用来自内部循环的值作为外部循环的新值)。

【讨论】:

  • 谢谢,这消除了错误。但是,如果我将 cost_matrix 变量声明移到循环之外,并将其从循环变量中删除,cost 仍然是 1.0,而我希望它是 100.0
  • 显然我没有意识到输出变量必须使用该操作才能运行。我认为这与 TF 解释和优化代码的方式有关。我使用了一个 hacky 解决方案来克服这个问题,但我认为有更好的方法来做到这一点(参见问题中的编辑)。将就此提出一个新问题。
  • 更新:触发要运行的操作可以使用tf.control_dependencies() 完成(更新的工作解决方案)。
【解决方案2】:

在@AlexandrePassos 的帮助下,将变量放在while_loop 之外,让它工作。但是,我还必须使用tf.control_dependencies() 强制执行命令(因为这些操作不直接用于循环变量)。循环现在看起来像这样:

cost_matrix = tf.Variable(np.ones((LENGTH_MAX_OUTPUT+1, LENGTH_MAX_OUTPUT+1)), dtype=tf.float32)

def iterate_batch(it_batch_nr, cost):
    it_rows = tf.while_loop(it_row_end, iterate_row, [it_row_nr])
    with tf.control_dependencies([it_rows]):
        cost = cost_matrix[0,0] 
        return tf.add(it_batch_nr,1), cost

def iterate_row(it_row_nr):
    a = tf.assign(cost_matrix[0,0], 100.0)
    with tf.control_dependencies([a]):
        return tf.add(it_row_nr,1)

【讨论】:

    猜你喜欢
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    相关资源
    最近更新 更多