TensorFlow队列运行器如何工作?

时间:2017-06-18 10:57:09

标签: multithreading tensorflow queue

我想了解Queue Runners的工作原理。我知道队列运行器用于更有效地填充队列,并行运行几个入队线程。但结果队列是怎样的?究竟发生了什么?

让我更具体地提出我的问题: 我有许多文件,其内容我想放在一个大队列中。

文件1:A,B,C

文件2:D,E,F

文件3:G,H,I

我关注TensorFlow input pipeline。我首先创建一个文件名列表,然后创建一个使用tf.string_input_producer()的文件名队列,一个阅读器操作和一个解码器。最后,我想将我的序列化示例放入一个可以与图形共享的示例队列中。为此,我使用QueueRunner:

qr = tf.train.QueueRunner(queue, [enqueue_op] * numberOfThreads)

我将它添加到QUEUE_RUNNERS集合中:

tf.train.add_queue_runner(qr)

我的enqueue_op一次排队一个例子。所以,当我使用例如numberOfThreads = 2,结果队列如何?文件以哪种顺序读入队列?例如,队列是否类似于

q = [A, B, C, D, E, F, G, H, I](所以尽管并行处理,文件内容没有在队列中混合)

或者队列看起来像是

q = [A, D, B, E, C, F, G, H, I]

def get_batch(file_list, batch_size, input_size,
                     num_enqueuing_threads):

    file_queue = tf.train.string_input_producer(file_list) 


    reader = tf.TFRecordReader() 

    _, serialized_example = reader.read(file_queue) 

    sequence_features = {
      'inputs': tf.FixedLenSequenceFeature(shape=[input_size],
                                       dtype=tf.float32),
      'labels': tf.FixedLenSequenceFeature(shape=[],
                                       dtype=tf.int64)}


    _, sequence = tf.parse_single_sequence_example(
      serialized_example, sequence_features=sequence_features)

    length = tf.shape(sequence['inputs'])[0]


    queue = tf.PaddingFIFOQueue(
      capacity=1000,
      dtypes=[tf.float32, tf.int64, tf.int32],
      shapes=[(None, input_size), (None,), ()])

    enqueue_ops = [queue.enqueue([sequence['inputs'],
                            sequence['labels'],
                            length])] * num_enqueuing_threads


    tf.train.add_queue_runner(tf.train.QueueRunner(queue, enqueue_ops))

    return queue.dequeue_many(batch_size)

1 个答案:

答案 0 :(得分:0)

我实际上发现您提到的同一页面的animated figure非常具有说明性。

有一个第一个队列,即文件名队列,它提供文件读取线程。在每个线程中,文件按顺序读取 - 或者更确切地说,根据读者遵循的顺序读取。这些线程中的每一个都提供另一个队列,即示例队列,其输出将由您的训练消耗。

在您的问题中,您对示例队列中示例的结果顺序感兴趣。

答案取决于读者的工作方式。最佳实践和最有效的方法(在上面的动画图中说明)是在准备好后立即将样本发送到示例队列。此流式传输功能通常由various Reader variants proposed by tensorflow提供,以促进和简化此最佳做法。但是,当然可以编写一个能够在结束时同时enqueue_many所有样本的阅读器。

在所有情况下,由于读者处于单独的非同步线程中,因此您无法按其各自输出的顺序进行任何保证。例如,在标准的流式传输案例中,示例可以定期交错,也可以不交错 - 实际上任何事情都可能发生。