keras + scikit-learn 包装器,当 GridSearchCV 与 n_jobs >1 时似乎挂起

Posted

技术标签:

【中文标题】keras + scikit-learn 包装器,当 GridSearchCV 与 n_jobs >1 时似乎挂起【英文标题】:keras + scikit-learn wrapper, appears to hang when GridSearchCV with n_jobs >1 【发布时间】:2018-05-11 16:39:34 【问题描述】:

更新:我必须重新编写这个问题,因为经过一些调查,我意识到这是一个不同的问题。

上下文:使用带有 scikit learn 的 kerasclassifier 包装器在网格搜索设置中运行 keras。系统:Ubuntu 16.04,库:anaconda 发行版 5.1、keras 2.0.9、scikitlearn 0.19.1、tensorflow 1.3.0 或 theano 0.9.0,仅使用 CPU。

代码: 我只是使用这里的代码进行测试:https://machinelearningmastery.com/use-keras-deep-learning-models-scikit-learn-python/,第二个示例“网格搜索深度学习模型参数”。注意第 35 行,内容如下:

grid = GridSearchCV(estimator=model, param_grid=param_grid)

症状:当网格搜索使用超过 1 个作业(意味着 cpus?)时,例如,将上面 A 行的 'n_jobs' 设置为 '2',下一行:

grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=2)

将导致代码无限期挂起,无论是使用 tensorflow 还是 theano,并且没有 cpu 使用(请参见随附的屏幕截图,其中创建了 5 个 python 进程但没有一个正在使用 cpu)。

通过调试,似乎是以下带有 'sklearn.model_selection._search' 的行会导致问题:

line 648: for parameters, (train, test) in product(candidate_params,
                                               cv.split(X, y, groups)))

,程序挂起,无法继续。

对于这意味着什么以及为什么会发生这种情况,我真的很感激。

提前致谢

【问题讨论】:

您好,我也有同样的问题。你找到解决这个问题的方法了吗, 【参考方案1】:

TLDR 回答:您不能,因为您的 Keras 模型无法序列化,并且在 Python 中使用 joblib 进行并行化需要序列化。

这个问题在这里很详细:https://www.neuraxle.org/stable/scikit-learn_problems_solutions.html#problem-you-can-t-parallelize-nor-save-pipelines-using-steps-that-can-t-be-serialized-as-is-by-joblib

并行化代码的解决方案是让您的 Keras 估算器可序列化。这可以使用上面链接中描述的保护程序来完成。

如果您有幸使用 TensorFlow v2 的预构建 Keras 模块,那么以下实用代码示例将对您很有用,因为您实际上只需要获取代码并使用您的代码进行修改:

https://github.com/guillaume-chevalier/seq2seq-signal-prediction

在此示例中,所有保存和加载代码都是使用 Neuraxle-TensorFlow 为您预先编写的,如果您使用 Neuraxle 的 AutoML 方法(例如:Neuraxle 的网格搜索和 Neuraxle 自己的并行性事物),这将使其可并行化。

【讨论】:

【参考方案2】:

我知道这是一个迟到的答案,但我也处理了这个问题,它确实让我放慢了速度,无法运行基本上可并行化的代码。问题确实与 tensorflow 会话有关。如果在GridSearchCV.fit()之前的父进程中创建了一个会话,它将挂起!

我的解决方案是将所有会话/图形创建代码限制在 KerasClassifer 类和我传递给它的模型创建函数中。

Felipe 所说的内存也是正确的,您将希望在模型创建函数或KerasClassifier 的子类中限制 TF 的内存使用。

相关信息:

Session hang issue with python multiprocessing Keras + Tensorflow and Multiprocessing in Python

【讨论】:

【参考方案3】:

您使用的是 GPU 吗?如果是这样,您不能让多个线程运行参数的每个变体,因为它们将无法共享 GPU。

这是一个完整的例子,说明如何在带有 GridsearchCV 的管道中使用 keras、sklearn 包装器:Pipeline with a Keras Model

如果你真的想在 GridSearchCV 中有多个作业,你可以尝试限制每个作业使用的 GPU 分数(例如,如果每个作业只分配 0.5 的可用 GPU 内存,你可以同时运行 2 个作业)

查看这些问题:

Limit the resource usage for tensorflow backend

GPU memory fraction does not work in keras 2.0.9 but it works in 2.0.8

【讨论】:

谢谢,但我用的不是GPU,而是CPU 如果我不得不提出一些建议,那可能与 tensorflow 会话有关。我认为您需要为每个网格搜索作业创建独立会话

以上是关于keras + scikit-learn 包装器,当 GridSearchCV 与 n_jobs >1 时似乎挂起的主要内容,如果未能解决你的问题,请参考以下文章

Scikit-Learn 包装器和 RandomizedSearchCV:RuntimeError

Keras scikit-learn 包装器在使用 one-hot 编码标签的交叉验证中的评分指标

keras开发成sklearn接口

keras 和 scikit-learn 中 MLP 回归器的不同损失值和准确度

从磁盘加载包含预训练 Keras 模型的 scikit-learn 管道

Keras官方中文文档:包装器Wrapper