Python multiprocessing.Pool无法pickle mxnet.mod.Module对象

时间:2018-05-15 06:11:00

标签: python mxnet

这里大概是我做的:

import mxnet as mx
import cv2
from multiprocessing import Pool
from itertools import repeat

num_worker=4
CNNNet=[]
img = cv2.imread('../datasets/1.jpg')
sym, arg_params, aux_params = mx.model.load_checkpoint('det1', 0)
for i in range(num_worker):
    worker_net = mx.mod.Module(symbol=sym,label_names=None)
    worker_net.bind(data_shapes=[('data', (1, 3, 1000, 1000))],for_training=False)
    worker_net.set_params(arg_params,aux_params)
    CNNNet.append(worker_net)
pool = Pool(num_worker)
threshold = 0.6
res = pool.map(do_work_warpper,zip(repeat(img),CNNNet[:num_worker],repeat(threshold)))

do_work_warpper()函数是:

def do_work_warpper(args):
    return do_work(*args)
def do_work(img,net,threshold):
    #do image predict job here
    return res

我对multiprocessing.Poolmx.mod.Module对象一起使用的问题感到困惑,我在python3.6中得到错误:

TypeError: can't pickle module objects

或在python2.7中:

PicklingError: Can't pickle <type 'module'>: attribute lookup __builtin__.module failed

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:0)

您获得此异常的原因是因为multiprocessing需要能够pickle传递给您的工作人员的变量,以便在它产生的各种进程之间传递它们。

错误:

TypeError: can't pickle module objects

建议您传递给Pool的其中一个变量包含一个模块(或一个以模块作为属性的类)。

要演示此问题,请查看以下两个类:

import os

class Pickable: 
    a = 1

class UnPickable:
    def __init__(self):
        self.mod = os

如果您尝试挑选这两个类的实例,您将获得:

In [11]: pickle.dumps(Pickable())
Out[11]: b'\x80\x03c__main__\nPickable\nq\x00)\x81q\x01.'

In [10]: pickle.dumps(UnPickable())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-7d4d725a1c6d> in <module>()
----> 1 pickle.dumps(UnPickable())

TypeError: can't pickle module objects

话虽如此 - 你要么创建自己的类来模仿mx.mod.Module的功能,但是可序列化 - 或者(在我看来更好的解决方案)使用简单的python-builtin类型将变量传递给你的{ {1}}并在其中构建Pool个实例。