使用R optimx中断后如何恢复内部存储的迭代值?
手动中断optimx优化后能否恢复最后一次迭代结果
核心结论
默认情况下,手动中断优化后,未保存到目标对象的最后一次迭代数据已彻底丢失。原因是optimx在完成整个优化流程前,不会将中间迭代状态赋值给ans变量;中断后函数无返回值,内存中的临时迭代数据会被R的垃圾回收机制清理,traceback()仅能查看调用栈,无法获取优化的中间状态。
可行的提前预防方案
如果需要在中断时保留最后一次迭代结果,可通过以下两种方式提前设置:
1. 利用trace参数记录迭代日志到文件
设置control=list(trace=3)(或更高等级)会在控制台打印每次迭代的参数和目标值,可将控制台输出重定向到文件,中断后从文件中提取最后一次迭代信息:
# 重定向输出到文件 sink("optim_trace.log") ans = optimx( startx, fn=genrose.f, gr=NULL, hess=NULL, method=c("Nelder-Mead"), control=list( maxit=5000000, save.failures=TRUE, trace=3), gs=10) # 恢复控制台输出 sink()
中断后打开optim_trace.log,文件末尾的内容即为最后一次迭代的记录。
2. 修改目标函数,实时保存迭代结果
在目标函数中添加逻辑,将每次迭代的参数和目标值保存到全局环境或文件中,即使中断也能保留最后一次数据:
require(optimx) # 初始化全局变量存储迭代历史 iter_history <- list() iter_count <- 0 genrose.f<- function(x, gs=NULL){ n <- length(x) if(is.null(gs)) { gs=100.0 } fval<-1.0 + sum (gs*(x[1:(n-1)]^2 - x[2:n])^2 + (x[2:n] - 1)^2) # 更新全局迭代计数和历史记录 assign("iter_count", iter_count + 1, envir = .GlobalEnv) current_iter <- list(iter = iter_count, x = x, fval = fval) assign("iter_history", append(iter_history, current_iter), envir = .GlobalEnv) # 每100次迭代保存到文件,防止R崩溃丢失 if(iter_count %% 100 == 0){ saveRDS(iter_history, file = "optim_iter_history.rds") } return(fval) } startx <- seq(1:100) / 5 n <- length(startx) ans = optimx( startx, fn=genrose.f, gr=NULL, hess=NULL, method=c("Nelder-Mead"), control=list( maxit=5000000, save.failures=TRUE, trace=3), gs=10)
中断后,直接查看全局变量iter_history[[length(iter_history)]]即可获取最后一次迭代的参数和目标值;若R意外崩溃,也可从optim_iter_history.rds文件中读取最近的迭代记录。
内容的提问来源于stack exchange,提问作者Bertrand
相关产品推荐
相关产品推荐

