gpt4 book ai didi

R优化: Pass value from function to gradient with each iteration

转载 作者:行者123 更新时间:2023-12-04 01:55:34 25 4
gpt4 key购买 nike

我有一个函数,我正在使用 optimx 进行优化R 中的函数(我也愿意使用 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")

我正在尝试找到一种方法来计算 quant1每次迭代 optimx 时只有一次.似乎第一步是合并 fngr成一个单一的功能。我想到了 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是需要迭代的。但是,我不知道如何通过quant1optfuncoptgr .如果我尝试通过 quant1 是真的吗? ,然后 optimx会不会正确识别参数向量?
  • 我包了optfuncoptgr合为一个函数,使数量 quant1将与两个函数存在于相同的函数空间中。如果我能找到返回 quant1 的方法,也许我可以避免这种情况。来自 optfunc , 然后将其传递给 optgr .这可能吗?我认为不是,因为 optimx 的文档很清楚该函数需要返回一个标量。
  • 我知道我也许可以使用 optimx 的点参数。作为额外的参数参数,但我知道这些是固定参数,而不是每次迭代都会改变的参数。除非也有办法操纵这个?

  • 提前致谢!

    最佳答案

    您的方法接近您想要的,但并不完全正确。您想调用costlyfunction(paramvec)来自optfn(paramvec)optgr(paramvec) , 但仅当 paramvec已经改变。然后你想将它的值保存在封闭的框架中,以及 paramvec 的值那是用来做的。也就是说,像这样:

    optfngr<-function(){
    quant1 <- NULL
    prevparam <- NULL

    updatecostly <- function(paramvec) {
    if (!identical(paramvec, prevparam)) {
    quant1 <<- costlyfunction(paramvec)
    prevparam <<- paramvec
    }
    }
    optfunc<-function(paramvec){
    updatecostly(paramvec)
    loglikelihood<-sum(quant1)**2
    return(loglikelihood)
    }
    optgr<-function(paramvec){
    updatecostly(paramvec)
    mygrad<-sum(quant1)
    return(mygrad)
    }
    return(list(fn = optfunc, gr = optgr))
    }

    do.call(optimx, c(list(par=paramvec,method="BFGS"),optfngr() ))

    我用了 <<-对封闭框架进行分配,并修复您的 do.call第二个论点。

    这样做被称为“memoization”(或在某些语言环境中为“memoisation”;参见 http://en.wikipedia.org/wiki/Memoization),并且有一个名为 memoise 的包这样做。它跟踪许多(或全部?)以前调用 costlyfunction 的结果。 , 所以如果 paramvec 会特别好只取少量值。但我认为在你的情况下它不会那么好,因为你可能只会对 costlyfunction 进行少量重复调用。然后永远不要使用相同的 paramvec再次。

    关于R优化: Pass value from function to gradient with each iteration,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50897490/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com