scipy.differentiate.

hessian#

scipy.differentiate.hessian(f, x, *, tolerances=None, maxiter=10, order=8, initial_step=0.5, step_factor=2.0)[source]#

数值计算函数的Hessian矩阵。

参数:
f可调用对象

需要计算Hessian的函数。函数签名必须为

f(xi: ndarray) -> ndarray

其中 xi 的每个元素都是有限实数。如果需要求导的函数接受额外参数,请对其进行封装(例如使用 functools.partiallambda),然后将封装后的可调用对象传递给 hessianf 不得改变数组 xi。关于向量化以及输入和输出的维度,请参阅“备注”。

x浮点数数组类型

计算Hessian的点。必须至少有一个维度。关于维度和向量化,请参阅“备注”。

tolerances浮点数字典,可选

绝对和相对容差。字典的有效键为

  • atol - 导数的绝对容差

  • rtol - 导数的相对容差

res.error < atol + rtol * abs(res.df) 时,迭代将停止。默认的 atol 是相应 dtype 的最小标准数,默认的 rtol 是相应 dtype 精度值的平方根。

order整数,默认值:8

要使用的有限差分公式的(正整数)阶数。奇数将向上取整到下一个偶数。

initial_step浮点数,默认值:0.5

有限差分导数近似的(绝对)初始步长。

step_factor浮点数,默认值:2.0

每次迭代中步长减小的因子;即,第1次迭代的步长为 initial_step/step_factor。如果 step_factor < 1,则后续步长将大于初始步长;如果小于某个阈值的步长不合意(例如,由于减法抵消误差),这可能会很有用。

maxiter整数,默认值:10

算法执行的最大迭代次数。请参阅“备注”。

返回:
res_RichResult

一个类似于 scipy.optimize.OptimizeResult 实例的对象,具有以下属性。描述以值将为标量的方式编写;但是,如果 f 返回一个数组,则输出也将是相同形状的数组。

success布尔数组

算法成功终止(状态 0)时为 True;否则为 False

status整数数组

表示算法退出状态的整数。

  • 0:算法收敛到指定的容差。

  • -1:误差估计增加,迭代终止。

  • -2:达到最大迭代次数。

  • -3:遇到非有限值。

ddf浮点数组

如果算法成功终止,则为 fx 处的Hessian矩阵。

error浮点数组

误差估计:当前Hessian估计与前一次迭代中估计值之间差异的幅值。

nfev整数数组

f 被评估的点的数量。

属性的每个元素都与 ddf 的相应元素相关联。例如,nfev 的元素 [i, j] 是为了计算 ddf 的元素 [i, j] 而评估 f 的点数。

另请参阅

derivative, jacobian

备注

假设我们希望计算函数 \(f: \mathbf{R}^m \rightarrow \mathbf{R}\) 的Hessian矩阵,我们将变量 m 赋值为 \(m\) 的正整数值。如果我们希望在单个点处评估Hessian,那么

  • 参数 x 必须是形状为 (m,) 的数组

  • 参数 f 必须向量化以接受形状为 (m, ...) 的数组。第一个轴表示 \(f\)\(m\) 个输入;省略号表示的其余轴用于在一次调用中在多个横坐标处评估函数。

  • 参数 f 必须返回形状为 (...) 的数组。

  • 结果对象的属性 dff 将是形状为 (m, m) 的数组,即Hessian矩阵。

此函数在某种意义上也是向量化的,即可以在一次调用中在 k 个点处评估Hessian。在这种情况下,x 将是形状为 (m, k) 的数组,f 将接受形状为 (m, ...) 的数组并返回形状为 (...) 的数组,并且结果的 ddf 属性将具有形状 (m, m, k)。请注意,与 k 个点关联的轴包含在 (...) 表示的轴内。

目前,hessian 是通过嵌套调用 jacobian 实现的。传递给 hessian 的所有选项都用于内部和外部调用,但有一个例外:内部 jacobian 调用中使用的 rtol 会被收紧 100 倍,以期可以忽略内部误差。结果是 rtol 不应设置小于 x 的 dtype 精度值的 100 倍;否则会发出警告。

参考文献

[1]

Hessian 矩阵, 维基百科, https://en.wikipedia.org/wiki/Hessian_matrix

示例

Rosenbrock 函数从 \(\mathbf{R}^m \rightarrow \mathbf{R}\) 映射;SciPy 实现 scipy.optimize.rosen 经过向量化,可以接受形状为 (m, ...) 的数组并返回形状为 ... 的数组。假设我们希望在 [0.5, 0.5, 0.5] 处评估Hessian矩阵。

>>> import numpy as np
>>> from scipy.differentiate import hessian
>>> from scipy.optimize import rosen, rosen_hess
>>> m = 3
>>> x = np.full(m, 0.5)
>>> res = hessian(rosen, x)
>>> ref = rosen_hess(x)  # reference value of the Hessian
>>> np.allclose(res.ddf, ref)
True

hessian 已向量化,可以在一次调用中在多个点处评估Hessian矩阵。

>>> rng = np.random.default_rng()
>>> x = rng.random((m, 10))
>>> res = hessian(rosen, x)
>>> ref = [rosen_hess(xi) for xi in x.T]
>>> ref = np.moveaxis(ref, 0, -1)
>>> np.allclose(res.ddf, ref)
True