2012-05-07 23 views
0

私はscipy.optimize.leastsqをシミュレータと併用しています。 leastsqは、ユーザ定義の目的関数を呼び出し、入力ベクトルを渡します。次に、目的関数は誤差ベクトルを返します。 leastsqは、誤差ベクトルの2乗の和が最小になるように入力ベクトルを最適化します。目的関数scipy.optimize.leastsqへのマルチスレッド呼び出し

私の場合、目的関数は呼び出されるたびにシミュレーション全体を実行します。使用されるシミュレータはシングルスレッドであり、実行ごとに数分必要です。したがって、私はシミュレータの複数のインスタンスを一度に実行したいと思います。ただし、目的関数への呼び出しは順次実行されます。

leastsqに目的関数への複数の呼び出しを一度に実行するにはどうすればよいですか?

答えて

-3

NumPy/SciPyの機能は、通常マルチスレッドに最適化されています。シミュレーション実行中に1つのコアだけが使用されていることを確認するためにCPU使用率を調べましたか?そうしないと、複数のインスタンスを実行しても何も得られません。

実際にはシングルスレッドの場合は、multiprocessingモジュールを使用することをお勧めします。 Pythonインタプリタのいくつかのインスタンスを実行するので、SciPyを同時に複数回呼び出すことができます。

5

Levenberg-Marquardt leastsqで使用されるアルゴリズムは、次の点を決定する前に現在の点で目的関数の値を知る必要があります。つまり、このようなシリアルアルゴリズムを並列化する簡単な方法はありません。

ただし、目的関数を並列化することもできます。ここで

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 

は、あなたがはっきりマルチプロセッシングモジュールを使用して、たとえば、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 

並列化のための別の機会を使用すると、複数のデータセットにフィットするようにしている場合---これは(embarassingly)パラレル問題であり、異なるデータセットを並列に装着することができる起こります。

これは役に立ちませんが、文献でLMアルゴリズムの並列化について議論することができます。例:http://dl.acm.org/citation.cfm?id=1542338この論文で提案されている主な最適化は、ヤコビ行列の数値計算の並列化のようです。 leastsqに独自の並列ヤコビアン関数を供給することで、これを行うことができます。しかし、Levenberg-Marquardt探索ステップを推論的に並列化する論文の残りの提案は、実装するのがより難しく、LMアルゴリズムの変更が必要です。

私は、並列計算の対象となる最適化アルゴリズムを実装しているPython(または他の言語)ライブラリは認識していませんが、いくつかあるかもしれません。あなたがそれらの1つを実装/発見することができれば、これをScipy usersメーリングリストに広告してください---これらのうちの1つに確かに興味があります!

5

leastsqには、いくつかのパラメータがあれば、導関数を計算するための独自の関数(Dfunパラメータ)を入力することができます。この関数が指定されていない場合は、が各パラメータに対して反復処理を行い、毎回微係数を計算するため、時間がかかります。これはフィッティングの大部分を占めるように見えます。

multiprocessing.Poolを使用して、各パラメータの導関数を計算する独自のDfun関数を使用して作業を行うことができます。これらの派生は独立して計算することが可能であり、並行して並列化する必要があります。ここで

はこれを行う方法を示す概略たとえば、次のとおりです。直接質問に関連していない

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) 
0

が、それは、複数のスレッドを使用して単一の最適化プロセスをスピードアップすることが可能です。最小化する関数は1つしかありませんが、パラメータの数のためにこれには数時間かかります。

現時点では、これはPythonでは不可能であるという印象を受けています。この場合、並列化は役に立ちません。

関連する問題