我想使用多个进程(not threads
)进行一些预处理,并将结果排入tf.RandomShuffleQueue,我的主图可以将其用于训练。
有办法吗?
我已将我的数据集转换为分割为256个分片的TFRecords。我想使用multiprocessing
启动20个进程,并让每个进程处理一系列分片。每个进程都应该读取图像,然后对它们进行扩充并将它们推入tf.RandomShuffleQueue
,从中可以将输入提供给图形进行训练。
有些人建议我浏览inception
中的tensorflow
示例。但是,这是一种非常不同的情况,因为只有数据分片的读取是由多个线程(not processes
)完成的,而预处理(例如 - 扩充)是在主线程中进行的。
答案 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
。