scipy.optimize.minimize Jacobian函数导致’ValueError: The truth value of an array with more than one element is ambiguous’

我使用BFGS方法,提供给它的是我的平方指数/RBF核的负对数似然函数,以及它的梯度(雅可比矩阵)。如果不使用梯度,仅使用一阶差分,它可以正常工作 – 但是一旦我尝试使用NLL的梯度,就会出现以下错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

错误出现时,我的SE_der函数(梯度/雅可比矩阵)源代码中并没有使用.any()或.all(),我还尝试了这两种方法,但得到的错误完全相同。

前面的追踪信息如下:

Traceback (most recent call last):File "loaddata.py", line 107, in <module>gp.fit(X, y)File "/home/justinting/programming/bhm/ML/gp.py", line 33, in fitres = minimize(self.SE_NLL, gp_hp_guess, method='bfgs', jac=True)File "/usr/lib/python3.5/site-packages/scipy/optimize/_minimize.py", line 441, in minimizereturn _minimize_bfgs(fun, x0, args, jac, callback, **options)File "/usr/lib/python3.5/site-packages/scipy/optimize/optimize.py", line 865, in _minimize_bfgsold_fval, old_old_fval)File "/usr/lib/python3.5/site-packages/scipy/optimize/optimize.py", line 706, in _line_search_wolfe12old_fval, old_old_fval)File "/usr/lib/python3.5/site-packages/scipy/optimize/linesearch.py", line 282, in line_search_wolfe2phi, derphi, old_fval, old_old_fval, derphi0, c1, c2, amax)File "/usr/lib/python3.5/site-packages/scipy/optimize/linesearch.py", line 379, in scalar_search_wolfe2if (phi_a1 > phi0 + c1 * alpha1 * derphi0) or \

相关代码如下:

gp_hp_guess = [1.0] * 3 # 初始猜测res = minimize(self.SE_NLL, gp_hp_guess, method='bfgs', jac=self.SE_der)# 其他代码def SE_der(self, args):    [f_err, l_scale, n_err] = args    L = self.L_create(f_err, l_scale, n_err)    alpha = linalg.solve(L.T, (linalg.solve(L, self.y))) # 保存以便在导数函数中使用    aaT = alpha.dot(alpha.T)    K_inv = np.linalg.inv(L.T).dot(np.linalg.inv(L))    # self.K_inv = np.linalg.inv(self.L.T).dot(np.linalg.inv(self.L))    dK_dtheta = np.gradient(self.K_se(self.X, self.X, f_err, l_scale))[0]    der = 0.5 * np.matrix.trace((aaT - K_inv).dot(dK_dtheta))    return -derdef SE_NLL(self, args):    [f_err, l_scale, n_err] = args    L = self.L_create(f_err, l_scale, n_err)    alpha = linalg.solve(L.T, (linalg.solve(L, self.y))) # 保存以便在导数函数中使用    nll = (        0.5 * self.y.T.dot(alpha) +         np.matrix.trace(L) + # 对角线之和        L.shape[0]/2 * math.log(2*math.pi)            )    return nll

我省略了辅助函数的源代码,因为当不使用梯度函数时,NLL可以正常工作,并且它们共享相同的辅助函数。

在优化后直接调用SE_der函数并传入优化后的参数(实际上并未在优化中使用梯度),它会输出一个单一的数字,正如预期的那样(至少我认为这是预期的),所以我没能发现问题所在。

这个错误是我对scipy期望的雅可比函数的误解,还是其他原因?我尝试查看了Python源代码,但实际处理函数的调用被隐藏在似乎不在Github上的Python代码中的函数后面 – 我不知道它们是否在其他地方的私有/C++存储库中。


回答:

看看侧边栏。你看到所有那些关于相同ValueError的SO问题了吗?

虽然情况各不相同,但几乎在所有情况下,这都是因为在Python环境中使用了布尔数组,而该环境期望的是标量布尔值。

一个简单的例子是

In [236]: if np.arange(10)>5:print('yes')---------------------------------------------------------------------------ValueError                                Traceback (most recent call last)<ipython-input-236-633002262b65> in <module>()----> 1 if np.arange(10)>5:print('yes')ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

np.arange(10)>5产生一个布尔数组,np.array([False, False, ...])

组合布尔表达式也可能产生这种情况。np.arange(10)>5 | np.arange(10)<2会产生这种情况,(np.arange(10)>5) | (np.arange(10)<2)则不会 – 因为逻辑运算符的优先级。 在这种情况下使用and而不是|是无望的。

我会更详细地查看你的代码,但在此期间,这可能会帮助你自己找到问题所在。

==================

从错误堆栈中:

if (phi_a1 > phi0 + c1 * alpha1 * derphi0) or \

此时代码期望(phi_a1 > phi0 + c1 * alpha1 * derphi0)(以及or后面的任何内容)是一个标量。可以推测这些变量之一是一个具有多个值的数组。诚然,这发生在调用堆栈的很深的地方,因此追溯这些值到你的代码会很困难。

打印,关注变量类型和形状,可能是最有用的。有时在这些迭代求解器上,代码在一个循环中运行良好,然后某个变量变为数组,在下一个循环中就卡住了。

==================

你为什么使用np.matrix.trace?在我的测试中,它会产生一个2维的单元素np.matrix。虽然这不明显会导致这个ValueError,但仍然值得怀疑。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注