理解R中optim()函数中maxit参数的含义

6
在下面对optim()的调用中,由于maxit=1,我希望fn()gr()各被评估一次。然而,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 
为什么会这样?是个 bug 吗?或者为什么每次迭代 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。)

1
在 R 邮件列表中可以找到类似的注释,但没有回复。http://r.789695.n4.nabble.com/quot-maxit-quot-argument-not-working-in-optim-function-base-package-quot-td4699708.html - Nairolf
1
测试使用其他值作为“方法”会得到不同的计数。 - Rui Barradas
3个回答

5
一个迭代是优化算法的一个迭代。一个函数评估是对目标函数的单次调用。每个迭代需要多少个函数评估取决于:
  • 正在使用什么算法(例如Nelder-Mead vs BFGS vs. ...)
  • 一个迭代步骤的工作方式
    • 例如,对于Nelder-Mead,一个迭代包括 (1) 反射; (2) [可能] 扩展; (3) [可能] 收缩; (4) [可能] 缩小; 总是有一个评估(反射),但其他步骤取决于第一个子步骤发生了什么
    • 对于L-BFGS-B,我认为涉及一次线搜索...
  • 是否需要通过有限差分计算导数
就这个问题而言,nlminb允许单独控制最大迭代次数和最大评估次数:

'eval.max'允许的目标函数评估的最大数量。默认为200。
'iter.max'允许的最大迭代次数。默认为150。


2
L-BFGS-B 的一个迭代涉及的步骤列表在 Byrd 等人 1995 年的技术报告中给出,第 17 页:http://users.iems.northwestern.edu/~nocedal/PDFfiles/limited.pdf。 - Nairolf

1

1

文档:

请参阅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 代码以确定每个方法将调用您的函数的次数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接