在foreach循环中并行执行autoML时,出现H2O“网格:无法将新模型追加到具有不同训练输入的网格”错误

gjmwrych  于 2023-02-10  发布在  其他
关注(0)|答案(3)|浏览(95)

我尝试使用H2O提供的autoML特性并行化多个ML模型的训练。我使用的核心代码如下:

library(foreach)
library(doParallel)

project_folder <- "/home/user/Documents/"

ncores <- parallel::detectCores(logical = FALSE)
nlogiccpu <- parallel::detectCores()
max_mem_size <- "4G"

cl<-makeCluster(nlogiccpu)

registerDoParallel(cl)

df4 <-foreach(i = as.numeric(seq(1,length(divisions))), .combine=rbind) %dopar% {
  library(dplyr)
  library(h2o)
  h2o.init(nthreads = ncores, max_mem_size = max_mem_size)

  div <- divisions[i]

  df.h2o <- as.h2o(
    df %>% filter(code == div) )

  y <- "TARGET"
  x <- names(df.train.x.discretized)

  automl.models.h2o <- h2o.automl(
    x = x,
    y = y,
    training_frame = df.h2o,
    nfolds = 10,
    seed = 111,
    project_name = paste0("PRJ_", div)
  )

  leader <- automl.models.h2o@leader

  div_folder <- file.path(project_folder, paste0("Division_", div))
  h2o.saveModel(leader,
                path = file.path(div_folder, "TARGET_model_bin"))
  ...
}

所有模型中只有一部分被训练并保存在它们的文件夹中,因为在某个时候我得到了以下错误:
水.异常. H2O非法参数异常:非法参数:培训_职能框架:grid:无法将新模型追加到具有不同训练输入的格网
我假设网格是在autoML阶段使用的,所以我尝试找到一个参数来传递grid_id,就像我在h2o.grid函数中所做的那样,如下所示:

grid <- h2o.grid(“gbm”,  grid_id = paste0(“gbm_grid_id”, div),
                 ...)

但是我找不到这样做的方法。我使用的H2O软件包版本是3.24.0.2。
有什么建议吗?

koaltpgm

koaltpgm1#

这个问题的简短答案是,您不能在单个网格中使用不同的训练帧。每个模型网格都必须与单个训练集相关联(这样做的目的是您不希望比较在不同训练集上训练的模型)。这就是您遇到错误的原因。看起来您的每个df.h2o训练帧都是原始df帧的不同子集。
另一个注意事项:H2O和R的并行功能不能很好地混合。H2O模型训练已经被并行化了,但是方式不同单个模型的训练在H2O内并行进行(在多核上),但H2O并不是设计来一次训练多个模型的,如果你想在一台机器上一次训练多个模型,则必须在不同端口上的不同R会话中启动多个H2O群集。

vxf3dgd4

vxf3dgd42#

h2o.shutdown()有时会话会使用两个训练数据集运行两次

bvk5enib

bvk5enib3#

也可能是你在同一个ip上打开了两次相同的h2o会话,使用了不同的训练数据,而h2o后端不允许这样做。

相关问题