BFGSメソッドを使用して、自乗指数関数/ RBFカーネルの負の対数尤度を与えます。それの勾配(Jacobian)と同様に。グラデーションを残して、それは最初の違いを使用して正常に動作します - しかし、scipy.optimize.minimizeヤコビアン関数が原因で '値エラー:複数の要素を持つ配列の真理値が曖昧です'
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
NLLのグラデーションを試してみるとエラーが発生します。また、以下の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 fit
res = 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 minimize
return _minimize_bfgs(fun, x0, args, jac, callback, **options)
File "/usr/lib/python3.5/site-packages/scipy/optimize/optimize.py", line 865, in _minimize_bfgs
old_fval, old_old_fval)
File "/usr/lib/python3.5/site-packages/scipy/optimize/optimize.py", line 706, in _line_search_wolfe12
old_fval, old_old_fval)
File "/usr/lib/python3.5/site-packages/scipy/optimize/linesearch.py", line 282, in line_search_wolfe2
phi, 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_wolfe2
if (phi_a1 > phi0 + c1 * alpha1 * derphi0) or \
関連するコードは次のとおりです。
gp_hp_guess = [1.0] * 3 # initial guess
res = minimize(self.SE_NLL, gp_hp_guess, method='bfgs', jac=self.SE_der)
# other stuff
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))) # save for use with derivative func
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 -der
def 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))) # save for use with derivative func
nll = (
0.5 * self.y.T.dot(alpha) +
np.matrix.trace(L) + # sum of diagonal
L.shape[0]/2 * math.log(2*math.pi)
)
return nll
とき勾配NLLが正常に動作しますように私は、ヘルパー関数のソースコードを残してきました関数は使用されず、同じヘルパー関数を共有します。
SE_der関数を呼び出すと、事実の後で最適化されたパラメータを直接渡して(実際には最適化でグラデーションを使用しない)、期待どおりの単一の数値を出力します(少なくとも、私は問題を見つけることに失敗している。
このエラーは、scipyがJacobian関数などで期待していることの誤解ですか?私はPythonのソースコードを掘り下げようとしましたが、関数を扱う実際の関数呼び出しは、GithubのPythonコードのようには見えない関数の背後に隠されています。私たちがprivate/C++リポジトリにいるかどうかはわかりませんどこか別の場所。
なぜSE_derが単一の数値を返すべきだと思いますか?勾配は、変数と同じ数の要素を持つベクトルです(そのうちの3つが表示されます:f_err、l_scale、n_err)。 –
ありがとう@Bookend。私はそれが郵便であった場合、私はこれを受け入れられた答えとしてマークしたいと思います。それは、私がラスムッセンとウィリアムズの本の唯一の値(したがってmatrix.trace)としての本の対数尤度の派生を誤解しています。 。 – mediantis