如何在循环中放置numpy norm condition?

l7wslrjt  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(131)

我试图在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])

5m1hhzi4

5m1hhzi41#

找到了答案,我需要在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)

字符串

相关问题