代码之家  ›  专栏  ›  技术社区  ›  AOK

为什么tensorflow tf.fifoqueue在下面的代码中很早就关闭了?

  •  0
  • AOK  · 技术社区  · 8 年前

    我正在尝试实现一个具有 enqueue 在后台运行 dequeue 在主线程中运行。

    目标是在循环中运行优化器,该优化器依赖于存储在缓冲区中的值,并且仅随优化过程中的每个步骤而更改。下面是一个简单的例子来说明:

    VarType = tf.int32
    
    data0 = np.array([1.0])
    
    init = tf.placeholder(VarType, [1])
    q = tf.FIFOQueue(capacity=1, shapes=[1], dtypes=VarType)
    nq_init = q.enqueue(init)
    # I use a Variable intermediary because I will want to access the
    # data multiple times, but I do not want the next data point in the
    # queue until I initialize the variable again.
    data_ = tf.Variable(q.dequeue(), trainable=False, collections=[])
    
    # Notice that data_ is accessed twice, but should be the same
    # in a single sess.run
    # so "data_ = q.dequeue()" would not be correct
    # plus there needs to be access to initial data
    data1 = data_ + 1
    data2 = data_ * data1
    qr = tf.train.QueueRunner(q, [q.enqueue(data2)] * 1)
    tf.train.add_queue_runner(qr)
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(coord=coord)
    
        sess.run(nq_init, feed_dict={init:data0})
        # this first initialization works fine
        sess.run(data_.initializer)
        for n in range(10):
            print(sess.run(data2))
            # this second initialization errors out: 
            sess.run(data_.initializer)
    
        coord.request_stop()
        coord.join(threads)
    
    print('Done')
    

    这段代码出错,错误如下:

    outofrangeerror(有关回溯,请参阅上面的内容):fifo queue''u0'fifo'u queue'已关闭,并且元素不足(请求的1,当前大小0)

    为什么,这是怎么解决的?

    1 回复  |  直到 8 年前
        1
  •  0
  •   AOK    8 年前

    所以我找到了“如何修复”的部分,但没有找到原因。

    似乎第一个排队/出列必须在第二个排队/出列放入queue\u runners集合之前运行,但是有一个警告,我们需要运行 sess.run(data_.initializer) 两次:

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        sess.run(nq_init, feed_dict={init:data0})
        sess.run(data_.initializer)
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(coord=coord)
    
        for n in range(10):
            print(sess.run(data2))
            sess.run(data_.initializer)
            sess.run(data_.initializer)
    
        coord.request_stop()
        coord.join(threads)
    

    产出如预期:

    [2]; [6]; [42];...
    

    如果没有这两个电话,我会得到以下信息:

    [2]; [6]; [6]; [42];...
    

    我怀疑 q.enqueue 有自己的缓冲区来保存旧的 data2 ,所以必须调用两次。这也适用于第一个值不重复,因为此时第二个值 排队 仍然是空的。不知道如何克服这个怪癖。

    推荐文章