了解 R 中 optim() 的最大参数

Understanding the maxit argument of optim() in R

在接下来对 optim() 的调用中,我希望对 fn() 进行一次评估,对 gr() 进行一次评估,因为 maxit=1。但是,fn()gr() 各计算 7 次。

optim(par=1000, fn=function(x) x^2, gr=function(x) 2*x,
      method="L-BFGS-B", control=list(maxit=1))$counts
function gradient 
       7        7 

这是为什么?这是一个错误吗?或者为什么 optim() 对一次迭代进行 7 次评估?


更详细的输出:

optim(par=1000,
      fn=function(x) { cat("f(", x, ")", sep="", fill=TRUE); x^2 },
      gr=function(x) { cat("g(", x, ")", sep="", fill=TRUE); 2*x },
      method="L-BFGS-B", control=list(maxit=1))$counts
f(1000)
g(1000)
f(999)
g(999)
f(995)
g(995)
f(979)
g(979)
f(915)
g(915)
f(659)
g(659)
f(1.136868e-13)
g(1.136868e-13)
function gradient 
       7        7 

(使用 R 版本 3.5.0 测试。)

迭代是优化算法的一次迭代。 函数求值是对objective函数的一次调用。每次迭代需要多少次函数评估取决于:

  • 正在使用什么算法(例如 Nelder-Mead vs BFGS vs. ...)
  • 一个迭代步骤是如何工作的
    • 例如对于 Nelder-Mead an iteration comprises (1) 反思; (2) [也许] 扩张; (3) [也许]收缩; (4) [也许]收缩;总是有一个评估(反思),但其他步骤取决于第一个子步骤中发生的情况
    • for L-BFGS-B 我认为涉及线搜索...
  • 导数是否需要用有限差分计算

对于它的价值,nlminb 允许单独控制最大迭代次数和最大评估次数:

‘eval.max’ Maximum number of evaluations of the objective function allowed. Defaults to 200.
‘iter.max’ Maximum number of iterations allowed. Defaults to 150.

文档:

请参阅 https://stat.ethz.ch/R-manual/R-devel/library/stats/html/optim.html 了解有关如何判断的更多信息:

convergence 
An integer code. 0 indicates successful completion (which is always the case for "SANN" and "Brent"). Possible error codes are

1      indicates that the iteration limit maxit had been reached.

运行 您的代码(但查看 convergence 而不是 counts),我得到:

> optim(par=1000,
+       fn=function(x) { cat("f(", x, ")", sep="", fill=TRUE); x^2 },
+       gr=function(x) { cat("g(", x, ")", sep="", fill=TRUE); 2*x },
+       method="L-BFGS-B", control=list(maxit=1))$convergence
f(1000)
g(1000)
f(999)
g(999)
f(995)
g(995)
f(979)
g(979)
f(915)
g(915)
f(659)
g(659)
f(1.136868e-13)
g(1.136868e-13)
[1] 1

所以它 运行 一次迭代并停止,返回 convergence = 1。另一个关键在 counts 描述中,它说:

counts  
A two-element integer vector giving the number of calls to fn and gr respectively. 
This excludes those calls needed to compute the Hessian, if requested, and any calls 
to fn to compute a finite-difference approximation to the gradient.

暗示它调用了很多次来弄清楚发生了什么。您可以查看 c 代码以确定每个方法将调用您的函数的次数。

在这里你可以找到很好的解释。

https://stat.ethz.ch/pipermail/r-devel/2010-August/058081.html

关键是函数在迭代过程中被评估了不止一次。 您可以看到将 maxit 增加到 2 会导致另一个函数评估。