我正在尝试在 python 中实现具有最佳步骤的梯度下降方法,但出现此错误:
AttributeError: 'Float' object has no attribute 'sqrt'
if (np.linalg.norm(np.array(dk)) < eps): break
File <__array_function__ internals>:200 in norm
File C:\ProgramData\anaconda3\Lib\site-packages\numpy\linalg\linalg.py:2512 in norm
ret = sqrt(sqnorm)
TypeError: loop of ufunc does not support argument 0 of type Float which has no callable sqrt method
这是我的代码:
import sympy as sp
import numpy as np
def grad(f):
X = f.free_symbols
Y = [f.diff(xi) for xi in X]
return [x_k for x_k in X], Y
def descente_pas_opti(f, X0, eps = 1e-6):
Xk = X0
fonction = sp.sympify(f)
X, gradform = grad(fonction)
r=sp.symbols('r')
dform= np.array([-df_k for df_k in gradform])
while True:
dk=np.array(
[df_k.subs(
[(X[k],Xk[k]) for k in range(len(X))])
for df_k in dform]
)
rho = sp.solve(
np.dot(
[df_k.subs(
[(X[k], Xk[k] + r*dk[k]) for k in range (len(X))] )
for df_k in gradform]
, dk)
, r)[0]
Xk = [Xk[0]+rho*dk[0], Xk[1]+rho*dk[1]]
if (np.linalg.norm(dk) < eps): break
return Xk
我在循环外尝试了一些单独的测试,所有测试都有效,这意味着我在循环内调用norm方法时遇到问题。
另外,np.linalg.norm(dk)在循环外计算时,在第一次迭代时返回~25.07,这是我所期望的,但当它在循环中时,它不起作用。
这是我给出的参数:
descente_pas_opti('5*x**2 + 0.5*y**2 -3*(x + y)', [-2,-7])
找到答案,我需要在 dk 中添加 dtype = np.float32 :
dk=np.array(
[df_k.subs(
[(X[k],Xk[k]) for k in range(len(X))])
for df_k in dform]
,dtype = np.float32)