多线程调用scipy.optimize.leastsq的目标函数

use*_*653 2 python mathematical-optimization scipy

我正在scipy.optimize.leastsq和模拟器一起使用.leastsq调用用户定义的目标函数并将输入向量传递给它.反过来,目标函数返回错误向量.leastsq以这样的方式优化输入向量,使得误差向量的平方和最小化.

在我的情况下,目标函数将在每次调用时运行整个模拟.使用的模拟器是单线程的,每次运行需要几分钟.因此,我想一次运行模拟器的多个实例.但是,对目标函数的调用是连续执行的.

如何leastsq一次执行对目标函数的多次调用?

xio*_*xox 7

leastsq通过提供自己的函数来计算导数(Dfun参数),有一个很好的机会加速,前提是你有几个参数.如果未提供此功能,则leastsq迭代每个参数以每次计算导数,这是耗时的.这似乎占用了大部分时间.

您可以使用自己的Dfun函数,使用a multiprocessing.Pool来计算每个参数的导数.这些衍生物可以独立计算,并且可以简单地并行化.

这是一个粗略的例子,展示了如何做到这一点:

import numpy as np
import multiprocessing
import scipy.optimize

def calcmod(params):
    """Return the model."""
    return func(params)

def delta(params):
    """Difference between model and data."""
    return calcmod(params) - y

pool = multiprocessing.Pool(4)

def Dfun(params):
    """Calculate derivatives for each parameter using pool."""
    zeropred = calcmod(params)

    derivparams = []
    delta = 1e-4
    for i in range(len(params)):
        copy = np.array(params)
        copy[i] += delta
        derivparams.append(copy)

    results = pool.map(calcmod, derivparams)
    derivs = [ (r - zeropred)/delta for r in results ]
    return derivs

retn = scipy.optimize.leastsq(leastfuncall, inputparams, gtol=0.01,
                              Dfun=Dfun, col_deriv=1)
Run Code Online (Sandbox Code Playgroud)


pv.*_*pv. 6

leastsqLevenberg-Marquardt 使用的算法需要在确定下一个点之前知道当前点的目标函数的值.简而言之,没有直接的方法来并行化这种串行算法.

但是,您可以在某些情况下并行化您的目标函数.这可以完成,如果是以下形式:

def objective_f(params):
    r = np.zeros([200], float)
    for j in range(200):
        r[j] = run_simulation(j, params)
    return

def run_simulation(j, params):
    r1 = ... compute j-th entry of the result ...
    return r1
Run Code Online (Sandbox Code Playgroud)

在这里,您可以清楚地在整个循环中并行化j,例如使用多处理模块.这样的事情:(未经测试)

def objective_f(params):
    r = np.zeros([200], float)
    def parameters():
        for j in range(200):
            yield j, params
    pool = multiprocessing.Pool()
    r[:] = pool.map(run_simulation, parameters())
    return r
Run Code Online (Sandbox Code Playgroud)

如果必须适合多个数据集,则会出现并行化的另一个机会 - 这是一个(令人尴尬的)并行问题,并且可以并行安装不同的数据集.

如果这没有帮助,您可以在文献中讨论关于LM算法的并行化的讨论.例如:http://dl.acm.org/citation.cfm?id = 1542338 本文提出的主要优化似乎是雅可比数值计算的并行化.您可以通过提供自己的并行雅可比功能来实现此目的leastsq.然而,该论文的其余建议(推测性地并行化Levenberg-Marquardt搜索步骤)更难以实现,并且需要改变LM算法.

我不知道Python(或其他语言)库实现了针对并行计算的优化算法,尽管可能有一些.如果你设法实现/找到其中一个,请在Scipy用户邮件列表上做广告--​​-其中一个肯定有兴趣!