我有一个函数,我正在使用R中的 optimx
函数进行优化(我也打开使用 optim
,因为我试图这样做) . 我有一个渐变,我传递给 optimx
(希望)与不使用渐变相比更快收敛 . 函数和梯度都使用从每个新参数集计算的许多相同量 . 特别是这些量中的一个在计算上非常昂贵,并且它试图找到一种计算该量的方法,然后将其传递给函数和梯度 .
所以这就是我在做的事情 . 到目前为止,这是有效的,但效率低下:
optfunc<-function(paramvec){
quant1<-costlyfunction(paramvec)
#costlyfunction is a separate function that takes a while to run
loglikelihood<-sum(quant1)**2
#not really squared, but the log likelihood uses quant1 in its calculation
return(loglikelihood)
}
optgr<-function(paramvec){
quant1<-costlyfunction(paramvec)
mygrad<-sum(quant1) #again not the real formula, just for illustration
return(mygrad)
}
optimx(par=paramvec,fn=optfunc,gr=optgr,method="BFGS")
我试图找到一种方法,每次迭代 optimx
只计算一次 quant1
. 似乎第一步是将 fn
和 gr
组合成一个函数 . 我认为this question的答案可能对我有所帮助,因此我将优化记录为:
optfngr<-function(){
quant1<-costlyfunction(paramvec)
optfunc<-function(paramvec){
loglikelihood<-sum(quant1)**2
return(loglikelihood)
}
optgr<-function(paramvec){
mygrad<-sum(quant1)
return(mygrad)
}
return(list(fn = optfunc, gr = optgr))
}
do.call(optimx, c(list(par=paramvec,method="BFGS",optfngr() )))
在这里,我收到错误:“optimx.check中的错误(par,optcfg $ ufn,optcfg $ ugr,optcfg $ uhess,lower,:无法在初始参数下评估函数 . ”当然,我的代码在这里有明显的问题所以,我正在考虑回答以下任何或所有问题可能会有所启发:
-
我通过
paramvec
作为optfunc
和optgr
的唯一参数,以便optimx
知道paramvec
是需要迭代的 . 但是,我不知道如何将quant1
传递给optfunc
和optgr
. 如果我尝试传递quant1
,那么optimx
会无法正确识别参数向量吗? -
我将
optfunc
和optgr
包装成一个函数,因此数量quant1
将与两个函数存在于同一个函数空间中 . 也许我可以避免这种情况,如果我能找到一种方法从optfunc
返回quant1
,然后将其传递给optgr
. 这可能吗?我没有'm thinking it',因为optimx
的文档很清楚该函数需要返回一个标量 . -
我知道我可以使用
optimx
的点参数作为额外的参数参数,但我知道这些是针对固定参数的,而不是随每次迭代而改变的参数 . 除非还有办法操纵这个?
提前致谢!
1 回答
你的方法接近你想要的,但不是很正确 . 您想在
optfn(paramvec)
或optgr(paramvec)
内调用costlyfunction(paramvec)
,但仅在paramvec
已更改时调用 . 然后,您希望将其值保存在封闭框架中,以及用于执行此操作的paramvec
的值 . 就是这样的:我使用
<<-
来对封闭框架进行赋值,并修复了do.call
第二个参数 .执行此操作称为"memoization"(或某些语言环境中的"memoisation";请参阅http://en.wikipedia.org/wiki/Memoization),并且有一个名为
memoise
的程序包可以执行此操作 . 它跟踪了之前调用costlyfunction
的大量(或全部?),因此如果paramvec
只占用少量值,那将特别好 . 但我认为它赢了't be so good in your situation because you' ll可能只会对costlyfunction
进行少量重复调用,然后再也不会使用相同的paramvec
.