我正在尝试使用joblib并行创建自定义随机林实施列。
这项任务令人尴尬地平行,所以我认为使用joblib获得加速不应该太难。
以下是一些示例代码:
class RandomForest(object):
def __init__(self, settings, data):
self.forest = [None] * settings.n_trees
self.parallel = Parallel(n_jobs=settings.njobs, backend="threading")
def fit(self, data, train_ids_current_minibatch, settings, param, cache):
self.forest = self.parallel(
delayed(_parallel_build_trees_batch)(
i_t, data, train_ids_current_minibatch, settings, param, cache)
for i_t, tree in enumerate(self.forest))
def partial_fit(self, data, train_ids_current_minibatch, settings, param, cache):
self.forest = self.parallel(
delayed(_parallel_build_trees_partial)(
tree, i_t, data, train_ids_current_minibatch, settings, param, cache)
for i_t, tree in enumerate(self.forest))
但是,在批处理和增量情况下,使用多个作业时,培训速度要慢得多。数据和缓存参数是包含(大)numpy数组的dicts,所以我想知道这是否是原因。
我尝试使用multiprocessing.Pool
对其进行编码,结果更糟,因为没有使用joblib的threading
后端,我假设因为fit函数大量使用numpy / scipy代码。
关于如何调试/修复减速的任何想法?
答案 0 :(得分:1)
您的分析对我来说似乎是正确的:减速是由data
和cache
是大对象引起的。现在,在多处理环境中,您没有共享内存,因此您需要以某种方式共享这些对象。 Python通过shared objects支持这个:有一个“主进程”真正保存对象。但是其他进程需要通过某种机制发送所有更新(AFAIK对象被pickle然后通过管道或队列发送),这会减慢它的速度。
我看到了一些选项:
data
作为初始数据集,然后你试着找到一个“最优”。如果您可以推送进程1以查找所有“类型A”优化,并且进程2找到所有“类型B”优化,然后让每个进程例如将他们的发现写在文件rf_process_x.txt
中的磁盘上,然后您不需要共享内存状态data
集(因此它不在共享内存中)