【发布时间】:2017-08-05 01:00:36
【问题描述】:
我尝试在 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以产生非常接近的结果 解决方案
或者因为
我需要做一些特殊的特征缩放。
(Ps。我还尝试绘制二维图,其中函数的值在 y 轴上,迭代次数在 x 轴上以“调试”梯度下降,但即使我得到了一个漂亮的下坡图,解还是不是很接近。)
【问题讨论】:
标签: python numpy optimization scipy gradient-descent