3

scipy.optimize.leastsqシミュレーターと組み合わせて使用​​しています。leastsqユーザー定義の目的関数を呼び出し、それに入力ベクトルを渡します。次に、目的関数はエラー ベクトルを返します。leastsq誤差ベクトルの二乗和が最小になるように入力ベクトルを最適化します。

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

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

4

5 に答える 5

8

いくつかのパラメーターがある場合、導関数 (パラメーター)leastsqを計算するための独自の関数を提供することで、高速化する良い機会があります。Dfunこの関数が指定されていない場合、 はleastsq各パラメータを反復して導関数を毎回計算しますが、これには時間がかかります。これは、フィッティングの時間の大半を占めているようです。

Dfuna を使用して各パラメータの導関数を計算する独自の関数を使用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)
于 2013-10-30T09:57:32.197 に答える
7

で使用されるアルゴリズムleastsq、Levenberg-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

jここでは、たとえば multiprocessing モジュールを使用して、ループ全体で明らかに並列化できます。このようなもの:(未テスト)

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

複数のデータセットを適合させる必要がある場合、並列化の別の機会が発生します --- これは (恥ずかしいほど) 並列の問題であり、異なるデータセットを並列に適合させることができます。

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

並列計算を対象とした最適化アルゴリズムを実装している Python (または他の言語) ライブラリについては知りませんが、いくつかあるかもしれません。それらの 1 つを実装/見つけることができた場合は、Scipy ユーザーのメーリング リストでこれを宣伝してください --- これらの 1 つに確かに関心があります!

于 2012-05-11T13:42:53.260 に答える
-1

これは役に立ちますか? http://docs.python.org/library/multiprocessing.html

私はいつも、Pool が Python でマルチプロセスするのに最も簡単であることを発見しました。

于 2012-05-07T21:22:49.647 に答える
-2

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

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

于 2012-05-07T21:23:16.997 に答える