2016-07-23 4 views
0

実行時に何かが壊れても、Pythonコンソールで全く同じデータと操作を使用して問題なく動作します。何とかしNumpy - AttributeError: 'Zero'オブジェクトに属性 'exp'がありません

# f_err - currently has value 1.11819388872025 
# l_scales - currently a numpy array [1.17840183376334 1.13456764589809] 
sq_euc_dists = self.se_term(x1, x2, l_scales) # this is fine. It calls cdists on x1/l_scales, x2/l_scales vectors 
return (f_err**2) * np.exp(-0.5 * sq_euc_dists) # <-- errors on this line 

私はコンソールで同じF_ERR、l_scales、およびX1、X2右のそれエラー出た後で、それらの正確に同じラインを呼び出し、しかし

AttributeError: 'Zero' object has no attribute 'exp' 

あり得る誤り、エラーは発生しません。

「ゼロ」オブジェクトエラーを具体的に参照している投稿を見つけることができず、私が見つけた非ゼロのものはここのケースに当てはまらないようです。

編集:これは情報が少し欠けていたので、実際の(抽出された)実行可能なサンプルデータがあります。失敗した実行からまっすぐに取り出したもので、孤立して動作するとエラーは再現できません実行時を除きます。

以下のsqeucld_dist関数は非常に悪いので、代わりにscipyのcdistを使用する必要があることに注意してください。しかし、実際のデータで15以上の偏微分を持つ行列の要素勾配に対してsympyのシンボルを使用しているので、cdistは任意のオブジェクトを扱わないためオプションではありません。

import numpy as np 

def se_term(x1, x2, l): 
    return sqeucl_dist(x1/l, x2/l) 

def sqeucl_dist(x, xs): 
    return np.sum([(i-j)**2 for i in x for j in xs], axis=1).reshape(x.shape[0], xs.shape[0]) 


x = np.array([[-0.29932052, 0.40997373], [0.40203481, 2.19895326], [-0.37679417, -1.11028267], [-2.53012051, 1.09819485], [0.59390005, 0.9735], [0.78276777, -1.18787904], [-0.9300892, 1.18802775], [0.44852545, -1.57954101], [1.33285028, -0.58594779], [0.7401607, 2.69842268], [-2.04258086, 0.43581565], [0.17353396, -1.34430191], [0.97214259, -1.29342284], [-0.11103534, -0.15112815], [0.41541759, -1.51803154], [-0.59852383, 0.78442389], [2.01323359, -0.85283772], [-0.14074266, -0.63457529], [-0.49504797, -1.06690869], [-0.18028754, -0.70835799], [-1.3794126, 0.20592016], [-0.49685373, -1.46109525], [-1.41276934, -0.66472598], [-1.44173868, 0.42678815], [0.64623684, 1.19927771], [-0.5945761, -0.10417961]]) 
f_err = 1.11466725760716 
l = [1.18388412685279, 1.02290811104357] 
result = (f_err**2) * np.exp(-0.5 * se_term(x, x, l)) # This runs fine, but fails with the exact same calls and data during runtime 

大変助かりました!

import sympy 
import numpy 

zero = sympy.sympify('0') 

numpy.exp(zero) 

あなたが見ている同じ例外が表示されます。ここでは

+2

'Zero'はsympyオブジェクトです(http://docs.sympy.org/latest/modules/core.html#sympy.core.numbers)。私はこれがnumpyとscipyコードがsympyオブジェクトを扱うことができない別のケースだと思う。 'numpy.exp'に渡す引数の型をチェックしてください。 numpy関数を呼び出す前に、記号式が数値に変換されているかどうかを確認する必要があります。 –

+0

洞察に感謝します。私は最終的に、多くの実装された方程式に散在するすべての変数をトレース/デバッグした後、すべてのScipy型を削除しました。 – mediantis

答えて

1

は、あなたが見ているエラーを再現する方法です。

コードを次のように変更して浮動小数点にすることで、これを(非効率的に)修正できます。

def sqeucl_dist(x, xs): 
    return np.sum([np.vectorize(float)(i-j)**2 for i in x for j in xs], 
        axis=1).reshape(x.shape[0], xs.shape[0]) 

lambdifyを使用してグラデーション関数を修正する方がよいでしょう。

はここで今[2*x, cos(y), 1]、Sympy式のリストであるlambdifyは、部分D

from sympy.abc import x, y, z 
expression = x**2 + sympy.sin(y) + z 
derivatives = [expression.diff(var, 1) for var in [x, y, z]] 

derivatives上で使用することができる方法の例です。値の特定のセットで数値的にこれを評価する関数を作成するには、次のように我々は(そのような引数として'numpy'を渡すとnumpy.cosではなく、sympy.cosを使用することを意味します)lambdifyを使用します。今すぐ

derivative_calc = sympy.lambdify((x, y, z), derivatives, 'numpy') 

derivative_calc(1, 2, 3)が返されます[2, -0.41614683654714241, 1] 。これらは、intnumpy.float64です。

サイドノート:np.exp(M)は、Mの各要素の要素指数を計算します。行列を指数関数的にする場合は、np.linalg.exmpが必要です。

+0

ありがとう@chthonicdaemon(i-j)は、Pythonスカラーではなくnumpy配列ですが、dtypeをfloat32に設定すると同様に 'SystemError:がエラーセットでエラーを返しました 'というエラーがスローされます。 lambdifyで修復すると、エラーが発生しないようにするか、パフォーマンス/効率を向上させることを意味しますか?どちらの場合でも、チップのおかげで、私はlambdifyを使うために自分のコードをリファクタリングしようとします。 – mediantis

+1

@nymerion私は 'vectorize'を使って"クイックフィックス "を修正し、lambdifyを使って議論を広げました。 – chthonicdaemon

関連する問題