梯度下降残差

Gradient descent residual

提问人:blov 提问时间:11/17/2023 最后编辑:blov 更新时间:11/17/2023 访问量:45

问:

我已经实现了梯度下降法来寻找非线性方程组的根,我想知道残差是如何确定的?残差只是欧几里得范数(2-范数)吗?我正在尝试绘制残差以查看随时间的变化,但我对该术语以及您如何计算它感到非常困惑。如果我的残差假设是正确的,我已经绘制了它并在下面显示。如果我的理解是正确的,这表明算法停滞不前,因为在迭代 1 左右之后,每次迭代的误差都没有显着减少,导致第一次迭代后出现这条平线?norm(F,2)norm(F,2)

import numpy as np
import array
from numpy.linalg import norm

def gradient_descent(fnon, jac, x0, tol, maxk, maxm, *args):
    k = 0
    x = x0

    F = eval(fnon)(x,*args)

    residuals = []
    arr = []
    arr.append(x)
    
    while (norm(F,2) > tol and k <= maxk):
        J = eval(jac)(x,2,fnon,F,*args)
        delta = -2 * np.matmul(np.transpose(J), F) #
        residuals.append(norm(F,2))
        lamb = 0.01       
        x = x + lamb * delta
        F = eval(fnon)(x,*args)
        arr.append(x)
        k += 1
    if (k >= maxk):
        print('No root found')
    else:
        print('Found root: ')
        print(x)
        
    return(are), residuals

def system(x):
    F = np.zeros((2,1), dtype=np.float64)
    F[0] = x[0]*x[0] + 2*x[1]*x[1] + math.sin(2*x[0])
    F[1] = x[0]*x[0] + math.cos(x[0]+5*x[1]) - 1.2
    return F

def jacob(x,n,fnon,F0,*args):
    J = np.zeros((2,2), dtype=np.float64)
    J[0,0] = 2*(x[0]+math.cos(2*x[0]))
    J[0,1] = 4*x[1]
    J[1,0] = 2*x[0]-math.sin(x[0]+5*x[1])
    J[1,1] = -5*math.sin(x[0]+5*x[1])
    return J

arr, residuals = gradient_descent('system', 'jacob', np.array([[-2],[-1]]), 1e-2, 20, 0)

绘图范数:

Plotting norm(F,2)

Python 数值方法 梯度下降 收敛

评论

0赞 César Debeunne 11/17/2023
看起来你的函数中没有填充残差,你确定你的代码吗?gradient_descent
0赞 blov 11/17/2023
@CésarDebeunne感谢您的回复!我已经更新了代码。我没有一开始就将其添加到代码中,因为我不确定它是否正确。范数(F,2)算不算残差?
0赞 César Debeunne 11/17/2023
在这种情况下,不可以。如果它是残差,你会把它包括在你的雅可比计算中。残差只是您的目标与当前值之间的差值:这里您的目标是 [0;0] 所以残差是函数的值

答: 暂无答案