【问题标题】:Parallel computing in R on Windows using doSNOW: How to transfer results from clusters back to master在 Windows 上使用 doSNOW 在 R 中进行并行计算:如何将结果从集群传输回主控
【发布时间】:2012-05-29 15:32:02
【问题描述】:

在 Windows 上使用 R 中的集群时,我一直在尝试找到一种简单的方法将结果从集群传输到主服务器。如果结果是一个数组或一个简单的数字,foreach / %dopar% 语句的 .combine 选项会处理这个问题,但是如果结果是一个复杂的对象,让这样一个 randomForest 模型,如何从从属集群转移整个模型还给主人?

我尝试:使用 env=.Global 进行组合,但它在我的 Windows 7 上不起作用。

最后,我通过将对象保存到文件来解决问题。然后主人可以恢复对象。如果有人知道更优雅的方式或为什么 assing 不起作用,我感谢 cmets。

示例代码:

print(" paralelize with 8 cores ------------------------------")
library(doSNOW)
cl<-makeCluster(8)
registerDoSNOW(cl)
clusterEvalQ(cl, library(randomForest))
clusterExport(cl, "x")
clusterExport(cl, "y")
clusterExport(cl, "x.selected")

makeModel <- function(i){
  m <- randomForest(x,x.selected[i,],mtry=250,sampsize=3200,ntree = 3000,do.trace=TRUE) 
  eval(parse(text = paste("model_",i," <- m",sep="")))
  eval(parse( text =paste("save(model_", i, ", file =\"model_", i, ".Rdata\")",sep="" ) ))
}

foreach(i = 1:length(x.selected[,1]),.verbose = TRUE ) %dopar% makeModel(i)
stopCluster(cl)

foreach(i = 1:length(x.selected[,1]),.verbose = TRUE ) %do% 
load(paste("model_",i,".RData",sep=""))

【问题讨论】:

  • 不知道foreach返回的是哪种类型的对象,貌似默认返回的不是对象列表。也许它试图以某种方式组合每个节点的结果但未能做到这一点。但是您可以使用clusterApply 而不是foreach。然后,您将收到一个模型列表。

标签: r parallel-processing


【解决方案1】:

如果您没有指定 .combine 函数,foreach 将返回一个列表,以便像 clusterApply 函数一样处理任意对象。许多 foreach 示例使用 .combine="c",但这不适用于 randomForest 模型对象。如果 foreach 循环的主体评估为 randomForest 模型对象,则 foreach 将返回这些对象的列表。

这是 foreach 包中 randomForest 示例的简化版本,它返回列表中的模型对象,然后将它们组合起来。我还修改了它以使用 doSNOW 包,如您的示例所示:

library(doSNOW)
library(randomForest)
cl <- makeCluster(8)
registerDoSNOW(cl)
nr <- 1000
x <- matrix(runif(100000), nr)
y <- gl(2, nr/2)
rf <- foreach(ntree=rep(125, 8), .packages='randomForest') %dopar% {
  randomForest(x, y, ntree=ntree)
}
crf <- do.call('combine', rf)
print(crf)
stopCluster(cl)

【讨论】:

  • 您能否指导我如何修改此代码以在大学集群上使用,我想在 4 个不同的节点上运行此作业,每个节点有 12 个核心。我有一个庞大的数据集,我想制作 1056 棵树(22*48,22= 每个核心的树,48 个核心)。我正在使用以下代码,但它不起作用,它只加载了所有负担的第一个节点,因此内存不足,其余节点处于空闲状态:registerDoSNOW(makeCluster(48))rf &lt;- foreach(ntree=rep(22,48), .combine=combine, .packages="randomForest") %dopar% randomForest(trainData[,-1], trainData$HCT116, ntree=ntree, norm.votes=FALSE)
  • 根据您的建议,我想出了如何在我大学的高性能集群上制作集群。我正在使用以下代码,但我认为它无法有效地并行化,因为具有 64 个内核和 2 TB RAM 的节点内存不足。请看看那里是否有任何问题。 library(doSNOW) library(foreach) library(randomForest) trainData &lt;- read.table("trainData.txt", sep="\t", header=T) testData &lt;- read.table("testData.txt", sep="\t", header=T) nodelist &lt;- readLines(Sys.getenv("OAR_NODEFILE"))
  • oar_job_id = as.numeric(Sys.getenv("OAR_JOB_ID")) connector = paste0("OAR_JOB_ID=", oar_job_id) connector = paste0(connector, " roarsh") registerDoSNOW(makeCluster(nodelist, type="SOCK", rshcmd = connector)) rf &lt;- foreach(ntree=rep(84,12), .combine=combine, .multicombine=T, .packages="randomForest") %dopar% randomForest(trainData[,-1], trainData$Class, ntree=ntree, norm.votes=FALSE) 我的 trainData 的 dim 是:46409553*9
  • @Newbie 这有点尴尬,因为我无法重现这一点,但如果您的内存不足,那么您可能需要为每个节点启动更少的工作人员。在您的作业提交中,请求更多节点,但每个节点的核心/CPU 更少。
  • 我认为我的问题是我的火车数据非常庞大(47600811*9)。我在想,如果我从我的真实火车数据中引导(假设 1000 个暗淡 10000*8 的子样本)并为所有这些子样本迭代生成树,最后将所有树组合成 1 个森林(正如你已经回答的那样这个问题)那么它将克服我的问题。您对此有何看法?
猜你喜欢
  • 2017-10-12
  • 1970-01-01
  • 2020-12-16
  • 2021-04-15
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
相关资源
最近更新 更多