Python scipy.optimize.minimize将数组写入数组并无法收敛
在使用scipy.optimize.minimize时,在一个示例问题中,当最小化函数正在收敛到最佳值时,我遇到了一个错误。我的代码是:Python scipy.optimize.minimize将数组写入数组并无法收敛,python,python-3.x,numpy,scipy,minimize,Python,Python 3.x,Numpy,Scipy,Minimize,在使用scipy.optimize.minimize时,在一个示例问题中,当最小化函数正在收敛到最佳值时,我遇到了一个错误。我的代码是: import numpy as np from scipy.optimize import minimize def get_data_sin(N, sigma_noise=0.1, end=50): f = lambda x: np.sin(x/6.) x = np.random.rand(N)*end y
import numpy as np
from scipy.optimize import minimize
def get_data_sin(N, sigma_noise=0.1, end=50):
f = lambda x: np.sin(x/6.)
x = np.random.rand(N)*end
y = f(x) + np.random.normal(0, sigma_noise, N)
return x.reshape(-1,1), y.reshape(-1,1)
gitter = lambda N, value: value*np.eye(N)
def rbf(x1, x2, sigma, l):
return sigma**2 * np.exp(-(0.5/l**2) * np.linalg.norm(x1 - x2)**2)
def get_cov(kernel, X1, X2, param):
return np.array([[kernel(x1, x2, *param) for x1 in X1] for x2 in X2])
#*param will use all items in param successively
#list comprehension: expression for item in list
def log_likelihood(hparam, X, y):
print(hparam)
sigma, l, sigma_noise = hparam
cov = get_cov(rbf, X, X, [sigma, l]) \
+ sigma_noise**2 * np.eye((X.shape[0])) \
+ gitter(X.shape[0], 1e-10)
ll = -0.5 * np.matmul(y.T, np.linalg.solve(cov,y))
ll += -np.log( np.linalg.det(np.linalg.cholesky(cov)) )
return -ll
np.random.seed(seed=100)
N = 30
X, y = get_data_sin(N)
fit = minimize(log_likelihood, (1., 1., 1.,), (X, y))
sigma, l, sigma_noise = fit.x
print(fit)
其中,rbf和get_cov函数用于创建具有rbf类元素的矩阵,然后用于计算对数似然(应优化的函数应输出标量)。
由于代码在收敛期间输出值,我想我的数学是正确的。一段时间后,hyperparameters(hparam)的输出会发生变化,如下所示:
[ 0.98103018 10.86622839 0.11097829]
[ 0.98103018 10.86622837 0.1109783 ]
[ 0.98103017 10.86622838 0.11097828]
[[ 0.98103018 10.86622837 0.11097828]]
其中minimize将列表写入列表,以便只能解包一个值。这是错误消息:
ValueError Traceback (most recent call last)
<ipython-input-55-7551e417800b> in <module>
21 return -ll
22
---> 23 fit = minimize(log_likelihood, (1., 1., 1.,), (X_train, y_train))
24 sigma, l, sigma_noise = fit.x
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
592 return _minimize_cg(fun, x0, args, jac, callback, **options)
593 elif meth == 'bfgs':
--> 594 return _minimize_bfgs(fun, x0, args, jac, callback, **options)
595 elif meth == 'newton-cg':
596 return _minimize_newtoncg(fun, x0, args, jac, hess, hessp, callback,
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/optimize.py in _minimize_bfgs(fun, x0, args, jac, callback, gtol, norm, eps, maxiter, disp, return_all, **unknown_options)
1014 alpha_k, fc, gc, old_fval, old_old_fval, gfkp1 = \
1015 _line_search_wolfe12(f, myfprime, xk, pk, gfk,
-> 1016 old_fval, old_old_fval, amin=1e-100, amax=1e100)
1017 except _LineSearchError:
1018 # Line search failed to find a better solution.
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/optimize.py in _line_search_wolfe12(f, fprime, xk, pk, gfk, old_fval, old_old_fval, **kwargs)
853 old_fval, old_old_fval,
854 extra_condition=extra_condition,
--> 855 **kwargs2)
856
857 if ret[0] is None:
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py in line_search_wolfe2(f, myfprime, xk, pk, gfk, old_fval, old_old_fval, args, c1, c2, amax, extra_condition, maxiter)
309 alpha_star, phi_star, old_fval, derphi_star = scalar_search_wolfe2(
310 phi, derphi, old_fval, old_old_fval, derphi0, c1, c2, amax,
--> 311 extra_condition2, maxiter=maxiter)
312
313 if derphi_star is None:
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py in scalar_search_wolfe2(phi, derphi, phi0, old_phi0, derphi0, c1, c2, amax, extra_condition, maxiter)
432 _zoom(alpha0, alpha1, phi_a0,
433 phi_a1, derphi_a0, phi, derphi,
--> 434 phi0, derphi0, c1, c2, extra_condition)
435 break
436
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py in _zoom(a_lo, a_hi, phi_lo, phi_hi, derphi_lo, phi, derphi, phi0, derphi0, c1, c2, extra_condition)
570 # Check new value of a_j
571
--> 572 phi_aj = phi(a_j)
573 if (phi_aj > phi0 + c1*a_j*derphi0) or (phi_aj >= phi_lo):
574 phi_rec = phi_hi
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py in phi(alpha)
272 def phi(alpha):
273 fc[0] += 1
--> 274 return f(xk + alpha * pk, *args)
275
276 if isinstance(myfprime, tuple):
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/optimize.py in function_wrapper(*wrapper_args)
324 def function_wrapper(*wrapper_args):
325 ncalls[0] += 1
--> 326 return function(*(wrapper_args + args))
327
328 return ncalls, function_wrapper
<ipython-input-55-7551e417800b> in log_likelihood(hparam, X, y)
11 def log_likelihood(hparam, X, y):
12 print(hparam)
---> 13 sigma, l, sigma_noise = hparam
14 cov = get_cov(rbf, X, X, [sigma, l]) \
15 + sigma_noise**2 * np.eye((X.shape[0])) \
ValueError: not enough values to unpack (expected 3, got 1)
ValueError回溯(最近一次调用)
在里面
21返回-ll
22
--->23拟合=最小化(对数可能性,(1,1,1,1),(X序列,y序列))
24西格玛,l,西格玛_噪声=拟合.x
最小化中的~/envs/env1/lib/python3.5/site-packages/scipy/optimize//u minimize.py(fun、x0、args、method、jac、hess、hessp、bounds、constraints、tol、callback、options)
592返回最小化cg(乐趣、x0、参数、jac、回调,**选项)
593 elif meth==“bfgs”:
-->594返回_最小化_bfgs(乐趣、x0、args、jac、回调,**选项)
595 elif meth==‘牛顿重心’:
596返回_最小化_newtoncg(fun、x0、args、jac、hess、hessp、callback、,
最小化BFG中的~/envs/env1/lib/python3.5/site-packages/scipy/optimize/optimize.py
1014 alpha_k、fc、gc、old_fval、old_old_fval、gfkp1=\
1015行搜索沃尔夫12(f,myfprime,xk,pk,gfk,
->1016 old_fval,old_old_fval,amin=1e-100,amax=1e100)
1017除_LineSearchError外:
1018线搜索未能找到更好的解决方案。
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/optimize.py in\u line\u search\u wolfe12(f、fprime、xk、pk、gfk、old\u fval、old\u old\u fval、**kwargs)
853老法,老法,
854额外条件=额外条件,
-->855**kwargs2)
856
857如果ret[0]为无:
~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py-in-line\u-search\u-wolfe2(f、myfpinite、xk、pk、gfk、old\u-fval、old\u-old\u-fval、args、c1、c2、amax、额外条件、maxiter)
309 alpha_星、phi_星、old_fval、derphi_星=标量搜索wolfe2(
310 phi,derphi,old_fval,old_old_fval,derphi0,c1,c2,amax,
-->311额外条件2,最大值=最大值)
312
313如果derphi_星为无:
标量搜索wolfe2中的~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py(phi、derphi、phi0、old_phi0、derphi0、c1、c2、amax、额外条件、maxiter)
432缩放(alpha0、alpha1、phi_a0、,
433 phi_a1,derphi_a0,phi,derphi,
-->434 phi0、DERPI0、c1、c2、额外条件)
435中断
436
缩放中的~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py(a_-lo、a_-hi、phi_-lo、phi_-hi、derphi_-lo、phi、derphi、phi0、derphi0、c1、c2、额外条件)
570#检查a#j的新值
571
-->572 phi_aj=phi(a_j)
573如果(phi_aj>phi0+c1*a_j*derphi0)或(phi_aj>=phi_lo):
574 phi_rec=phi_hi
phi(alpha)中的~/envs/env1/lib/python3.5/site-packages/scipy/optimize/linesearch.py
272 def phi(α):
273 fc[0]+=1
-->274返回f(xk+alpha*pk,*args)
275
276如果isinstance(myfprime,元组):
函数包装器(*wrapper\u args)中的~/envs/env1/lib/python3.5/site-packages/scipy/optimize/optimize.py
324 def函数包装器(*包装器参数):
325 nCall[0]+=1
-->326返回函数(*(包装器参数+参数))
327
328返回NCALL,函数包装器
对数似然(hparam,X,y)
11 def对数可能性(hparam,X,y):
12打印(hparam)
--->13西格玛,l,西格玛_噪声=hparam
14 cov=获得cov(rbf,X,X,[sigma,l])\
15+sigma_噪声**2*np.眼睛((X.形状[0]))\
ValueError:没有足够的值来解包(预期为3,得到1)
复制:
Python版本3.5.2、scipy版本1.3.1、numpy版本1.17.2
使用固定种子,种子42不产生错误,种子100产生错误。虽然不使用固定种子,但有些随机数会产生错误,有些则不会。(我多次运行脚本,大约3次中只有2次产生错误。)
上面的代码运行在jupyter笔记本中
有人知道这种行为吗,或者能帮我找出问题所在吗
我知道有一种解决方法,使用catchcall并在发生这种情况时读取list元素中的列表,但我仍然想知道这个错误来自何处 初始值以元组形式给出,
(1,1,1.,)
,但minimize
将其转换为3元素numpy
数组。大多数情况下,形状是(3,),但在问题实例中,它变成(1,3)。我怀疑发生这种情况是因为上一次调用log\u likelion
返回了一个异常值(它应该只是一个标量)。在返回之前,添加ll
的测试或打印是一件容易的事情。您的代码非常复杂,我无法判断在所有情况下发生了什么或可能发生什么。一次通话中的ll
是否会在下次通话中触发此错误?@hpaulj谢谢你的提示,我会调查的@hpaulj我已经检查过了,ll
的输出维度总是相同的,应该是一个标量。