2016-07-23 7 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 

ошибка, что я получаю

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

Однако, называя те же самые строки, с той же f_err, l_scales и x1, x2 в консоли сразу после ошибки вне, как-то делает не создавать ошибок.

Мне не удалось найти сообщение, ссылающееся на ошибку объекта «Нуль», и не найденные мной «Zero», похоже, не применимы к моему делу.

РЕДАКТИРОВАТЬ: Это было немного не в информации, так что вот фактический (извлеченный) исполняемый пример с образцами данных, которые я взял прямо из неудачного прогона, который при работе изолированно работает нормально/я не могу воспроизвести ошибку за исключением времени выполнения.

Обратите внимание, что функция sqeucld_dist ниже довольно плохая, и вместо этого я должен использовать cdist scipy. Однако, поскольку я использую символы sympy для матричных элементарных градиентов с более чем 15 частными производными в моих реальных данных, 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 

Любая помощь очень ценится!

+2

'Zero' - это симплексный объект (http://docs.sympy.org/latest/modules/core.html#sympy.core.numbers.Zero), поэтому я подозреваю, что это другой случай, когда numpy и scipy-код не могут обрабатывать объекты sympy. Проверьте тип аргумента, который вы передаете, на 'numpy.exp'. Вероятно, вам придется убедиться, что ваше символическое выражение преобразуется в числовые значения перед вызовом функций numpy. –

+0

Спасибо за понимание. В конечном итоге я избавился от всех типов Scipy, «загрязняющих» мои массивы numpy, после трассировки/отладки всех переменных, рассеянных по многим реализованным уравнениям. – mediantis

ответ

1

Вот как воспроизвести ошибку, вы видите:

import sympy 
import numpy 

zero = sympy.sympify('0') 

numpy.exp(zero) 

Вы увидите то же самое исключение, вы видите.

Вы можете исправить это (неэффективно), изменив код на следующее, чтобы сделать вещи плавающей точкой.

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.

Вот пример того, как lambdify может быть использован на частичном г

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 теперь [2*x, cos(y), 1], список выражений SymPy. Чтобы создать функцию, которая будет оценивать это численно при определенном наборе значений, мы используем lambdify следующим образом (прохождение 'numpy' в качестве аргумента, как это означает, что использовать numpy.cos, а не sympy.cos):

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

Теперь derivative_calc(1, 2, 3) вернется [2, -0.41614683654714241, 1] , Это int s и numpy.float64 s.

Примечание стороны:np.exp(M) будет вычислять поэлементное показатель каждого из элементов M. Если вы пытаетесь сделать матричную экспоненту, вам нужно np.linalg.exmp.

+0

Благодаря @chthonicdaemon исправление as is не работает как (i-j) - это массив numpy, а не скаляр Python, но установка dtype для float32 аналогичным образом вызывает «SystemError: », который возвращает результат с ошибкой set' error. Когда вы говорите, исправить с lambdify, вы имеете в виду, что это предотвратит возникновение ошибки или улучшит производительность/эффективность? В любом случае, спасибо за подсказку, я попробую рефакторинг моего кода, чтобы использовать lambdify. – mediantis

+1

@nymerion Я исправил «быстрое исправление» с помощью «векторизации» и расширил обсуждение использования lambdify. – chthonicdaemon

 Смежные вопросы

  • Нет связанных вопросов^_^