如何在 GridSearchCV( ..., n_jobs = ... ) 中找到最佳进程数?

Gha*_*nem 5 python parallel-processing machine-learning scikit-learn parallelism-amdahl

我想知道,哪个更好地GridSearchCV( ..., n_jobs = ... )用于为模型选择最佳参数集,n_jobs = -1或者n_jobs使用大数字,
例如n_jobs = 30

基于 Sklearn 文档:

n_jobs = -1 意味着计算将在计算机的所有 CPU 上分派。

在我的 PC 上,我有一个 Intel i3 CPU,它有 2 个内核和 4 个线程,这是否意味着如果我设置了n_jobs = -1,它会隐式地等于n_jobs = 2

use*_*197 5

...这是否意味着如果我设置n_jobs = -1,它会隐含地等于n_jobs = 2

这很简单:

python ( scipy / joblib inside a GridSearchCV()) 用于检测 CPU 核心的数量,这是合理的调度并发(独立)进程,给定一个请求是通过n_jobs = -1设置完成的。

在此处输入图片说明 看到 3 核 CPU 很有趣吗?

在某些可以综合模拟 CPU / 内核的虚拟机案例中,结果并不像您已知的 Intel CPU / i3 案例那样微不足道。

如果有疑问,可以用一个简单的案例(在一个确实很小的数据集上,而不是成熟的模型空间搜索......)来测试这一点,然后让故事继续证明这一点。

import psutil;                  print( "{0:17s}{1:} CPUs PHYSICAL".format(
      "psutil:",
       psutil.cpu_count( logical = False ) ) )
pass;                           print( "{0:17s}{1:} CPUs LOGICAL".format(
      "psutil:",
       psutil.cpu_count( logical = True  ) ) )
...
Run Code Online (Sandbox Code Playgroud)

类似的主机平台“自我检测”可能会报告不同系统/设置的更多详细信息:

'''
sys:             linux 
                 3.6.1 (default, Jun 27 2017, 14:35:15)  .. [GCC 7.1.1 20170622 (Red Hat 7.1.1-3)]

multiprocessing: 1 CPU(s)
psutil:          1 CPUs PHYSICAL
psutil:          1 CPUs LOGICAL
psutil:          psutil.cpu_freq(  per_cpu = True  ) not able to report. ?( v5.1.0+ )
psutil:          5.0.1
psutil:          psutil.cpu_times( per_cpu = True  ) not able to report. ?( vX.Y.Z+ )
psutil:          5.0.1
psutil:          svmem(total=1039192064, available=257290240, percent=75.2, used=641396736, free=190361600, active=581107712, inactive=140537856, buffers=12210176, cached=195223552, shared=32768)
numexpr:         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ModuleNotFoundError: No module named 'numexpr'.
joblib:          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ModuleNotFoundError: No module named 'joblib'.
sklearn/joblib:  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ModuleNotFoundError: No module named 'sklearn.externals.joblib' 
'''
Run Code Online (Sandbox Code Playgroud)

或者

''' [i5]
>>> numexpr.print_versions()
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Numexpr version:   2.5
NumPy version:     1.10.4
Python version:    2.7.13 |Anaconda 4.0.0 (32-bit)| (default, May 11 2017, 14:07:41) [MSC v.1500 32 bit (Intel)]
AMD/Intel CPU?     True
VML available?     True
VML/MKL version:   Intel(R) Math Kernel Library Version 11.3.1 Product Build 20151021 for 32-bit applications
Number of threads used by default: 4 (out of 4 detected cores)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
'''
Run Code Online (Sandbox Code Playgroud)

...哪个更好地与 GridSearchCV 一起使用来为模型选择最佳参数集,
n_jobs = -1或者n_jobs使用像n_jobs = 30?

对此没有简单的“一刀切”答案:

Scikit 工具(以及许多其他遵循此实践的工具)用于在使用n_jobs指令时生成所需数量的并发进程实例(以便逃避共享 GIL 锁步进 - 如果对详细信息感兴趣,请在别处阅读更多相关信息) .

这种进程实例化不是免费的(在时间方面,即花费相当数量的[TIME]域成本,而且在空间方面,即花费至少是n_jobs单个 python 进程实例的 RAM 分配的 - 倍在[SPACE]-domain)。

鉴于此,您的战斗是与双刃剑的战斗。

试图“低估” CPU将使(某些)CPU 内核可能处于空闲状态。
尝试“超额预订” RAM空间会使您的性能比预期的更差,因为虚拟内存会导致操作系统交换,这会使您的机器学习缩放数据访问时间从~ 10+[ns]100,000~ 10+ [ms]以上变慢,这几乎是不可能的感到高兴。

的整体效果n_jobs = a_reasonable_amount_of_processes阿姆达尔定律的主题(重新制定的,不是附加的开销天真的版本),因此会有多少 CPU 核心有助于提高一个人的实际优化峰值(最大值)处理意图,除此之外的间接费用(为[TIME]- 和[SPACE]上面域概述)实际上会降低任何潜在的积极影响预期。

在生产中使用RandomForestRegressor()了非常大的数据集后,我可以告诉你[SPACE]-domain 是你试图进一步增长的最糟糕的敌人,n_jobs并且没有任何系统级的调整能够克服这个边界(因此越来越多的超低延迟RAM 和越来越多的(真实的)CPU 内核是进入任何更大的n_jobs计算计划的唯一实用方法)。


Gha*_*nem 5

Kevyn Collins-Thompson 教授在 Python 应用机器学习课程中给出了一个更简单的答案:

如果我的系统中有 4 个核心n_jobs = 30(以 30 个为例),则与n_jobs = 4. 所以没有额外的效果

因此,始终可以获得的最大性能是使用n_jobs = -1