【问题标题】:How to compute objective, gradient and hessian within one function and pass it to scipy.optimize.minimize?如何在一个函数中计算目标、梯度和粗麻布并将其传递给 scipy.optimize.minimize?
【发布时间】:2021-10-07 00:15:43
【问题描述】:

根据docs,如果jac是一个布尔值并且True,那么目标 假设函数fun返回(f, grad),即目标值 和梯度。这对于避免重复计算很有用 目标和梯度中出现的术语。

现在我想知道是否有类似的选项或方法可以实现 对于粗麻布 hess 也是如此,这样目标函数可以返回 一个元组(f, grad, hess),其中hess是hessian矩阵?

这是一个 MWE:

import numpy as np
from scipy.optimize import minimize

def obj_and_grad_and_hess(x):
    obj = np.exp(x) * x**2
    grad = obj + 2*np.exp(x)*x
    hess = obj + 4*np.exp(x)*(x) + 2*np.exp(x)
    return obj, grad, hess

# res = minimize(obj_and_grad_and_hess, x0=[1.0], jac=True, hess=True)

这个问题是 类似于this question,其中 jacobian 函数可以返回 jacobian 和 hessian。

【问题讨论】:

  • 我不明白你为什么要问这个。您从字面上链接到最小化的当前文档,其中显示了该函数支持的所有选项。缺少您所要求的内容是显而易见的(您对提高性能的假设也可能是错误的,因为大多数算法不需要在每个搜索步骤重新计算 Hessian)
  • 我知道缺少此选项。这就是为什么我问是否有另一种方法来实现它。恕我直言,我认为您对性能的陈述是错误的。
  • 如果您不相信文档是完整的,您可以阅读[source] 来测试它。

标签: python scipy scipy-optimize scipy-optimize-minimize


【解决方案1】:

在后台,scipy.optimize.minimize 使用 MemoizeJac 处理jac=True 案例的装饰器。装饰器在每次调用时缓存函数的返回值fgrad。通过从此类继承,您可以以同样的方式实现 MemoizeJacHess 装饰器:

from scipy.optimize.optimize import MemoizeJac

class MemoizeJacHess(MemoizeJac):
    """ Decorator that caches the return vales of a function returning
        (fun, grad, hess) each time it is called. """

    def __init__(self, fun):
        super().__init__(fun)
        self.hess = None

    def _compute_if_needed(self, x, *args):
        if not np.all(x == self.x) or self._value is None or self.jac is None or self.hess is None:
            self.x = np.asarray(x).copy()
            self._value, self.jac, self.hess = self.fun(x, *args)

    def hessian(self, x, *args):
        self._compute_if_needed(x, *args)
        return self.hess

但是,由于尚不支持 hess=True 选项,因此您必须 像这样使用它:

obj = MemoizeJacHess(obj_and_grad_and_hess)
grad = obj.derivative
hess = obj.hessian

res = minimize(obj, x0=[1.0], jac=grad, hess=hess)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-12
    • 2016-05-02
    • 2014-03-22
    • 1970-01-01
    • 2017-07-18
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多