在 foreach 循环中并行执行 autoML 时出现 H2O "grid: Cannot append new models to a grid with different training input" 错误
H2O "grid: Cannot append new models to a grid with different training input" error when parallelizing the execution of autoML in a foreach loop
我正在尝试使用 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"))
...
}
所有模型中只有一部分被训练并保存在他们的文件夹中,因为在某些时候我得到以下错误:
water.exceptions.H2OIllegalArgumentException: Illegal argument:
training_frame of function: grid: Cannot append new models to a grid
with different training input
我想在 autoML 阶段使用了网格,所以我试图找到一个参数来传递 grid_id
,就像我在 h2o.grid
函数中所做的那样:
grid <- h2o.grid(“gbm”, grid_id = paste0(“gbm_grid_id”, div),
...)
但我找不到这样做的方法。
我使用的 H2O 包版本是 3.24.0.2.
有什么建议吗?
问题的简短回答是您不能在单个网格中使用不同的训练框架。每个模型网格必须与单个训练集相关联(这个想法是您不想比较在不同训练集上训练的模型)。这就是您遇到错误的原因。看起来您的每个 df.h2o
训练帧都是原始 df
帧的不同子集。
另一个注意事项:H2O 和 R 的并行功能不能很好地结合。 H2O 模型训练已经并行化,但以不同的方式(出于可扩展性原因)。单个模型的训练在 H2O 内(在多个内核上)并行进行,但 H2O 并非旨在同时训练多个模型。如果您想在一台机器上同时训练多个模型,那么您必须在不同端口的不同 R 会话中启动多个 H2O 集群。
也可能是您在同一个 ip 上打开同一个 h2o 会话两次,使用不同的训练数据,h2o 混淆了。
h2o.shutdown()
有时会话 运行 两次,有两个训练数据集
我正在尝试使用 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"))
...
}
所有模型中只有一部分被训练并保存在他们的文件夹中,因为在某些时候我得到以下错误:
water.exceptions.H2OIllegalArgumentException: Illegal argument: training_frame of function: grid: Cannot append new models to a grid with different training input
我想在 autoML 阶段使用了网格,所以我试图找到一个参数来传递 grid_id
,就像我在 h2o.grid
函数中所做的那样:
grid <- h2o.grid(“gbm”, grid_id = paste0(“gbm_grid_id”, div),
...)
但我找不到这样做的方法。 我使用的 H2O 包版本是 3.24.0.2.
有什么建议吗?
问题的简短回答是您不能在单个网格中使用不同的训练框架。每个模型网格必须与单个训练集相关联(这个想法是您不想比较在不同训练集上训练的模型)。这就是您遇到错误的原因。看起来您的每个 df.h2o
训练帧都是原始 df
帧的不同子集。
另一个注意事项:H2O 和 R 的并行功能不能很好地结合。 H2O 模型训练已经并行化,但以不同的方式(出于可扩展性原因)。单个模型的训练在 H2O 内(在多个内核上)并行进行,但 H2O 并非旨在同时训练多个模型。如果您想在一台机器上同时训练多个模型,那么您必须在不同端口的不同 R 会话中启动多个 H2O 集群。
也可能是您在同一个 ip 上打开同一个 h2o 会话两次,使用不同的训练数据,h2o 混淆了。
h2o.shutdown() 有时会话 运行 两次,有两个训练数据集