使用多处理从多个进程中排队tf.RandomShuffleQueue

时间:2017-05-10 10:32:27

标签: python tensorflow multiprocessing

我想使用多个进程(not threads)进行一些预处理,并将结果排入tf.RandomShuffleQueue,我的主图可以将其用于训练。

有办法吗?

我的实际问题

我已将我的数据集转换为分割为256个分片的TFRecords。我想使用multiprocessing启动20个进程,并让每个进程处理一系列分片。每个进程都应该读取图像,然后对它们进行扩充并将它们推入tf.RandomShuffleQueue,从中可以将输入提供给图形进行训练。

有些人建议我浏览inception中的tensorflow示例。但是,这是一种非常不同的情况,因为只有数据分片的读取是由多个线程(not processes)完成的,而预处理(例如 - 扩充)是在主线程中进行的。

3 个答案:

答案 0 :(得分:1)

  

评论:TFRecords的腌制并不重要。   我可以传递一个包含分片TFRecord文件范围名称的列表列表。

我必须重新启动决策流程!

  

评论:我可以将它作为参数传递给Pool.map()。

验证,如果multiprocesing.Queue()可以处理此问题 张量函数的结果是Tensor object 请尝试以下方法:

tensor_object = func(TFRecord)
q = multiprocessing.Manager().Queue()
q.put(tensor_object)
data = q.get()
print(data)
  

评论:如何确保所有进程都排入同一队列?

这很简单enqueue来自Pool.map(...的结果 毕竟process完成了。
另外,我们可以{strong}全部 enqueue queueing并行,processes数据。

但这样做取决于 pickleabel 数据,如上所述。

例如:

import multiprocessing as mp
def func(filename):
    TFRecord = read(filename)
    tensor_obj = tf.func(TFRecord)
    return tensor_obj

def main_Tensor(tensor_objs):
    tf = # ... instantiat Tensor Session
    rsq = tf.RandomShuffleQueue(...)
    for t in tensor_objs:
        rsq.enqueue(t)

if __name__ == '__main__':
    sharded_TFRecords = ['file1', 'file2']
    with mp.Pool(20) as pool:
        tensor_objs = pool.map(func, sharded_TFRecords)
        pool.join()

    main_Tensor(tensor_objs)

答案 1 :(得分:1)

这旨在解决您的实际问题

在另一个主题中,有人告诉你Python拥有全局解释器锁(GIL),因此除非你使用多个进程,否则多核没有速度优势。

这可能促使您希望使用multiprocessing

然而,对于TF,Python通常仅用于构造"图形"。实际执行发生在本机代码(或GPU)中,其中GIL不起任何作用。

鉴于此,我建议简单地让TF使用多线程。这可以使用intra_op_parallelism_threads参数控制,例如:

with tf.Session(graph=graph, 
    config=tf.ConfigProto(allow_soft_placement=True, 
    intra_op_parallelism_threads=20)) as sess:
    # ...

(旁注:如果你有一个2-CPU,32核系统,最好的参数很可能是intra_op_parallelism_threads=16,具体取决于很多因素)

答案 2 :(得分:0)

使用TF运行multiprocessing的推荐方法似乎是为每个孩子创建一个单独的tf.Session,因为跨进程共享它是不可行的。

你可以看看this example,我希望它有所帮助。

[编辑:旧答案]

您可以使用multiprocessing.Pool并依靠其回调机制在结果准备好后立即将结果放入tf.RandomShuffleQueue

这是一个非常简单的例子,说明如何做到这一点。

from multiprocessing import Pool


class Processor(object):
    def __init__(self, random_shuffle_queue):
        self.queue = random_shuffle_queue
        self.pool = Pool()

    def schedule_task(self, task):
        self.pool.apply_async(processing_function, args=[task], callback=self.task_done)

    def task_done(self, results):
        self.queue.enqueue(results)

这假定Python 2,对于Python 3,我建议使用concurrent.futures.ProcessPoolExecutor