如何将 numpy 范数条件放入循环中?

问题描述 投票:0回答:1

我正在尝试在 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])
python numpy sympy
1个回答
0
投票

找到答案,我需要在 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)
© www.soinside.com 2019 - 2024. All rights reserved.