简体   繁体   English

scipy.optimize.fmin的朴素并行化

[英]Naive parallelization of scipy.optimize.fmin

The function scipy.optimize.fmin_bfgs allows the user to input both a target function and a gradient. 函数scipy.optimize.fmin_bfgs允许用户输入目标函数和渐变。 Since I have an 8-core machine on my desktop, I thought I could parallelize the solver by running 由于我的桌面上有一台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)

In a nutshell, I'm using multiprocessing to compute each direction of the gradient. 简而言之,我正在使用多处理来计算渐变的每个方向。 If the target function err_func is expensive, this seems to gain substantial speedup. 如果目标函数err_func很昂贵,那么这似乎可以获得大幅加速。 My question however is about the usage and con/destruction of all the multiprocessing.Pools . 然而,我的问题是关于所有multiprocessing.Pools的使用和con /破坏。 Since it's possible that err_func_gradient can be called tens of thousands of times, will this cause a slowdown or leak somewhere ? 因为err_func_gradient可能会被调用数万次, 这会导致某个地方的速度减慢或泄漏吗?

You could use mystic , which provides parallel versions of a few of the scipy.optimize algorithms, including fmin and friends. 你可以使用mystic ,它提供了一些scipy.optimize算法的并行版本,包括fmin和friends。

Trying to do a naive call to have each of the simplex evaluated in parallel is usually going to slow you down, unless you have some very very expensive objective functions to calculate. 试图做一个天真的调用,让每个单独的并行评估通常会减慢你的速度,除非你有一些非常昂贵的目标函数来计算。 However, if you instead call several instances of fmin , you can actually get pseduo-GLOBAL optimization at steepest-descent speeds. 但是,如果你改为调用fmin几个实例,你实际上可以以最速下降的速度获得pseduo-GLOBAL优化。 The following example demonstrates an algorithm that has been used in several pubs (see below): https://github.com/uqfoundation/mystic/blob/master/examples/buckshot_example06.py 以下示例演示了一个已在多个pub中使用的算法(见下文): https//github.com/uqfoundation/mystic/blob/master/examples/buckshot_example06.py

Or similarly, look at the examples here: using a fork of multiprocessing : https://github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_mpmap.py 或者类似地,看一下这里的例子:使用multiprocessing的分支: https//github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_mpmap.py

or a fork of parallelpython (distributed parallel computing): https://github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_ppmap.py 或者是parallelpython的分支(分布式并行计算): https//github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_ppmap.py

or using an extension of mpi4py : https://github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_mpimap.py 或者使用mpi4py的扩展名: https//github.com/uqfoundation/pathos/blob/master/examples2/optimize_cheby_powell_mpimap.py

Get mystic (the solver framework) and pathos (the parallel computing framework) here: https://github.com/uqfoundation 在这里获取mystic (求解器框架)和pathos (并行计算框架): https//github.com/uqfoundation

Pub references (both slightly out of date): http://conference.scipy.org/proceedings/scipy2011/mckerns.html http://trac.mystic.cacr.caltech.edu/project/mystic/wiki/Publications Pub引用(略有过时): http//conference.scipy.org/proceedings/scipy2011/mckerns.html http://trac.mystic.cacr.caltech.edu/project/mystic/wiki/Publications

If, however, you wanted to do the more naive version of fmin , the best approach is to only initialize and load the pool once. 但是,如果您想要更简单的fmin版本,最好的方法是只初始化并加载pool一次。 This is what pathos provides for you already, but if you wanted to code it yourself, just save the instance of the pool as a singleton. 这就是pathos已经为您提供的,但是如果您想自己编写代码,只需将pool的实例保存为单例。 https://github.com/uqfoundation/pathos/blob/master/pathos/multiprocessing.py https://github.com/uqfoundation/pathos/blob/master/pathos/multiprocessing.py

For starters, you can calc the gradient as 对于初学者,您可以将渐变计算为

(f(x)-f(x+eps))/eps (F(X)-f(X + EPS))/ EPS

Then calc f(x) once for all partial derivatives. 然后对所有偏导数计算一次f(x)。 That should save you half the work 这应该可以节省你一半的工作量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM