【问题标题】:scipy.optimize.minimize : compute hessian and gradient togetherscipy.optimize.minimize : 一起计算 hessian 和梯度
【发布时间】:2015-07-12 06:27:57
【问题描述】:

scipy.optimize.minimize 函数基本上实现了与 MATLAB 的“fminunc”函数等效的函数,用于查找函数的局部最小值。

在 scipy 中,梯度函数和 Hessian 函数是分开的。

res = minimize(rosen, x0, method='Newton-CG',
...                jac=rosen_der, hess=rosen_hess,
...                options={'xtol': 1e-30, 'disp': True})

但是,我有一个函数,其 Hessian 和梯度共享相当多的计算,我想一起计算 Hessian 和梯度,以提高效率。在 fminunc 中,目标函数可以写成返回多个值,即:

function [ q, grad, Hessian ] = rosen(x)

有没有一种好方法可以将一个函数传递给 scipy.optimize.minimize 以一起计算这些元素?

【问题讨论】:

    标签: python matlab numpy optimization scipy


    【解决方案1】:

    您可以使用缓存解决方案,但首先 numpy 数组不可散列,其次您只需要缓存几个值,具体取决于算法是否在 x 上反复多次。如果算法只从一个点移动到下一个点,您可以通过这种方式仅缓存最后一个计算点,您的 f_hesf_jac 只是 lambda 接口,用于计算两者的更长函数:

    import numpy as np
    
    # I choose the example f(x,y) = x**2 + y**2, with x,y the 1st and 2nd element of x below:
    def f(x):
        return x[0]**2+x[1]**2
    
    def f_jac_hess(x):
        if all(x==f_jac_hess.lastx):
            print('fetch cached value')
            return f_jac_hess.lastf
        print('new elaboration')
        res = array([2*x[0],2*x[1]]),array([[2,0],[0,2]])
    
        f_jac_hess.lastx = x
        f_jac_hess.lastf = res
    
        return res
    
    f_jac_hess.lastx = np.empty((2,)) * np.nan
    
    f_jac = lambda x : f_jac_hess(x)[0]
    f_hes = lambda x : f_jac_hess(x)[1]
    

    现在第二个调用将缓存保存的值:

    >>> f_jac([3,2])
    new elaboration
    Out: [6, 4]
    >>> f_hes([3,2])
    fetch cached value
    Out: [[2, 0], [0, 2]]
    

    然后你称它为:

    minimize(f,array([1,2]),method='Newton-CG',jac = f_jac, hess= f_hes, options={'xtol': 1e-30, 'disp': True})
    

    【讨论】:

    • 谢谢,我怀疑解决方案会涉及某种全局变量。似乎重新编写 _minimize_trust_ncg() 函数以接收所有三个函数的函数生成器,就像 fminunc 一样有用且相当简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 2020-03-31
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多