使用 doParallel 在 R 中并行化 keras 模型

Posted

技术标签:

【中文标题】使用 doParallel 在 R 中并行化 keras 模型【英文标题】:Parallelizing keras models in R using doParallel 【发布时间】:2018-12-16 22:45:32 【问题描述】:

我正在尝试使用 keras for R 集成多个神经网络。为此,我想通过使用 "foreach" 来并行化不同网络的训练 循环。

models <- list()
x_bagged <- list()
y_bagged <- list()

n_nets = 2
bag_frac <-0.7
len <- nrow(x_train)

for(i in 1:n_nets)
    sam <- sample(len, floor(bag_frac*len), replace=FALSE)
    x_bagged[[i]] <- x_train[sam,]
    y_bagged[[i]] <- y_train[sam]

    models[[i]] <- keras_model_sequential() 

models[[i]] %>% 
  layer_dense(units = 100, input_shape = ncol(x_train), activation = "relu", kernel_initializer = 'glorot_normal') %>% 
  layer_batch_normalization() %>%
  layer_dense(units = 100, activation = custom_activation, kernel_initializer = 'glorot_normal') %>%
  layer_dense(units = 1, activation = 'linear', kernel_initializer = 'glorot_normal')


    models[[i]] %>% compile(
  loss = "MSE",
    optimizer= optimizer_sgd(lr=0.01)
    )
    


library(foreach)
library(doParallel)
cl<-makeCluster(2)
registerDoParallel(cl)
nep <- 10

 foreach(i = 1:n_nets,.packages=c("keras")) %dopar%  
         models[[i]] %>% keras::fit(
  x_bagged[[i]], y_bagged[[i]], 
  epochs = nep,
  validation_split = 0.1,
  batch_size =256,
  verbose=1
)
 
stopCluster(cl)

使用 %do% 而不是 %dopar% 运行代码没有问题;但是,当我尝试在多个内核上同时安装网络时,出现以下错误:

: 任务 1 失败 - “'what' 必须是函数或字符 字符串”回溯:

    foreach(i = 1:n_reti, .packages = c("keras")) %dopar% .模型[[i]] %>% keras::fit(x_bagged[[i]], y_bagged[[i]], . epochs = nep,validation_split = 0.1,batch_size = 256,. 详细 = 1) 。 e$fun(obj、substitute(ex)、parent.frame()、e$data)

有人知道我该如何克服这个错误吗?有没有其他方法可以在 R 上并行训练模型?

提前谢谢你!

【问题讨论】:

使用minimal, reproducible example 可以更容易地帮助您重现您的错误(另请参阅link)。 当我试图从不合适的模型中预测时,我遇到了这个错误。 我现在遇到了类似的问题。我怀疑这是因为 TensorFlow 后端不是为支持并行处理而设计的,并且使用 Reticulate 作为中介使其更加复杂。 【参考方案1】:

虽然这个问题很老了,但我遇到了同样的问题,所以我在这里发布了解决方案。问题是 Keras 模型对象在被​​序列化之前无法传输给工作人员。一个快速的解决方法是在将模型发送给工作人员之前对其进行序列化,然后在本地节点上对它们进行反序列化:

library(foreach)
library(doParallel)
cl<-makeCluster(2)
registerDoParallel(cl)
nep <- 10

# Serialize models before sending them to the workers
models_par <- lapply(models_par, keras::serialize_model)

# Now send the models, not just the indices
foreach(model = models_par,.packages=c("keras")) %dopar%  

  # Unserialize locally
  model_local <- keras::unserialize_model(model)
  model_local %>% keras::fit(
    x_bagged[[i]], y_bagged[[i]], 
    epochs = nep,
    validation_split = 0.1,
    batch_size =256,
    verbose=1
  )

  # Serialize before sending back to master
  keras::serialize_model(model_local)
 
stopCluster(cl)

【讨论】:

我正在尝试使用您的示例从 keras 模型 (model %>% predict(newdata)) 进行预测并预先序列化模型,然后在 foreach 循环中反序列化,但我收到以下错误“反序列化错误(socklist[[n]]):从连接读取错误”。看起来多个进程正在尝试同时反序列化... 您是否能够使用 forach 和 doparallel 进行预测。我遇到了同样的问题。

以上是关于使用 doParallel 在 R 中并行化 keras 模型的主要内容,如果未能解决你的问题,请参考以下文章

使用 R doParallel 或 foreach 从 mysql 并行获取数据

写入连接时出错 - 与 R 并行化 - Linux/Ubuntu 问题

与 Rborist 并行化

如何在R中的并行任务中删除临时文件

R doParallel foreach 中的并行处理

有没有办法在 xts 中将 period.apply 与 doParallel 和 foreach 一起使用?