我目前正在尝试使用 scipy.optimize 来查找尝试拟合某些数据的模拟参数。 A 创建了一个函数,给出我的模型在数据上的卡方,以便 scipy.optimize 必须最小化该函数。
我进行模拟的主要问题之一是,因此被调用的函数非常耗时,而且我发现方法 L-BFGS_B(或就此而言只是 BFGS)在同一点计算了函数值的数倍! !!我不明白为什么它会这么做,这简直要了我的命。
一个具有非常简单功能的示例:
from scipy.optimize import minimize
def f3(x):
print x
return x[0]*x[0] + x[1]*x[1] + x[2]*x[2]
x0 = [3, -5, 7]
minimize(f3, x0, method = 'L-BFGS-B')
将返回 :
[ 3. -5. 7.]
[ 3. -5. 7.]
[ 3.00000001 -5. 7. ]
[ 3. -4.99999999 7. ]
[ 3. -5. 7.00000001]
[ 2.67070726 -4.45117871 6.23165016]
[ 2.67070726 -4.45117871 6.23165016]
[ 2.67070727 -4.45117871 6.23165016]
[ 2.67070726 -4.4511787 6.23165016]
[ 2.67070726 -4.45117871 6.23165017]
[ -1.72315050e-06 1.66152263e-06 -1.59989476e-06]
[ -1.72315050e-06 1.66152263e-06 -1.59989476e-06]
[ -1.71315050e-06 1.66152263e-06 -1.59989476e-06]
[ -1.72315050e-06 1.67152263e-06 -1.59989476e-06]
[ -1.72315050e-06 1.66152263e-06 -1.58989476e-06]
status: 0
success: True
nfev: 15
fun: 8.2895683293030033e-12
x: array([ -1.72315050e-06, 1.66152263e-06, -1.59989476e-06])
message: 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL'
jac: array([ -3.43630101e-06, 3.33304526e-06, -3.18978951e-06])
nit: 2
正如您在函数调用的打印列表中看到的那样,minimize
在同一个 x 中多次调用 f3。
这很令人沮丧,因为我觉得在这里浪费了很多时间。
如果有人能在这里启发我,我很高兴。谢谢。
它会这样做,因为它没有你希望的那么小心。此缺陷已添加到 scipy bug tracker 中here https://github.com/scipy/scipy/issues/4076。正如我在那里发布的,您可以通过自己缓存以前的值来解决这个问题。或者,您可以使用jac=True
在你的minimize
调用并编写函数以返回该点的值和梯度。第一种方法的示例是:
import numpy as np
from scipy import optimize
class CacheLast(object):
def __init__(self, f):
self.f = f
self.last_x = None
self.last_f = None
self.ncall = 0
def __call__(self, x):
if np.all(x == self.last_x):
return self.last_f
else:
self.last_x = x
self.last_f = self.f(x)
self.ncall += 1
return self.last_f
def f3(x):
return x[0]*x[0] + x[1]*x[1] + x[2]*x[2]
x0 = [3, -5, 7]
func = CacheLast(f3)
res = optimize.minimize(func, x0, method='L-BFGS-B')
print 'total function calls: ', res.nfev
print 'actual function evals: ', func.ncall
这使:
total function calls: 15
actual function evals: 12
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)