delayed()函数做什么(当与Python中的joblib一起使用时)

时间:2017-02-14 07:44:04

标签: python joblib

我已阅读documentation,但我不明白其含义是什么:  The delayed function is a simple trick to be able to create a tuple (function, args, kwargs) with a function-call syntax.

我正在使用它迭代我想要操作的列表(allImages),如下所示:

def joblib_loop():
    Parallel(n_jobs=8)(delayed(getHog)(i) for i in allImages)

这会返回我的HOG功能,就像我想要的那样(以及使用我所有8个内核的速度增益),但我只是不确定它实际上在做什么。

我的Python知识充其量是正常的,而且我很可能缺少一些基本的东西。任何指向正确方向的人都会非常感激

4 个答案:

答案 0 :(得分:21)

如果我们看看如果只写

会发生什么,也许事情会变得更加清楚。
Parallel(n_jobs=8)(getHog(i) for i in allImages)

Python的工作方式,getHog(i) for i in allImages创建一个列表,其中每个元素都已被评估。这意味着在将列表传递到您的getHog对象时,所有Parallel调用都已经返回,Parallel可以并行执行了!所有的工作都已经按顺序在我们现在所在的线程中完成了。

因此我们必须通过保留 a。)我们要调用的函数和 b。)参数来延迟希望使用来调用该函数,但实际上尚未执行该函数。

delayed通过清晰的语法为我们方便地进行了此操作。如果我们以后要“保留”调用foo(2, g=3),我们可以简单地调用delayed(foo)(2, g=3),然后返回元组(foo, [2], {g: 3}),以供其他人执行。


因此,在您的示例中,简而言之,会发生以下情况。

  1. 您创建了delayed(getHog)(i)

  2. 的列表
  3. 其中的每个delayed(getHog)(i)返回元组(function, args, kwargs)(在文档中您已读到),在这种情况下,它就是元组(getHog, [i], {})

  4. 您先前构造的Parallel对象为列表中的每个元素创建一个新线程,并将元组分配给它们。

  5. 在每个新线程上,它执行一个列表元素:调用元组的第一个元素,将第二个和第三个元素解压缩为参数el[0](*el[1], **el[2])function(*args, **kwargs),其中这种情况下会导致呼叫getHog(i)

答案 1 :(得分:0)

我们需要一个循环来测试不同模型配置的列表。这是驱动网格搜索过程的主要功能,并将针对每种模型配置调用score_model()函数。通过并行评估模型配置,我们可以大大加快网格搜索过程。一种方法是使用Joblib库。我们可以使用要使用的内核数定义一个Parallel对象,并将其设置为您的硬件中检测到的分数的数量。

定义执行者

executor = Parallel(n_jobs=cpu_count(), backend= 'multiprocessing' )

然后创建一个要并行执行的任务列表,这将是对我们拥有的每个模型配置的score模型()函数的一个调用。

假设def score_model(data, n_test, cfg): ........................

定义任务列表

tasks = (delayed(score_model)(data, n_test, cfg) for cfg in cfg_list)

我们可以使用Parallel对象并行执行任务列表。

scores = executor(tasks)

答案 2 :(得分:-2)

所以你想要做的就是堆积一组函数调用及其参数,以便你可以有效地将它们传递给调度程序/执行程序。 Delayed是一个decorator,它接收一个函数及其args并将它们包装到一个对象中,该对象可以放入一个列表中并根据需要弹出。 Dask具有相同的功能,它可以部分地用于输入图形调度程序。

答案 3 :(得分:-4)

参考https://wiki.python.org/moin/ParallelProcessing Parallel对象创建一个多处理池,它在多个进程中分叉Python解释器来执行列表中的每个项目。延迟函数是一个简单的技巧,可以使用函数调用语法创建元组(函数,args,kwargs)。

我想建议的另一件事是,而不是明确定义数量的内核,我们可以这样概括:

import multiprocessing
num_core=multiprocessing.cpu_count()