【问题标题】:TensorFlow stuck into endless loop using tf.while_loop()TensorFlow 使用 tf.while_loop() 陷入无限循环
【发布时间】:2016-10-28 11:05:55
【问题描述】:

重现步骤

我正在使用TensorFlow实现一个需要使用tf.while_loop()的网络

import tensorflow as tf
import numpy as np
class model(object):
    def __init__(self):
        self.argmax_ep_gate_array = [ tf.placeholder(tf.int32, [None]) for _ in range(10)]
        argmax_ep_gate_array_concat = tf.concat(0, self.argmax_ep_gate_array)
        story_len = tf.constant(7)
        starter = tf.constant(0)
        z = []
        def body(hops):
            hops = tf.add(hops,1)
            z.append(hops)
            return hops
        def condition(hops):
            return tf.logical_and(tf.less(tf.gather(argmax_ep_gate_array_concat, hops),story_len),tf.less(hops,tf.constant(20)))

        self.gate_index = tf.while_loop(condition,body,[starter])
        self.z=tf.concat(0,z)

    def step(self, sess):
        feed={}
        for i in range(10):
            feed[self.argmax_ep_gate_array[i].name]=[i]
        print (sess.run([self.gate_index,self.z],feed))
with tf.Session() as sess:
    while_loop = model()
    sess.run(tf.initialize_all_variables())
    while_loop.step(sess)

你有什么尝试?

我发现如果我想 sess.run() 任何未返回的 body() 变量,tensorflow 将陷入无限循环。 上面的例子是微不足道的,但它揭示了一些东西。在实际情况下,我使用 tf.while_loop() 运行一个包含 y= wx+b 类似的 RNN,但在 while 循环之后不会返回 wb。在前向网络中,它工作正常。但是,如果我运行反向传播,程序将陷入无限循环。我想上面的代码重现了我的问题,因为反向传播确实需要修改 wb。或者有什么办法可以处理这个问题?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    TL;DR:您不能存储在循环体中创建的张量以供以后使用,因为这会破坏有关循环结构的一些假设。

    一般来说,condition()body() 函数不能有副作用。 实际上,您的程序不太可能具有预期的行为:TensorFlow 将执行 body() 函数一次,以构建必要的图形结构,因此 z 在运行 @987654325 后将只包含一个元素@。

    相反,您必须在循环体中增量构造 z,使用 tf.concat() 并将值作为循环变量生成:

    starter = tf.constant(0)
    z_initial = tf.constant([], dtype=tf.int32)
    
    def body(hops, z_prev):
        hops = tf.add(hops, 1)
        z_next = tf.concat(0, [z_prev, tf.expand_dims(hops, 0)])
        return hops, z_next
    def condition(hops, z):
        return tf.logical_and(tf.less(tf.gather(
            argmax_ep_gate_array_concat, hops), story_len), tf.less(hops, tf.constant(20)))
    
    self.gate_index, self.z = tf.while_loop(condition,body,[starter, z_initial])
    

    【讨论】:

    • 谢谢。还有3个问题。 1. 如果self.z=tf.concat(0,z) 给出了Nonetype 之类的错误,或者只包含一个值,我可以接受结果,但在我的示例中,程序只是卡住了。 2. 我的body() 函数涉及许多可训练的参数,如权重、偏差、单元格。我是否需要将它们全部发送到body() 函数并返回它们? 3.cell是TensorFlow中的对象,如何将对象发送到body()
    • 1.是的,这很遗憾。找到一种方法来避免这个错误是值得的。 2. body() 函数可以从封闭范围内隐式捕获张量和变量,因此您可以使用这种机制将它们放入循环中。 3.我不确定你在说什么cell,但你可能也可以在这里使用隐式捕获。
    • 我似乎在使用这种方法时遇到了问题。前向传递很好,但是在尝试计算梯度时,似乎只看到一个值(最后一个)并且我收到此错误:ValueError: Shapes (24, 4, 65) and (1, 4, 65)不兼容。这是预期的吗?
    • @jstaker7,我能想到的两件事是:1. 确保您的条件函数至少成功运行一次; 2.检查您的身体功能并确保您的图表的完整性。希望这会有所帮助。
    • @mrry 我有同样的问题(从 gi​​thub 问题页面登陆这里)。我正在使用模拟组件 (mock.Mock()),会不会是这些东西起到了副作用的作用?
    猜你喜欢
    • 2020-05-13
    • 1970-01-01
    • 2013-03-17
    • 2021-02-15
    • 2022-01-23
    • 2021-01-23
    相关资源
    最近更新 更多