我试图在rosenbrock函数上测试我的梯度下降程序。但无论我如何调整自己的学习率(step
参数),精度(precision
参数)和迭代次数(iteration
参数),我都无法获得非常接近的结果。多元标量函数的梯度下降优化
import numpy as np
def minimize(f, f_grad, x, step=1e-3, iterations=1e3, precision=1e-3):
count = 0
while True:
last_x = x
x = x - step * f_grad(x)
count += 1
if count > iterations or np.linalg.norm(x - last_x) < precision:
break
return x
def rosenbrock(x):
"""The Rosenbrock function"""
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
def rosenbrock_grad(x):
"""Gradient of Rosenbrock function"""
xm = x[1:-1]
xm_m1 = x[:-2]
xm_p1 = x[2:]
der = np.zeros_like(x)
der[1:-1] = 200*(xm-xm_m1**2) - 400*(xm_p1 - xm**2)*xm - 2*(1-xm)
der[0] = -400*x[0]*(x[1]-x[0]**2) - 2*(1-x[0])
der[-1] = 200*(x[-1]-x[-2]**2)
return der
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
minimize(rosenbrock, rosenbrock_grad, x0, step=1e-6, iterations=1e4, precision=1e-6)
例如,像上面的代码给我array([ 1.01723267, 1.03694999, 1.07870143, 1.16693184, 1.36404334])
。但如果我使用scipy.optimize
中的任何内置优化方法,我可以得到非常接近的答案或完全相等array([ 1., 1., 1., 1., 1.])
(这是真实的答案)。
但是,如果我在我的程序中使用非常小的step
,precision
和非常大的iterations
,计算只需要在我的计算机上永久存在。
我不知道这是由于
在我的程序中的任何错误
或者仅仅因为
梯度下降是低效这里的要求很低
step
,precision
和非常大的iterations
产生非常接近的 解决方案
,或者因为
我需要做一些特殊的功能扩展。
(聚苯乙烯。我还试图绘制二维图,其中的函数值是在y轴上和迭代次数是在X轴上为“调试”梯度下降,但即使我得到一个nice-解决方案仍然不是非常接近。)
赞赏。我想知道如果我选择了固定的学习速率,但它很小,我会在迭代之后仍然超出问题的范围吗? – Nicholas