与foreach并行预测nnet输出时R内存爆炸

时间:2017-09-21 14:39:03

标签: r parallel-processing neural-network doparallel nnet

我有一个(大)神经网络由R中的nnet包训练。我希望能够模拟来自这个神经网络的预测,并且使用像foreach这样的东西以并行方式进行预测。成功使用之前(所有在Windows机器上)。

我的代码基本上是

形式
library(nnet)

data = data.frame(out=c(0, 0.1, 0.4, 0.6),
              in1=c(1, 2, 3, 4),
              in2=c(10, 4, 2, 6))

net = nnet(out ~ in1 + in2, data=data, size=5)

library(doParallel)
registerDoParallel(cores=detectCores()-2)

results = foreach(test=1:10, .combine=rbind, .packages=c("nnet")) %dopar% {
  result = predict(net, newdata = data.frame(in1=test, in2=5))
  return(result)
}

除了更大的NN适合和预测;它大约300MB。

上面的代码在使用传统的for循环或使用%do%时运行正常,但在使用%dopar%时,所有内容都会被加载到内存中,每个内核使用大约700MB。如果我运行它足够长的时间,一切都会爆炸。

在查找类似的问题后,我仍然不知道造成这种情况的原因。省略'预测'部分一切顺利。

如何让每个核心查找不变的网络'而不是把它加载到内存中?或者是不可能的?

2 个答案:

答案 0 :(得分:1)

当您启动新的并行工作程序时,您实际上创建了一个新环境,这意味着您在该新环境中执行的任何操作都需要访问相关的变量/函数。

例如,您必须指定.packages=c("nnet"),因为您需要在每个新工作人员(环境)中使用nnet包,这就是您克隆"或"出口"从全球环境到每个工人环境

因为您需要经过训练的神经网络进行预测,所以您还需要将其导出给每个工作人员,而且我没有看到您正在经历的内存爆炸的方法。如果您仍然对并行化感兴趣但内存不足,我唯一的建议就是调查doMPI

答案 1 :(得分:0)

  

如何让每个核心查找不变的网络'而不是把它加载到内存中?或者是不可能的?

CPak的回复解释了正在发生的事情;您在单独的R会话中有效地运行主脚本的多个副本(= worker)。由于您使用的是Windows,请致电

registerDoParallel(cores = n)

扩展为:

cl <- parallel::makeCluster(n, type = "PSOCK")
registerDoParallel(cl)

是什么将n 独立背景 R工作者设置为具有自己的独立内存地址空间。

现在,如果您使用的是类Unix系统,那么它将相当于使用n 分叉 R工作者,参见parallel::mclapply()。 Windows上的R不支持分叉进程。使用分叉处理,您将有效地获得您要求的内容,因为分叉子进程将共享已由主进程分配的对象(只要这些对象未被修改),例如, net