2016-07-14 13 views
1

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++リポジトリにいるかどうかはわかりませんどこか別の場所。

+1

なぜSE_derが単一の数値を返すべきだと思いますか?勾配は、変数と同じ数の要素を持つベクトルです(そのうちの3つが表示されます:f_err、l_scale、n_err)。 –

+0

ありがとう@Bookend。私はそれが郵便であった場合、私はこれを受け入れられた答えとしてマークしたいと思います。それは、私がラスムッセンとウィリアムズの本の唯一の値(したがってmatrix.trace)としての本の対数尤度の派生を誤解しています。 。 – mediantis

答えて

1

サイドバーを見てください。同じことについてのそれらのすべての質問を参照してくださいValueError

状況はさまざまですが、ほぼすべての場合、スカラーブール値を期待する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)をスカラーとする。おそらくこれらの変数の1つは、複数の値を持つ配列です。確かに、これは呼び出し側のスタックに発生しているので、それらの値をコードに戻すことは困難です。

可変タイプと形状に焦点を当てた印刷が最も有用かもしれません。時には、これらの反復ソルバでは、コードが1つのループに対して正常に実行され、次に配列にいくらかの変数が変更され、次のループで発生することがあります。

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

なぜあなたはnp.matrix.traceを使用していますか?私のテストでは、2dの単一要素np.matrixが生成されます。このValueErrorが生成されることは明らかではありませんが、それでも疑わしいです。

+0

問題を引き起こすのは間違った形状なので、ここで唯一の回答としてこれを受け入れます。私は実装している方程式に何かを誤解していました。目的関数を単一の値として派生させているので、私はそれを再訪する必要があります。 – mediantis

関連する問題