Numpy - AttributeError: объект 'Zero' не имеет атрибута 'exp'
У меня возникают проблемы с устранением несоответствия между чем-то, что ломается во время выполнения, но с использованием точно таких же данных и операций в консоли Python, чтобы все работало нормально.
# 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 в консоли сразу после того, как произошла ошибка, как-то не приводит к ошибкам.
Я не смог найти сообщение, конкретно ссылающееся на ошибку объекта "Ноль", и найденные мной сообщения, отличные от "Ноль", похоже, не применимы к моему случаю.
РЕДАКТИРОВАТЬ: Это было немного не хватает информации, так что вот фактический (извлеченный) исполняемый пример с примерами данных, которые я взял прямо из неудачного запуска, который при запуске в изоляции работает нормально / я не могу воспроизвести ошибку, кроме как во время выполнения.
Обратите внимание, что приведенная ниже функция 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
Любая помощь с благодарностью!
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 может использоваться на частичном 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
сейчас [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
с и numpy.float64
s.
Примечание: np.exp(M)
будет рассчитывать поэлементный показатель каждого из элементов M
, Если вы пытаетесь сделать экспоненциальную матрицу, вам нужно np.linalg.exmp
,