【问题标题】:R neuralnet package too slow for millions of recordsR 神经网络包对于数百万条记录来说太慢了
【发布时间】:2016-04-24 00:01:29
【问题描述】:

我正在尝试使用 R 包神经网络训练一个用于预测客户流失的神经网络。代码如下:

data <- read.csv('C:/PredictChurn.csv') 
maxs <- apply(data, 2, max) 
mins <- apply(data, 2, min)
scaled_temp <- as.data.frame(scale(data, center = mins, scale = maxs - mins))
scaled <- data
scaled[, -c(1)] <- scaled_temp[, -c(1)]
index <- sample(1:nrow(data),round(0.75*nrow(data)))
train_ <- scaled[index,]
test_ <- scaled[-index,]
library(neuralnet)
n <- names(train_[, -c(1)])
f <- as.formula(paste("CHURNED_F ~", paste(n[!n %in% "CHURNED_F"], collapse = " + ")))
nn <- neuralnet(f,data=train_,hidden=c(5),linear.output=F)

它可以正常工作,但是在使用完整数据集(数百万行的范围内)进行训练时,它需要的时间太长了。所以我知道 R 默认是单线程的,所以我尝试研究如何将工作并行化到所有内核中。甚至可以并行执行此功能吗?我尝试了各种包都没有成功。

有人能做到吗? 它不一定是神经网络包,任何让我训练神经网络的解决方案都可以。

谢谢

【问题讨论】:

  • 下面我的回答对你有帮助吗?
  • 尝试使用 BLAS 库作为后端,例如 Intel MKL。

标签: r parallel-processing neural-network


【解决方案1】:

您可以尝试为此使用 caret 和 doParallel 包。这是我一直在使用的。它适用于某些模型类型,但可能不适用于所有模型。

  layer1 = c(6,12,18,24,30)
  layer2 = c(6,12,18,24,30)
  layer3 = c(6,12,18,24,30)

  cv.folds = 5

  # In order to make models fully reproducible when using parallel processing, we need to pass seeds as a parameter
  # https://stackoverflow.com/questions/13403427/fully-reproducible-parallel-models-using-caret

  total.param.permutations = length(layer1) * length(layer2) * length(layer3)

  seeds <- vector(mode = "list", length = cv.folds + 1)
  set.seed(1)  
  for(i in 1:cv.folds) seeds[[i]]<- sample.int(n=1, total.param.permutations, replace = TRUE)
  seeds[[cv.folds + 1]]<-sample.int(1, 1, replace = TRUE) #for the last model

  nn.grid <- expand.grid(layer1 = layer1, layer2 = layer2, layer3 = layer3)

  cl <- makeCluster(detectCores()*0.5) # use 50% of cores only, leave rest for other tasks
  registerDoParallel(cl)

  train_control <- caret::trainControl(method = "cv" 
                                       ,number=cv.folds 
                                       ,seeds = seeds # user defined seeds for parallel processing
                                       ,verboseIter = TRUE
                                       ,allowParallel = TRUE
                                       )

  stopCluster(cl)
  registerDoSEQ()

  tic("Total Time to NN Training: ")
  set.seed(1)
  model.nn.caret = caret::train(form = formula,
                       data = scaled.train.data,
                       method = 'neuralnet',
                       tuneGrid = nn.grid,
                       trControl = train_control
                       )
 toc()

【讨论】:

    【解决方案2】:

    Rmpi 包我有很好的经验,它可能也适用于你的情况。

    library(Rmpi)
    

    简单来说,它的用法如下:

    nproc = 4  # could be automatically determined
    # Specify one master and nproc-1 slaves
    Rmpi:: mpi.spawn.Rslaves(nslaves=nproc-1)
    # Execute function "func_to_be_parallelized" on multiple CPUs; pass two variables to function
    my_fast_results = Rmpi::mpi.parLapply(var1_passed_to_func,
                                          func_to_be_parallelized,
                                          var2_passed_to_func)
    # Close slaves
    Rmpi::mpi.close.Rslaves(dellog=T)
    

    【讨论】:

    • 感谢您的提示。但是在使用 Rmpi​​ 库时出现错误,说缺少 msmpi.dll。另外,您将如何编写命令,可以吗: my_fast_results = Rmpi​​::mpi.parLapply(neuralnet(f,data=train_,hidden=c(5),linear.output=F))
    • @Aulait 您收到的有关缺少动态链接库 (.dll) 的错误表明某些缺少或过时的依赖项。我将安装/更新 Rmpi​​,并将依赖项标志设置为 true:install.packages("Rmpi", dependencies=TRUE)
    • @Aulait 命令 mpi.parLapply() 的正确语法可能是:mpi.parLapply(f, neuralnet, train_, c(5), FALSE)。是的,传递给函数 neuralnet() 的第一个参数是 mpi.parLapply() 的第一个参数。
    • 我不确定这是否可行。 neuralnets 在数据上进行交互式训练。如果我理解正确,这将使nproc-1 不同的神经网络。因此,我认为这种原始的并行性不会起作用。这就是 GPU 实现如此受欢迎的原因。然而,R 中目前不存在这样的实现,所以我认为最适合这种大数据的是 H2O
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2020-08-08
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    相关资源
    最近更新 更多