私はscipy.optimize.fmin_bfgs(f, init_theta, fprime)
最小化するために使用してf
いますが、これには勾配がありfprime
ます。ほとんどの計算は同じであり、2 回行う必要がないため、1 つの関数でf
andを計算します。fprime
と の両方をfmin_bfgs()
返す単一の関数を指定して呼び出す方法はありますか?f
fprime
私はscipy.optimize.fmin_bfgs(f, init_theta, fprime)
最小化するために使用してf
いますが、これには勾配がありfprime
ます。ほとんどの計算は同じであり、2 回行う必要がないため、1 つの関数でf
andを計算します。fprime
と の両方をfmin_bfgs()
返す単一の関数を指定して呼び出す方法はありますか?f
fprime
f
コードの利便性のためにとの計算を組み合わせるだけでなく、計算時間を節約しようとしている場合は、そのような関数を渡すことができないように見えるためf'
、値をキャッシュするために関数の周りに追加のラッパーが必要なようです。fmin_bfgs
(他の最適化関数とは異なります)。
これを行う 1 つの方法として、最近評価された 10 個のポイントを小さなキャッシュに保持します。(この関数の呼び出しがスレッドセーフである必要があるかどうかはわかりません。おそらくそうではありませんが、そうであれば、おそらくここにロックを追加する必要があると思います。)
def func_wrapper(f, cache_size=10):
evals = {}
last_points = collections.deque()
def get(pt, which):
s = pt.tostring() # get binary string of numpy array, to make it hashable
if s not in evals:
evals[s] = f(pt)
last_points.append(s)
if len(last_points) >= cache_size:
del evals[last_points.popleft()]
return evals[s][which]
return functools.partial(get, which=0), functools.partial(get, which=1)
もしそうなら
>>> def f(x):
... print "evaluating", x
... return (x-3)**2, 2*(x-3)
>>> f_, fprime = func_wrapper(f)
>>> optimize.fmin_bfgs(f_, 1000, fprime)
evaluating [ 994.93480441]
evaluating [ 974.67402207]
evaluating [ 893.63089268]
evaluating [ 665.93446894]
evaluating [ 126.99931561]
evaluating [ 3.]
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 4
Function evaluations: 7
Gradient evaluations: 7
array([ 3.])
評価を繰り返さないことがわかります。
f(x)
関数値と勾配の両方を返すPython 関数があるとします。
In [20]: def f(x):
....: return (x-3)**2, 2*(x-3)
次に、出力を次のように個別に渡します。
In [21]: optimize.fmin_bfgs(lambda x: f(x)[0], 1000, lambda x: f(x)[1])
Optimization terminated successfully.
Current function value: 0.000000
Iterations: 4
Function evaluations: 7
Gradient evaluations: 7
Out[21]: array([ 3.])