mlr3嵌套重采样报错No model stored,内存占用过高问题求助
嵌套重采样中
No model stored错误排查与内存优化方案 在使用mlr3执行嵌套重采样(结合RFE特征选择与重复交叉验证)时,出现以下错误:
Error: No model stored
若开启store_models=TRUE,则会因模型内存占用过大导致128GB内存的RStudio Workbench崩溃。已知不指定store_models可避免存储中间模型以降低内存消耗,但仍能提取预测结果和性能指标,目前尚未尝试store_backends=FALSE,需排查问题并找到参数调整方案。
原代码
MSvCon <- read.csv("MS v Control Proteomics Final.csv", row.names=1) MSvCon$Status <- as.factor(MSvCon$Status) MSvCon[,2:4399] <- scale(MSvCon[,2:4399], center=TRUE, scale=TRUE) set.seed(123, "L'Ecuyer") task = as_task_classif(MSvCon, target = "Status") learner = lrn("classif.ranger", importance = "impurity", num.trees=10000) set_threads(learner, n = 8) measure = msr("classif.fbeta", beta=1, average="micro") terminator = trm("none") resampling_inner = rsmp("repeated_cv", folds = 10, repeats = 10) at = AutoFSelector$new( learner = learner, resampling = resampling_inner, measure = measure, terminator = terminator, fselect = fs("rfe", n_features = 1, feature_fraction = 0.5, recursive = FALSE)) resampling_outer = rsmp("repeated_cv", folds = 10, repeats = 10) rr = resample(task, at, resampling_outer)
问题原因
No model stored错误源于RFE特征选择需要访问模型的特征重要性来完成筛选逻辑,但默认情况下AutoFSelector不存储模型,导致无法获取必要的模型状态。而全局开启store_models=TRUE会存储所有内层和外层的模型,对于高维度数据集(4k+特征)+大量决策树(10000棵)的组合,内存占用会急剧膨胀。
解决方案与参数调整
1. 分层控制模型存储
给AutoFSelector单独开启store_models=TRUE(满足RFE的模型访问需求),同时在外层重采样时关闭store_models=FALSE(避免存储外层大模型),精准控制内存占用:
# 修改AutoFSelector初始化 at = AutoFSelector$new( learner = learner, resampling = resampling_inner, measure = measure, terminator = terminator, fselect = fs("rfe", n_features = 1, feature_fraction = 0.5, recursive = FALSE), store_models = TRUE # 内层存储模型用于RFE筛选 ) # 修改外层重采样调用 rr = resample(task, at, resampling_outer, store_models = FALSE)
2. 优化RFE与ranger参数降低内存
- 减少决策树数量:ranger的
num.trees=10000内存开销极大,实际性能提升在树数量到1000后趋于平缓,可先降到1000测试; - 调整RFE终止条件:
n_features=1会导致大量筛选轮次,可先设为50等合理值,减少迭代次数; - 启用递归特征消除:设置
recursive=TRUE,RFE会逐步移除最不重要的特征,比每次删除一半特征更高效; - 开启ranger内存优化:添加
save.memory=TRUE参数,让ranger使用更节省内存的数据结构。
3. store_backends=FALSE的作用
该参数控制是否存储任务的原始数据集后端,默认TRUE会为每个重采样折复制完整数据集。对于高维度数据集,开启store_backends=FALSE可大幅减少内存占用,但它不会直接解决No model stored错误,建议结合其他优化一起开启:
# 在AutoFSelector和外层重采样中都设置 at = AutoFSelector$new( # ... 其他参数 store_backends = FALSE ) rr = resample(task, at, resampling_outer, store_models = FALSE, store_backends = FALSE)
4. 其他内存优化技巧
- 减少线程数:当前
set_threads(learner, n=8),内存紧张时可降到4,降低并行内存开销; - 手动触发垃圾回收:重采样前调用
gc()释放闲置内存; - 清理无关变量:删除不需要的中间对象,比如原始数据集
MSvCon在生成task后可删除。
修改后的完整代码示例
MSvCon <- read.csv("MS v Control Proteomics Final.csv", row.names=1) MSvCon$Status <- as.factor(MSvCon$Status) MSvCon[,2:4399] <- scale(MSvCon[,2:4399], center=TRUE, scale=TRUE) set.seed(123, "L'Ecuyer") task = as_task_classif(MSvCon, target = "Status") # 优化ranger参数 learner = lrn("classif.ranger", importance = "impurity", num.trees=1000, # 降低树数量 save.memory = TRUE) # 内存优化 set_threads(learner, n = 4) # 减少线程数 measure = msr("classif.fbeta", beta=1, average="micro") terminator = trm("none") resampling_inner = rsmp("repeated_cv", folds = 10, repeats = 10) at = AutoFSelector$new( learner = learner, resampling = resampling_inner, measure = measure, terminator = terminator, fselect = fs("rfe", n_features = 50, feature_fraction = 0.7, recursive = TRUE), store_models = TRUE, # 内层存模型供RFE使用 store_backends = FALSE # 不存数据集后端 ) resampling_outer = rsmp("repeated_cv", folds = 10, repeats = 10) # 外层不存模型,不存后端 rr = resample(task, at, resampling_outer, store_models = FALSE, store_backends = FALSE) # 提取性能指标与预测结果 rr$score(measure) rr$predictions()
内容的提问来源于stack exchange,提问作者awaldman
相关产品推荐
相关产品推荐

