[英]Why is scipy.optimize.minimize trying to pass in weird arguments to my objective function?
I have a class that helps instantiate a statistical model. 我有一个有助于实例化统计模型的类。 Some of its data members are parameters.
它的某些数据成员是参数。 I am trying to write a method that optimizes these parameters.
我正在尝试编写一种优化这些参数的方法。 The objection function is based on the negative of the likelihood function.
异议函数基于似然函数的负数。 This likelihood function is implemented itself as a class method, which uses the values of the class data members in its calculation.
此可能性函数本身是作为类方法实现的,该类方法在计算时使用类数据成员的值。
I know this is bad style, but every time the objective function gets called by scipy.optimize.minimize()
, it changes the objects data members to the better ones. 我知道这是不好的样式,但是每次
scipy.optimize.minimize()
调用目标函数时,它都会将对象数据成员更改为更好的成员。 I am less concerned with why this is bad, and more concerned with why this isn't working. 我不太关心为什么这很糟糕,而更关心为什么这没有用。 Below the code is the full traceback.
代码下方是完整的追溯。
It seems like it works partially. 似乎部分起作用。 It runs for a few seconds on test data, but then it triggers my assertion.
它在测试数据上运行了几秒钟,但随后触发了我的断言。 It seems that
minimize()
does something weird when it's nearing the end of its optimizations. 当优化接近尾声时,
minimize()
似乎有些奇怪。 Why would it try to pass in different types of arguments to the objective function obj_fun()
? 为什么要尝试将不同类型的参数传递给目标函数
obj_fun()
? In my IPython interpreter I check the object's parameters afterwards, and it seems to be arriving at the expected result. 之后,在我的IPython解释器中,我检查了对象的参数,它似乎达到了预期的结果。
I tried looking through some of the source of scipy. 我试图浏览一些肮脏的来源。 It's very confusing, though.
但是,这非常令人困惑。 There is a lot of ambiguous variable naming and function wrapping.
有很多模棱两可的变量命名和函数包装。 Can anybody give me some color on why this is happening, and how to fix it?
有人能给我一些颜色为什么发生这种情况以及如何解决它的信息吗? Again I would like to keep this optimization stuff inside my 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')
Traceback: 追溯:
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)
If I remember correctly, SciPy, when optimizing, can send both scalars and arrays to the function to be minimized. 如果我没记错的话,SciPy在优化时可以将标量和数组都发送到要最小化的函数。 Thus, if you optimize
f(x)
, you will get, say, x = 3.14
and x = array([1, 4])
. 因此,如果优化
f(x)
,则将得到x = 3.14
和x = array([1, 4])
。 (This would be for speeding up calculations, for objective functions f
that use NumPy array functions.) If this is indeed the case, having your code handle this would solve the problem. (这是为了加快计算速度,对于使用NumPy数组函数的目标函数
f
。)如果确实如此,让您的代码处理就可以解决问题。
Now, you can easily check what the situation is with a check like print pars, type(pars), len(pars)
in obj_fun()
. 现在,您可以通过
obj_fun()
print pars, type(pars), len(pars)
轻松检查情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.