【问题标题】:Naive parallelization of scipy.optimize.fminscipy.optimize.fmin 的幼稚并行化
【发布时间】:2013-07-03 19:07:12
【问题描述】:

scipy.optimize.fmin_bfgs 函数允许用户输入目标函数和梯度。由于我的桌面上有一台 8 核机器,我想我可以通过运行来并行化求解器

from scipy import optimize
import itertools
import numpy as np

def single_grad_point((idx,px)):
    p = px.copy()
    epsilon = 10**(-6.0)
    p[idx] += epsilon
    d1 = err_func(p)
    p[idx] -= 2*epsilon
    d2 = err_func(p)
    return (d1-d2)/(2*epsilon)

def err_func_gradient(p):
    P = multiprocessing.Pool()   
    input_args = zip(*(xrange(len(p)), itertools.cycle((p,))))
    sol = P.imap(single_grad_point, input_args)
    return np.array(list(sol))

optimize.fmin_bfgs(err_func, p0, fprime=err_func_gradient)

简而言之,我使用多重处理来计算梯度的每个方向。如果目标函数err_func 很昂贵,这似乎获得了显着的加速。然而,我的问题是关于所有multiprocessing.Pools 的使用和破坏/破坏。由于err_func_gradient 有可能被调用数万次,这会导致速度变慢或在某处泄漏

【问题讨论】:

  • 我看过,但 scipy 似乎没有并行的非线性优化器。如果我错了,我会把它作为一个答案。
  • 您不能创建一次multiprocessing.Pool,然后将其作为附加参数传递给ffprime 吗?这样,您或许可以避免在每次迭代中构建/销毁池所涉及的开销。

标签: python parallel-processing scipy multiprocessing


【解决方案1】:

您可以使用mystic,它提供了一些scipy.optimize 算法的并行版本,包括fmin 和朋友。

除非您有一些非常昂贵的目标函数要计算,否则尝试进行简单的调用以并行评估每个单纯形通常会减慢您的速度。但是,如果您改为调用 fmin 的多个实例,您实际上可以在最陡下降速度下获得伪全局优化。以下示例演示了已在多个 pubs 中使用的算法(见下文): https://github.com/uqfoundation/mystic/blob/master/examples/buckshot_example06.py

或者类似地,看看这里的例子:使用multiprocessing的fork:https://github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_mpmap.py

parallelpython 的一个分支(分布式并行计算): https://github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_ppmap.py

或使用mpi4py 的扩展名: https://github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_mpimap.py

在此处获取mystic(求解器框架)和pathos(并行计算框架): https://github.com/uqfoundation

Pub 参考资料(均已过时): http://conference.scipy.org/proceedings/scipy2011/mckerns.html http://trac.mystic.cacr.caltech.edu/project/mystic/wiki/Publications

但是,如果您想做更简单的fmin 版本,最好的方法是只初始化和加载pool 一次。这是pathos 已经为您提供的,但如果您想自己编写代码,只需将pool 的实例保存为单例即可。 https://github.com/uqfoundation/pathos/blob/master/pathos/multiprocessing.py

【讨论】:

【解决方案2】:

对于初学者,您可以将梯度计算为

(f(x)-f(x+eps))/eps

然后对所有偏导数计算一次 f(x)。这应该可以为您节省一半的工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2012-10-24
    • 2013-01-05
    相关资源
    最近更新 更多