gpt4 book ai didi

r - 为什么 save 和 saveRDS 在 dopar 中的行为不同?

转载 作者:行者123 更新时间:2023-11-30 08:32:29 29 4
gpt4 key购买 nike

(这是我第一次尝试创建可重现的示例问题 - 请随时评论以更好的方式来描述或说明问题!)

主要问题声明

我正在使用 foreach 并行训练约 25,000 个模型的%dopar%caretList (来自 caretEnsemble 包)。由于 R 崩溃和内存问题,我需要将每个预测保存为单独的对象,因此我的工作流程如下所示 - 请参阅下面的可重现示例。

cl <- makePSOCKcluster(4)
clusterEvalQ(cl, library(foreach))
registerDoParallel(cl)

multiple.forecasts <- foreach(x=1:1,.combine='rbind',.packages=c('zoo','earth','caret',"glmnet","caretEnsemble")) %dopar% {
tryCatch({
results <- caretList(mpg ~ cyl,data=mtcars,trControl=fitControl,methodList=c("glmnet","lm","earth"),continue_on_fail = TRUE)
for (i in 1:length(results)) {
results[[i]]$trainingData <- c() ## should be trimming out trainingData
}
save(results,file="foreach_results.Rdata") ## export each caretList as its own object
1
},
error = function(e) {
write.csv(e$message,file="foreach_failure.txt") ## monitor failures as needed
0
}
)
}

(IRL 此项目不涉及 mtcars 数据 - foreach 循环的每次迭代都会迭代列表中的数据帧之一,并为每个数据帧保存一个新的预测对象。)

当此对象保存在 foreach 中时循环中,由于压缩,对象大小在 Windows 中约为 136 KB。

但是,当创建并保存此对象时,使用 foreach ,像这样:

results <- caretList(mpg ~ cyl,data=mtcars,trControl=fitControl,methodList=c("glmnet","lm","earth"),continue_on_fail = TRUE)
for (i in 1:length(results)) {
results[[i]]$trainingData <- c()
}
save(results,file="no_foreach_results.Rdata")

该对象大致相同,在 Windows 中大约为 156KB。那么 Windows 中保存的对象大小会增加什么?

在实际工作流程中,较小的非foreach对象平均约为 4 MB,较大的 foreach对象平均为 10 MB,因此当我保存大约 25,000 个这些文件时,这会产生真正的存储问题。

  • 为什么在 foreach 循环中保存的对象大小如此之大,我能对此采取什么措施吗?

注释

  • 我的假设是 save foreach内保存整个环境:而不只是保存对象,即使使用 saveRDS 命令这样做也是如此(见下文),导出到每个工作人员的环境都有一些隐式保存。
  • Trim似乎不适用于 caretList :trim trainControl选项似乎没有修剪它应该做的事情,因为我必须手动添加命令来修剪 trainingData .
  • 我当前的解决方法是设置 save压缩为xz :我需要 foreach 循环来利用多核,因此我需要更大的对象。然而,这会使工作流程减慢约 3-4 倍,这就是我寻找解决方案的原因。
  • 需要 PSOCK 集群来解决 caret 中的问题。并行化:参见答案here .
  • SaveRDS对问题没有帮助:我已经使用 saveRDS 进行了测试而不是save ,但对象大小的差异无处不在。
  • 删除 tryCatch无济于事:即使没有tryCatchforeach循环中,对象大小的差异无处不在。

技术细节

可重现的示例:

library(caret)
library(caretEnsemble)

## train a caretList without foreach loop
fitControl <- trainControl(## 10-fold CV
method = "repeatedcv",
number = 10,
## repeated ten times
repeats = 10,
trim=TRUE)

results <- caretList(mpg ~ cyl,data=mtcars,trControl=fitControl,methodList=c("glmnet","lm","earth"),continue_on_fail = TRUE)
for (i in 1:length(results)) {
results[[i]]$trainingData <- c()
}
object.size(results) ##returns about 546536 bytes
save(results,file="no_foreach_results.Rdata") ##in Windows, this object is about 136 KB

## train a caretList with foreach loop
library(doParallel)

cl <- makePSOCKcluster(4)
clusterEvalQ(cl, library(foreach))
registerDoParallel(cl)

multiple.forecasts <- foreach(x=1:1,.combine='rbind',.packages=c('zoo','earth','caret',"glmnet","caretEnsemble")) %dopar% {
tryCatch({
results <- caretList(mpg ~ cyl,data=mtcars,trControl=fitControl,methodList=c("glmnet","lm","earth"),continue_on_fail = TRUE)
for (i in 1:length(results)) {
results[[i]]$trainingData <- c()
}
save(results,file="foreach_results.Rdata") ## in Windows, this object is about 160 KB
## loading this file back in and running object.size gives about 546504 bytes, approximately the same
1
},
error = function(e) {
write.csv(e$message,file="foreach_failure.txt")
0
}
)
}

sessionInfo() 输出:

R version 3.2.2 (2015-08-14)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server 2012 x64 (build 9200)

locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] parallel stats graphics grDevices utils datasets methods base

other attached packages:
[1] doParallel_1.0.10 iterators_1.0.8 earth_4.4.4 plotmo_3.1.4 TeachingDemos_2.10
[6] plotrix_3.6-2 glmnet_2.0-5 foreach_1.4.3 Matrix_1.2-4 caretEnsemble_2.0.0
[11] caret_6.0-64 ggplot2_2.1.0 RevoUtilsMath_8.0.1 RevoUtils_8.0.1 RevoMods_8.0.1
[16] RevoScaleR_8.0.1 lattice_0.20-33 rpart_4.1-10

loaded via a namespace (and not attached):
[1] Rcpp_0.12.4 compiler_3.2.2 nloptr_1.0.4 plyr_1.8.3 tools_3.2.2
[6] lme4_1.1-11 digest_0.6.9 nlme_3.1-126 gtable_0.2.0 mgcv_1.8-12
[11] SparseM_1.7 gridExtra_2.2.1 stringr_1.0.0 MatrixModels_0.4-1 stats4_3.2.2
[16] grid_3.2.2 nnet_7.3-12 data.table_1.9.6 pbapply_1.2-1 minqa_1.2.4
[21] reshape2_1.4.1 car_2.1-2 magrittr_1.5 scales_0.4.0 codetools_0.2-14
[26] MASS_7.3-45 splines_3.2.2 pbkrtest_0.4-6 colorspace_1.2-6 quantreg_5.21
[31] stringi_1.0-1 munsell_0.4.3 chron_2.3-47

最佳答案

我也不知道为什么,但我想出的解决方法就是运行

rm(训练数据)

从环境中删除任何重型存储 - 例如训练数据集 - 并阻止其保存到磁盘。

(很高兴不仅仅是我一个人对此感到疯狂。)

关于r - 为什么 save 和 saveRDS 在 dopar 中的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38837319/

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