Python 如何将joblib并行化与不使用';我什么也不退
我目前正试图在pythonPython 如何将joblib并行化与不使用';我什么也不退,python,multithreading,scikit-learn,parallel-processing,joblib,Python,Multithreading,Scikit Learn,Parallel Processing,Joblib,我目前正试图在python3.8.3中使用joblib实现一个并行for循环 在for循环中,我想对一个类的实例应用一个类方法,同时对另一个类应用一个方法。 这是一个MWE,我做了尝试,看看我的想法是否有效,但它没有。有人知道如何让它工作吗 from joblib import Parallel, delayed class A(): def __init__(self): self.val = 0 def add5(self): self.va
3.8.3
中使用joblib
实现一个并行for
循环
在for循环中,我想对一个类的实例应用一个类方法,同时对另一个类应用一个方法。
这是一个MWE,我做了尝试,看看我的想法是否有效,但它没有。有人知道如何让它工作吗
from joblib import Parallel, delayed
class A():
def __init__(self):
self.val = 0
def add5(self):
self.val += 5
class B():
def __init__(self):
self.obj = [A() for _ in range(10)]
def apply(self):
""" this is where I'm trying to use joblib:
for a in self.obj:
a.add5()"""
def f(x):
x.add5()
Parallel(n_jobs=-1)(delayed(f)(x) for x in self.obj)
def prnt(self):
print([a.val for a in self.obj])
b = B()
b.prnt() # returns [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
b.apply()
b.prnt() # returns [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] but
# I expect [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
我的问题还有一些背景:我正在使用sci kit learn实现一个boosting算法,在应用该算法之前生成弱学习者。拟合和预测是在for循环中完成的,可能需要一些时间,因此我想添加并行化以尝试加快进度。基本上,A类
是一个分类器,B类
是我的算法,我想在这里适应我生成的所有分类器。从()可以看出:
joblib的默认后端将以独立的方式运行每个函数调用
Python进程,因此它们不能变异一个公共Python对象
在主程序中定义
然而,如果并行功能真的需要依赖共享
线程的内存语义,应该使用
require='sharedmem',例如:
因此,您有两个选择:1)将require='sharedmem'
添加到您的Parallel
中,用于:
Parallel(n_jobs=-1, require='sharedmem')(delayed(f)(x) for x in self.obj)
然而,他指出:
请记住,依赖共享内存语义可能是错误的
从性能角度来看,次优作为对
共享Python对象将遭受锁争用
在2)选项中,您必须更改代码中的两个内容
首先将f
功能更改为:
def f(x):
x.add5()
返回对象
def f(x):
x.add5()
return x
在并行循环中
,更改为:
Parallel(n_jobs=-1)(delayed(f)(x) for x in self.obj)
进入:
这样您就可以将self.obj
分配给并行循环返回的列表
最终代码:
from joblib import Parallel, delayed
class A:
def __init__(self):
self.val = 0
def add5(self):
self.val += 5
class B:
def __init__(self):
self.obj = [A() for _ in range(10)]
def apply(self):
""" this is where I'm trying to use joblib:
for a in self.obj:
a.add5()"""
def f(x):
x.add5()
return x
self.obj = Parallel(n_jobs=-1)(delayed(f)(x) for x in self.obj)
def prnt(self):
print([a.val for a in self.obj])
b = B()
b.prnt() # returns [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
b.apply()
b.prnt() # returns [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] but
# I expect [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
嘿,非常感谢,标记为已回答。第二个选项是我实现的,它就像一个符咒!
from joblib import Parallel, delayed
class A:
def __init__(self):
self.val = 0
def add5(self):
self.val += 5
class B:
def __init__(self):
self.obj = [A() for _ in range(10)]
def apply(self):
""" this is where I'm trying to use joblib:
for a in self.obj:
a.add5()"""
def f(x):
x.add5()
return x
self.obj = Parallel(n_jobs=-1)(delayed(f)(x) for x in self.obj)
def prnt(self):
print([a.val for a in self.obj])
b = B()
b.prnt() # returns [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
b.apply()
b.prnt() # returns [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] but
# I expect [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]