Python 如何在Scipy.optimize.minimize中显示结果 如果我们从文档中考虑这个例子: from scipy.optimize import minimize, rosen, rosen_der x0 = [1.3, 0.7, 0.8, 1.9, 1.2] result = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6) print(result)

Python 如何在Scipy.optimize.minimize中显示结果 如果我们从文档中考虑这个例子: from scipy.optimize import minimize, rosen, rosen_der x0 = [1.3, 0.7, 0.8, 1.9, 1.2] result = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6) print(result),python,scipy,Python,Scipy,我们得到以下结果 final_simplex: (array([[ 1.00000002, 1.00000002, 1.00000007, 1.00000015, 1.00000028], [ 0.99999999, 0.99999996, 0.99999994, 0.99999986, 0.99999971], [ 1.00000005, 1.00000007, 1.00000017, 1.00000031, 1.00000063],

我们得到以下结果

final_simplex: (array([[ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028],
       [ 0.99999999,  0.99999996,  0.99999994,  0.99999986,  0.99999971],
       [ 1.00000005,  1.00000007,  1.00000017,  1.00000031,  1.00000063],
       [ 1.00000004,  1.00000008,  1.00000013,  1.00000025,  1.00000047],
       [ 0.99999999,  0.99999996,  0.99999994,  0.99999984,  0.99999963],
       [ 1.00000005,  1.00000004,  1.00000003,  1.00000003,  1.00000004]]), array([  1.94206402e-13,   2.44964782e-13,   3.10422870e-13,
         3.37952410e-13,   5.52173609e-13,   7.16586838e-13]))
           fun: 1.9420640199868412e-13
       message: 'Optimization terminated successfully.'
          nfev: 494
           nit: 295
        status: 0
       success: True
             x: array([ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028])

如您所见,迭代次数为295次。我的问题是如何在每次迭代中获得x的值?

通常的方法是使用定制的

回调:可调用,可选

在每次迭代后调用,称为回调(xk),其中xk是当前参数向量

现在,使用此功能非常简单:

history = []
def callback(x):
    fobj = rosen(x)
    history.append(fobj)

result = minimize(rosen, x0, method='Nelder-Mead', tol=1e-6, callback=callback)
print(history)
但是正如上面评论中两个链接中的第一个(好链接!)中提到的,这种方法使用额外的函数求值!(其来源显然基于经典的软件开发设计原则问题:要使用多少抽象?)

根据您的任务,功能评估可能成本高昂(如果不是,请忽略以下内容)

在这种情况下,您可以使用缓存以前计算的值,而不总是重新计算它们

现在,至少对于您的优化器“Nelder Mead”,一个无梯度优化器,您需要缓存多个值,以与无回调解决方案相比较(因为不知何故需要旧值)。这可能取决于所选择的最小化方法(以及一些内部构件)

当使用数值微分时,使用一些梯度记忆,因为这非常昂贵。但这段代码只缓存最后一个值,这对您的情况不起作用(NM不同)

因此,我们可以构建自己的记忆缓存,仅基于函数(没有梯度,因为没有使用):

使用回调和缓存大小8调用:

final_simplex: (array([[ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028],
      [ 0.99999999,  0.99999996,  0.99999994,  0.99999986,  0.99999971],
      [ 1.00000005,  1.00000007,  1.00000017,  1.00000031,  1.00000063],
      [ 1.00000004,  1.00000008,  1.00000013,  1.00000025,  1.00000047],
      [ 0.99999999,  0.99999996,  0.99999994,  0.99999984,  0.99999963],
      [ 1.00000005,  1.00000004,  1.00000003,  1.00000003,  1.00000004]]), array([  1.94206402e-13,   2.44964782e-13,   3.10422870e-13,
        3.37952410e-13,   5.52173609e-13,   7.16586838e-13]))
          fun: 1.9420640199868412e-13
      message: 'Optimization terminated successfully.'
         nfev: 494
          nit: 295
       status: 0
      success: True
            x: array([ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028])
iteration fun(x)
[array([ 516.14978061]), array([ 1.16866125]), array([ 0.00135733]), array([  6.48182410e-05]), array([  1.03326372e-06]), array([  7.12094933e-10])]
504
缓存为24(不推荐;仅用于演示):

现在,这里显然存在一个折衷,因为我们存储了大小相同的缓存:

  • C#u SIZE*N
    #x向量
  • C_SIZE*1
    #趣味值
我们在每次调用中对
C_SIZE*N
计算一个线性运算

这是否值得,以及如何选择缓存大小,取决于您的函数、最小值,可能还取决于您的参数

请记住,所选择的方法是基于这样一个想法:基于numpy的线性计算量可能比使用基于纯python的logn(或类似)算法更快

(未全面检查备忘录代码!)

可能与或重复
final_simplex: (array([[ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028],
      [ 0.99999999,  0.99999996,  0.99999994,  0.99999986,  0.99999971],
      [ 1.00000005,  1.00000007,  1.00000017,  1.00000031,  1.00000063],
      [ 1.00000004,  1.00000008,  1.00000013,  1.00000025,  1.00000047],
      [ 0.99999999,  0.99999996,  0.99999994,  0.99999984,  0.99999963],
      [ 1.00000005,  1.00000004,  1.00000003,  1.00000003,  1.00000004]]), array([  1.94206402e-13,   2.44964782e-13,   3.10422870e-13,
        3.37952410e-13,   5.52173609e-13,   7.16586838e-13]))
          fun: 1.9420640199868412e-13
      message: 'Optimization terminated successfully.'
         nfev: 494
          nit: 295
       status: 0
      success: True
            x: array([ 1.00000002,  1.00000002,  1.00000007,  1.00000015,  1.00000028])
iteration fun(x)
[array([ 516.14978061]), array([ 1.16866125]), array([ 0.00135733]), array([  6.48182410e-05]), array([  1.03326372e-06]), array([  7.12094933e-10])]
504
      nfev: 494
       nit: 295
    status: 0
   success: True
...
494