R中的h2o:模型计算挂起

问题描述 投票:0回答:1

我不知道为什么我的随机森林网格搜索挂起。我尝试了许多关于Stackoverflow的建议,但没有任何效果。首先,这是我的代码:

library(data.table)
library(h2o)
library(dplyr)

# Initialise H2O
localH2O = h2o.init(nthreads = -1, min_mem_size = "9240M", max_mem_size = "11336M")

h2o.removeAll()

# Specify some dirs, inputs etc. (not shown)
laufnummer  <- 10
set.seed(laufnummer)
maxmodels   <- 500

# Convert to h2o
h2o_input <- as.h2o(input)

# Split: 80% = train; 0 = valid; rest = 20% = test
splits <- h2o.splitFrame(h2o_input, c(0.80,0))
train  <- h2o.assign(splits[[1]], "train") # 80%
test   <- h2o.assign(splits[[3]], "test")  # 10%

设置参数:

# Select range of ntrees
min_ntrees      <- 10
max_ntrees      <- 2500
stepsize_ntrees <- 20
ntrees_opts <- seq(min_ntrees,max_ntrees, stepsize_ntrees)

# Select range of tries
min_mtries      <- 1
max_mtries      <- 12
stepsize_mtries <- 1
mtries_opts <- seq(min_mtries,max_mtries, stepsize_mtries)

# Cross-validation number of folds
nfolds <- 5

hyper_params_dl = list(ntrees = ntrees_opts,
                       mtries = mtries_opts)
search_criteria_dl = list(
  strategy = "RandomDiscrete",
  max_models = maxmodels)

最后,随机网格搜索(这是它悬挂的位置,几乎总是25%)

rf_grid <- h2o.grid(seed = laufnummer,
                    algorithm = "randomForest", 
                    grid_id = "dlgrid",
                    x = predictors, 
                    y = response, 
                    training_frame = train,
                    nfolds = nfolds,
                    keep_cross_validation_predictions = TRUE,
                    model_id = "rf_grid",
                    hyper_params = hyper_params_dl,
                    search_criteria = search_criteria_dl
)

这是我已经尝试过的:

  1. 未在init中设置nthreads:无效。
  2. 将nthreads设置为4:无效。
  3. 设置较低的内存(我有16 GB):无效。
  4. 在网格搜索中添加的并行度= 0:无效
  5. 未使用h2o.removeAll():无效果
  6. 始终使用h2o.shutdown(prompt = FALSE):无效果
  7. 使用了JDK,R和h2o的不同版本。 (现在全部使用最新的)

问题是,网格搜索进度停止在25%左右,有时甚至更少。

有帮助的是将代码切换为GBM而不是RF,但是它有时也挂在那里(我需要RF!)。还有助于将模型数量减少到500,而不是5000,但仅适用于NN和GBM,而不适用于RF。

现在尝试了几周后,我将不胜感激!谢谢!

r random-forest h2o hang
1个回答
0
投票

最有可能导致挂起的原因是内存不足。您要么需要使用更少的内存,要么在具有更多内存的系统上运行作业。

这里有许多因素在起作用,除非您了解底层资源的使用,否则调试它们不一定很明显。

以下三部分提供有关如何监视内存使用情况,如何减少内存使用情况以及如何获得具有更多内存的系统的建议。


这里有一些内存监视建议:

  1. 监视您的物理内存使用情况。在Mac或Linux上使用top之类的程序来执行此操作。要查看的重要数字是RSS(驻留集大小),它表示主机上正在使用的实际物理内存量。

  2. 监视任何交换。确保您的系统没有交换到磁盘。当您尝试一次使用虚拟内存多于主机上的物理内存时,就会发生交换。在Linux上,vmstat命令适合显示交换。

  3. 使用-XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps打开Java GC日志记录,您将获得更多日志输出,这将向您显示Java本身是否只是由于内存不足而陷入困境。这很有可能。这是从R的内部启动H2O-3时通过传递jvm_custom_args标志来实现此目的的示例:

h2o.init(jvm_custom_args = c("-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps"))

您将看到一条消息,显示:

H2O is not running yet, starting it now...

Note:  In case of errors look at the following log files:
    /var/folders/vv/pkzvhy8x5hsfbsjg75_6q4ch0000gn/T//RtmpUsdTRQ/h2o_tomk_started_from_r.out
    /var/folders/vv/pkzvhy8x5hsfbsjg75_6q4ch0000gn/T//RtmpUsdTRQ/h2o_tomk_started_from_r.err

上面的.out文件现在将包含GC日志输出,如下所示:

...
02-02 08:30:29.785 127.0.0.1:54321       21814  main      INFO: Open H2O Flow in your web browser: http://127.0.0.1:54321
02-02 08:30:29.785 127.0.0.1:54321       21814  main      INFO:
02-02 08:30:29.886 127.0.0.1:54321       21814  #84503-22 INFO: GET /, parms: {}
02-02 08:30:29.946 127.0.0.1:54321       21814  #84503-20 INFO: GET /, parms: {}
02-02 08:30:29.959 127.0.0.1:54321       21814  #84503-21 INFO: GET /, parms: {}
02-02 08:30:29.980 127.0.0.1:54321       21814  #84503-22 INFO: GET /3/Capabilities/API, parms: {}
02-02 08:30:29.981 127.0.0.1:54321       21814  #84503-22 INFO: Locking cloud to new members, because water.api.schemas3.CapabilitiesV3
02-02 08:30:30.005 127.0.0.1:54321       21814  #84503-25 INFO: GET /3/InitID, parms: {}
14.334: [GC (Allocation Failure) [PSYoungGen: 94891K->3020K(153088K)] 109101K->56300K(299008K), 0.0193290 secs] [Times: user=0.22 sys=0.01, real=0.02 secs]
14.371: [GC (Allocation Failure) [PSYoungGen: 120914K->3084K(153088K)] 174194K->173560K(338432K), 0.0256458 secs] [Times: user=0.29 sys=0.04, real=0.03 secs]
14.396: [Full GC (Ergonomics) [PSYoungGen: 3084K->0K(153088K)] [ParOldGen: 170475K->163650K(435200K)] 173560K->163650K(588288K), [Metaspace: 22282K->22282K(1069056K)], 0.0484233 secs] [Times: user=0.47 sys=0.00, real=0.05 secs]
14.452: [GC (Allocation Failure) [PSYoungGen: 118503K->160K(281088K)] 282153K->280997K(716288K), 0.0273738 secs] [Times: user=0.30 sys=0.05, real=0.02 secs]
14.479: [Full GC (Ergonomics) [PSYoungGen: 160K->0K(281088K)] [ParOldGen: 280837K->280838K(609792K)] 280997K->280838K(890880K), [Metaspace: 22282K->22282K(1069056K)], 0.0160751 secs] [Times: user=0.09 sys=0.00, real=0.02 secs]
14.516: [GC (Allocation Failure) [PSYoungGen: 235456K->160K(281088K)] 516294K->515373K(890880K), 0.0320757 secs] [Times: user=0.30 sys=0.10, real=0.03 secs]
14.548: [Full GC (Ergonomics) [PSYoungGen: 160K->0K(281088K)] [ParOldGen: 515213K->515213K(969216K)] 515373K->515213K(1250304K), [Metaspace: 22282K->22282K(1069056K)], 0.0171208 secs] [Times: user=0.09 sys=0.00, real=0.02 secs]

“分配失败”消息看起来很吓人,但实际上完全正常。担心的时候是当您看到背靠背的完整GC周期需要大量的“实际秒数”时。


以下是一些建议使用更少的内存:

  • 将数据分割一次,然后将其保存到磁盘,然后在两个新的as.h2o或h2o.importFile步骤中,将它们读回到新的H2O-3新群集中。

    在您的示例中,您正在执行splitFrame。这将在内存中复制数据。

  • 将h2o.importFile首选为as.h2o。

    我不知道这对您的情况有多大影响,但是h2o.importFile是为大数据设计和测试的,而as.h2o不是。

  • 使用更少的数据。

    您还没有说出数据的形状,但是,如果automl或网格搜索适用于GBM而不适用于DRF,那肯定是内存不足。这两种算法在计算方面几乎做完全相同的事情,但是DRF模型往往更大,因为DRF具有更高的树深,这意味着需要更多的内存来存储模型。

  • 使用nthreads选项减少并发工作线程的数量。

    您运行的活动并发线程越多,所需的内存就越大,因为每个线程都需要一些工作内存。例如,您可以尝试将nthreads设置为拥有的CPU内核数量的一半。

  • 不要使用xgboost。

    Xgboost使用内存的方式很特殊,因为它在Java堆之外复制了第二个数据。这意味着当您使用xgboost时,您不想为java max_mem_size(或Xmx)提供整个主机的内存,否则可能会遇到问题(尤其是交换)。

  • 不要使用DRF。

    DRF树更深,因此产生的模型更大。或者,构建(并保留在内存中)较少的DRF模型,较浅的DRF模型或具有较少树的模型。


  • 获得更多内存的最佳快速建议是在云中运行。您不一定需要多节点设置。如果可以充分解决问题,则单个大型节点更容易使用。在您的情况下,可能会。鉴于您上面所说的(即您现在有16 GB,并且如果不使用DRF就可以完成),我将从使用EC2中的m5.4xlarge实例开始,该实例具有64 GB的RAM,成本不到1美元/ hr,并将其最大大小设为48G。

© www.soinside.com 2019 - 2024. All rights reserved.