当我将approx_fprime应用于scipy.minimize时,它不会迭代



我尝试在scipy包中使用最小化函数,如下面的代码所示当我使用jac option = approx_fprime时,迭代为0,优化不起作用。但是当我使用jac option = rosen_der时,它工作了!

import numpy as np
from scipy.optimize import minimize, approx_fprime

def rosen(x):
"""The Rosenbrock function"""
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
def rosen_der(x): 
# derivative 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])
eps = np.sqrt(np.finfo(float).eps)
fprime = lambda x : np.array(approx_fprime(x0, rosen, eps))
res = minimize(rosen, x0, method='CG', jac=fprime, options={'maxiter':10, 'disp': True})
print(res.x)
[ 515.40001106 -197.99999905]
[ 515.4 -198. ]
98.10000000000005
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 98.100000
Iterations: 0
Function evaluations: 33
Gradient evaluations: 21
[1.3 0.7]

我检查了approx_fprime是narray,相同的rosen_der和值也是相同的。为什么优化不起作用?

你的函数fprimex的函数,但近似于x0的导数。因此,在每次迭代中,您都在初始猜测x0处评估梯度。你应该在x处计算/近似导数:

fprime = lambda x : approx_fprime(x, rosen, eps)

注意approx_fprime已经返回了一个np。narray,所以不需要额外的np。数组调用。

同样值得一提的是,你不需要传递近似的导数,因为minimize在默认情况下是通过有限差分来近似它们的,一旦你不传递任何导数,即jac=None。然而,minimize在底层使用approx_derivative而不是approx_fprime,因为它提供了在可变边界上求导数的支持。

最新更新