使用梯度函数 R 的数值 Hessian

Numeric Hessian using gradient function R

我需要使用我的梯度函数计算我的函数数值Hessian(编程通过 公式,不是数字)。 numDerivrootSolve 等包使用 numerical 梯度计算 hessian 不满足我的需要。我需要在 内部 执行的事情(我无法调用单独的方法)在 optim 包中,但是处理我的优化任务的唯一方法在 nlopt 包中很好地实现并将其最佳值传递给 optim 以获得 hessian 对我的程序来说太昂贵了。

所以我需要一些函数来计算 Hessian,而不是使用数字梯度(例如,参见这些公式 https://neos-guide.org/content/difference-approximations)。我无法创建这样的函数,因为我不明白如何选择参数 h(增量),我的函数对此非常敏感。我可以在 R 中找到这样的函数或以某种方式从 optim 包中检索它吗?或者至少有人可以解释如何为 h 选择错误最小化值,那么我将自己 post 这个函数?

如果我理解正确,你应该使用 numDeriv::jacobian(),它接受一个 vector-valued 函数并计算一个矩阵(每个元素相对于每个输入的导数),并将其应用于你的分析梯度函数。 jacobian() 确实使用了数值近似(准确地说是理查森外推法),但我没有看到任何其他方法可以从 black-box 梯度函数到 Hessian 矩阵?

您确实需要指定(或使用默认值)数值 'delta' 函数(默认为 1e-4)。另一方面,optim() 用于计算 Hessian 的内部代码也使用有限差分:参见 here and here ...

下面我定义了一个函数,它的梯度函数,还有它的Hessian;此代码显示 jacobian(grad(x)) 与 Hessian 相同(对于特定测试用例)。

library(numDeriv)
x1 <- c(1,1,1)

测试我没有搞砸梯度和 Hessian 函数:

all.equal(grad(f,x1),g(x1)) ## TRUE
all.equal(h(x1),hessian(f,x1)) ## TRUE

我的 Hessian 矩阵和梯度的 Jacobian 矩阵的数值等价性:

all.equal(h(x1),jacobian(g,x1)) ## TRUE

测试函数:

f <- function(x) {
  sin(x[1])*exp(x[2])*x[3]^2
}

g <- function(x) {
  c(cos(x[1])*exp(x[2])*x[3]^2,
    sin(x[1])*exp(x[2])*x[3]^2,
    sin(x[1])*exp(x[2])*2*x[3])
}  

h <- function(x) {
    m <- matrix(NA,3,3)
    m[lower.tri(m,diag=TRUE)] <-
        c(-sin(x[1])*exp(x[2])*x[3]^2,
          cos(x[1])*exp(x[2])*x[3]^2,
          cos(x[1])*exp(x[2])*2*x[3],
    # col 2
           sin(x[1])*exp(x[2])*x[3]^2,
           sin(x[1])*exp(x[3])*2*x[3],
    # col 3
           sin(x[1])*exp(x[2])*2)
    m <- Matrix::forceSymmetric(m,"L")
    m <- unname(as.matrix(m))
    return(m)
}