为什么 scipy.optimize.minimize 试图将奇怪的参数传递给我的 objective 函数?
Why is scipy.optimize.minimize trying to pass in weird arguments to my objective function?
我有一个 class 可以帮助实例化统计模型。它的一些数据成员是参数。我正在尝试编写一种优化这些参数的方法。反对函数基于似然函数的负数。此似然函数本身作为 class 方法实现,该方法在其计算中使用 class 数据成员的值。
我知道这是不好的风格,但每次 objective 函数被 scipy.optimize.minimize()
调用时,它都会将对象数据成员更改为更好的数据成员。我不太关心为什么这不好,而更关心为什么这不起作用。代码下方是完整的回溯。
似乎部分有效。它在测试数据上运行了几秒钟,但随后触发了我的断言。似乎 minimize()
在接近优化结束时做了一些奇怪的事情。为什么它会尝试将不同类型的参数传递给 objective 函数 obj_fun()
?在我的 IPython 解释器中,我随后检查了对象的参数,它似乎达到了预期的结果。
我尝试查看 scipy 的一些来源。不过,这非常令人困惑。有很多模棱两可的变量命名和函数包装。任何人都可以告诉我为什么会发生这种情况以及如何解决它吗?我想再次将这些优化内容保留在我的 class.
中
class MyThing(object):
.
.
.
def mle_fit(self, y, inpt, optim_these):
#step 1: figure out what you want to optimize
self.optimize_these = optim_these
#step 2: get inital flat parameter vector
self._make_list_optimizable_hyp_pars()
init_guess = self.flat_hyper_params
#step 3: run minimize
def obj_fun(pars):
# returns negative log likelihood
assert len(pars) == len(init_guess) # HERE #
self.flat_hyper_params = pars
self._unflatten_new_hps()
self.like(y, inpt)
return .5 * self.neg_2_log_like
res = minimize(obj_fun, init_guess, method = 'BFGS')
回溯:
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 419, in minimize
return _minimize_bfgs(fun, x0, args, jac, callback, **options)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 850, in _minimize_bfgs
old_fval, old_old_fval)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 690, in _line_search_wolfe12
old_fval, old_old_fval)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 263, in line_search_wolfe2
derphi0, c1, c2, amax)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 363, in scalar_search_wolfe2
phi0, derphi0, c1, c2)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 498, in _zoom
phi_aj = phi(a_j)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 239, in phi
return f(xk + alpha * pk, *args)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 281, in function_wrapper
return function(*(wrapper_args + args))
File "MyThing.py", line 222, in obj_fun
assert len(pars) == len(init_guess)
如果我没记错的话,SciPy在优化时,可以将标量和数组都发送到要最小化的函数。因此,如果您优化 f(x)
,您将得到 x = 3.14
和 x = array([1, 4])
。 (这将用于加速计算,对于使用 NumPy 数组函数的 objective 函数 f
。)
如果确实是这种情况,让您的代码处理这将解决问题。
现在,您可以通过 obj_fun()
中的 print pars, type(pars), len(pars)
这样的检查轻松检查情况。
我有一个 class 可以帮助实例化统计模型。它的一些数据成员是参数。我正在尝试编写一种优化这些参数的方法。反对函数基于似然函数的负数。此似然函数本身作为 class 方法实现,该方法在其计算中使用 class 数据成员的值。
我知道这是不好的风格,但每次 objective 函数被 scipy.optimize.minimize()
调用时,它都会将对象数据成员更改为更好的数据成员。我不太关心为什么这不好,而更关心为什么这不起作用。代码下方是完整的回溯。
似乎部分有效。它在测试数据上运行了几秒钟,但随后触发了我的断言。似乎 minimize()
在接近优化结束时做了一些奇怪的事情。为什么它会尝试将不同类型的参数传递给 objective 函数 obj_fun()
?在我的 IPython 解释器中,我随后检查了对象的参数,它似乎达到了预期的结果。
我尝试查看 scipy 的一些来源。不过,这非常令人困惑。有很多模棱两可的变量命名和函数包装。任何人都可以告诉我为什么会发生这种情况以及如何解决它吗?我想再次将这些优化内容保留在我的 class.
中class MyThing(object):
.
.
.
def mle_fit(self, y, inpt, optim_these):
#step 1: figure out what you want to optimize
self.optimize_these = optim_these
#step 2: get inital flat parameter vector
self._make_list_optimizable_hyp_pars()
init_guess = self.flat_hyper_params
#step 3: run minimize
def obj_fun(pars):
# returns negative log likelihood
assert len(pars) == len(init_guess) # HERE #
self.flat_hyper_params = pars
self._unflatten_new_hps()
self.like(y, inpt)
return .5 * self.neg_2_log_like
res = minimize(obj_fun, init_guess, method = 'BFGS')
回溯:
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 419, in minimize
return _minimize_bfgs(fun, x0, args, jac, callback, **options)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 850, in _minimize_bfgs
old_fval, old_old_fval)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 690, in _line_search_wolfe12
old_fval, old_old_fval)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 263, in line_search_wolfe2
derphi0, c1, c2, amax)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 363, in scalar_search_wolfe2
phi0, derphi0, c1, c2)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 498, in _zoom
phi_aj = phi(a_j)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/linesearch.py", line 239, in phi
return f(xk + alpha * pk, *args)
File "/home/taylor/anaconda/lib/python2.7/site-packages/scipy/optimize/optimize.py", line 281, in function_wrapper
return function(*(wrapper_args + args))
File "MyThing.py", line 222, in obj_fun
assert len(pars) == len(init_guess)
如果我没记错的话,SciPy在优化时,可以将标量和数组都发送到要最小化的函数。因此,如果您优化 f(x)
,您将得到 x = 3.14
和 x = array([1, 4])
。 (这将用于加速计算,对于使用 NumPy 数组函数的 objective 函数 f
。)
如果确实是这种情况,让您的代码处理这将解决问题。
现在,您可以通过 obj_fun()
中的 print pars, type(pars), len(pars)
这样的检查轻松检查情况。