梯度下降陷入局部最小值?

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

我正在运行梯度下降来找到非线性方程组的根,我想知道如何检测该方法是否陷入局部最小值,因为我相信在我使用的设置下可能会出现这种情况?我的初始值为 [-2, -1],容差为 10^-2 和 20 次迭代。我读到的一件事是,如果残差开始持平或开始极其缓慢地减少,则可能表明该方法陷入局部最小值,但我并不完全确定。我已经将我的残差及其迭代绘制为每次迭代的迭代值,我想知道如何知道它是否停留在局部最小值。

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 jacb(x):
    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


iterates, residuals = GradientDescent('system', 'jacb', np.array([[-2],[-1]]), 1e-2, 20, 0);

FullGradientDescent.py

我通常使用 20 次迭代进行测试,但我做了 200 次来说明残差的减慢

Marat建议使用动量GD。 代码更改:

dn = 0
gamma = 0.8
dn_prev = 0
while (norm(F,2) > tol and n <= max_iterations):
    J = eval(jac)(x,2,fnon,F,*fnonargs)
    residuals.append(norm(F,2))
    
    dn = gamma * dn_prev+2*(np.matmul(np.transpose(J), F))
    dn_prev = dn

    lamb = 0.01       
    x = x - lamb * dn

使用动量 GD 进行残差

lastchance建议做一个等值线图,这似乎显示了算法的行为,但它仍然没有收敛?

python numerical-methods gradient-descent root-finding
1个回答
0
投票

如果你绘制 F[] 向量的大小,那么你会得到:

你可以通过单点迭代得到一个根......有很多欠松弛。

from math import cos, sin, sqrt

def f( x, y ):
    return [ x ** 2 + 2 * y ** 2 + sin(2 * x), x ** 2 + cos(x + 5 * y) - 1.2 ]

x, y = -0.8, 0.0
F = f( x, y )
eps = 1.0e-15
underrelax = 0.1

while abs( F[0] ) + abs( F[1] ) > eps:
   xold, yold = x, y
   y =  sqrt( ( - x ** 2 - sin( 2 * x ) ) / 2 )
   x = -sqrt( 1.2 - cos( x + 5 * y ) )
   x = xold + underrelax * ( x - xold )
   y = yold + underrelax * ( y - yold )
   F = f( x, y )
   print( x, y, F[0], F[1] )

print( "Root at ", x, y )

输出

...
Root at  -0.8405629295980004 0.3790605689518969
© www.soinside.com 2019 - 2024. All rights reserved.