Python:问题更新解决方案向量和梯度下降方法的步长大小

发布于 2025-01-31 05:55:43 字数 1708 浏览 3 评论 0 原文

我有一个三个方程式的系统,可以简化其正方形的总和。

Z = (3*x-cos(y*z)-(1/2))**2 + ((x**2)-625*(y**2))**2 + (exp(-x*y) + 20*z + (10*pi - 3)/3)**2

我已经设法计算了梯度,其评估和搜索方向。但是由于某种原因,只有第一个迭代才能返回所需的结果,在随后的迭代中,相同的解决方案向量和两个不同的步骤尺寸一遍又一遍地重复。我已经试图改变它们的更新方式,但我没有任何更改。

def grad_descent(f,v,u,er,it):
  g = grad(f,v)
  print('  0 {:8.5f} {:8.5f} {:8.5f}'.format(u[0],u[1],u[2]))
  for k in range(it): 
    c = ev_grad(g,v,u)
    fm = ev_sol(f,v,u)
    s = cal_step(f,g,v,u)
    uk = []
    for i in range(len(c)):
      uk += [float(u[i]) - s*float(c[i])]
    u = uk.copy()
    print('{:3d} {:8.5f} {:8.5f} {:8.5f} {:12.5e} {:8.5f}'.format(k+1,u[0],u[1],u[2],float(fm),s))

这是我的结果。

0  0.00000  0.00000  0.00000

1  0.01125  0.00000 -0.52360  1.11912e+02  0.00125

2  0.01125  0.00000 -0.52360  2.14989e+00  0.00000

3  0.01125  0.00000 -0.52360  2.14989e+00  0.00000

4  0.01125  0.00000 -0.52360  2.14989e+00 -0.00000

5  0.01125  0.00000 -0.52360  2.14989e+00  0.00000

6  0.01125  0.00000 -0.52360  2.14989e+00 -0.00000

.....

我最怀疑有一个错误的地方,我得到了步骤大小。

def cal_step(f,g,v,u):
  c = ev_grad(g,v,u)
  t = Symbol('t')
  xt = []
  for i in range(len(v)):
    xt += [float(u[i]) - t*float(c[i])]
  fs = f.subs(v[0],u[0])
  for i in range(1,len(v)):
    fs = fs.subs(v[i],xt[i])
  df = diff(fs,t)
  ddf = diff(df,t)
  s = 1
  for i in range(5):
    s = s - float(df.subs(t,s))/float(ddf.subs(t,s))
  return(s)

该程序在COLAB中的链接,以防万一有必要对其进行审查:

I have a system of three equations that simplifies to the sum of their squares, Z.

Z = (3*x-cos(y*z)-(1/2))**2 + ((x**2)-625*(y**2))**2 + (exp(-x*y) + 20*z + (10*pi - 3)/3)**2

I have already managed to calculate the gradient, its evaluation and the search direction. But for some reason, only the first iteration returns the desired result, and in subsequent iterations the same vector of solutions and two different step sizes are repeated over and over again. I already tried to change the way they are updated but I don't get any change.

def grad_descent(f,v,u,er,it):
  g = grad(f,v)
  print('  0 {:8.5f} {:8.5f} {:8.5f}'.format(u[0],u[1],u[2]))
  for k in range(it): 
    c = ev_grad(g,v,u)
    fm = ev_sol(f,v,u)
    s = cal_step(f,g,v,u)
    uk = []
    for i in range(len(c)):
      uk += [float(u[i]) - s*float(c[i])]
    u = uk.copy()
    print('{:3d} {:8.5f} {:8.5f} {:8.5f} {:12.5e} {:8.5f}'.format(k+1,u[0],u[1],u[2],float(fm),s))

This are my results.

0  0.00000  0.00000  0.00000

1  0.01125  0.00000 -0.52360  1.11912e+02  0.00125

2  0.01125  0.00000 -0.52360  2.14989e+00  0.00000

3  0.01125  0.00000 -0.52360  2.14989e+00  0.00000

4  0.01125  0.00000 -0.52360  2.14989e+00 -0.00000

5  0.01125  0.00000 -0.52360  2.14989e+00  0.00000

6  0.01125  0.00000 -0.52360  2.14989e+00 -0.00000

.....

Where I most suspect there is an error is in the part where I get the step size.

def cal_step(f,g,v,u):
  c = ev_grad(g,v,u)
  t = Symbol('t')
  xt = []
  for i in range(len(v)):
    xt += [float(u[i]) - t*float(c[i])]
  fs = f.subs(v[0],u[0])
  for i in range(1,len(v)):
    fs = fs.subs(v[i],xt[i])
  df = diff(fs,t)
  ddf = diff(df,t)
  s = 1
  for i in range(5):
    s = s - float(df.subs(t,s))/float(ddf.subs(t,s))
  return(s)

Link of the program in Colab in case it is necessary to review it:

https://colab.research.google.com/drive/1bNUNMmuZ_9sMg5HIFggYcF9j5OLwmIiX?usp=sharing

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文