使用类似NumPy的API进行数组操作库

在数据科学和机器学习领域,NumPy是一个广泛使用的库,它提供了强大的数组操作功能。随着技术的发展,出现了一些新的库,它们提供了与NumPy类似的API,但可以在不同的硬件上运行,例如GPU。这些库包括CuPy和PyTorch,它们允许在GPU上进行高效的数组操作。

Scikit-learn是一个流行的机器学习库,它提供了许多用于数据挖掘和数据分析的工具。为了支持这些新的数组操作库,Scikit-learn引入了对Array API的支持。这意味着,可以在Scikit-learn中使用CuPy或PyTorch等库作为后端,进行数据操作和模型训练。

目前,这种支持还处于实验阶段,需要显式启用。只有当安装了array-api-compat库时,Scikit-learn的某些估计器才能接受Array API兼容的输入数据结构,并自动将操作派发到底层命名空间,而不是依赖于NumPy

目前,已知与Scikit-learn的估计器兼容的Array API库包括array-api-strict、CuPy和PyTorch。下面是一个使用CuPy在GPU上运行LinearDiscriminantAnalysis的示例代码:

from sklearn.datasets import make_classification from sklearn import config_context from sklearn.discriminant_analysis import LinearDiscriminantAnalysis import cupy X_np, y_np = make_classification(random_state=0) X_cu = cupy.asarray(X_np) y_cu = cupy.asarray(y_np) X_cu.device <CUDA Device 0> with config_context(array_api_dispatch=True): lda = LinearDiscriminantAnalysis() X_trans = lda.fit_transform(X_cu, y_cu) X_trans.device <CUDA Device 0>

在模型训练完成后,拟合的属性(如果是数组)也将来自与训练数据相同的Array API命名空间。例如,如果使用CuPy的Array API命名空间进行训练,那么拟合的属性将位于GPU上。Scikit-learn提供了一个实验性的_estimator_with_converted_arrays工具,它可以将估计器属性从Array API转换为ndarray:

from sklearn.utils._array_api import _estimator_with_converted_arrays cupy_to_ndarray = lambda array: array.get() lda_np = _estimator_with_converted_arrays(lda, cupy_to_ndarray) X_trans = lda_np.transform(X_np) type(X_trans) <class 'numpy.ndarray'>

对于PyTorch的支持,可以通过设置array_api_dispatch=True并直接传递张量来实现:

import torch X_torch = torch.asarray(X_np, device="cuda", dtype=torch.float32) y_torch = torch.asarray(y_np, device="cuda", dtype=torch.float32) with config_context(array_api_dispatch=True): lda = LinearDiscriminantAnalysis() X_trans = lda.fit_transform(X_torch, y_torch) type(X_trans) <class 'torch.Tensor'> X_trans.device.type 'cuda'

Scikit-learn中支持Array API兼容输入的估计器和其他工具包括PCA、Ridge、LinearDiscriminantAnalysis等。此外,还有一些元估计器和度量工具也支持Array API输入。随着时间的推移,支持的范围预计将会扩大。

当使用Array API兼容输入调用函数或方法时,通常的做法是返回与输入数据相同数组容器类型和设备的数组值。同样,当估计器使用Array API兼容输入进行拟合时,拟合的属性将是来自与输入相同的库的数组,并存储在相同的设备上。随后的predict和transform方法期望输入与传递给fit方法的数据来自相同的数组库和设备。

需要注意的是,返回标量值的评分函数将返回Python标量(通常是float实例),而不是数组标量值。此外,为了确保正确性并防止溢出,Scikit-learn中的某些操作会自动在float64精度的浮点值上执行操作。然而,某些数组命名空间和设备的组合(例如在MPS上的PyTorch)不支持float64数据类型。在这些情况下,Scikit-learn将改用float32数据类型。这可能导致与不使用数组API调度或使用支持float64的设备相比,行为不同(通常是数值不稳定的结果)。

要在Scikit-learn中启用对Array API的支持,需要在测试环境中安装array-api-compat库。要运行完整的检查集,需要安装PyTorch和CuPy,并拥有GPU。无法执行或缺少依赖项的检查将自动跳过。因此,运行测试时使用-v标志很重要,以便查看哪些检查被跳过。

在macOS上,PyTorch可以使用Metal Performance Shaders (MPS)来访问硬件加速器(例如M1或M2芯片内部的GPU组件)。然而,截至目前,PyTorch对MPS设备的支持还不完整。有关更多详细信息,请参见以下GitHub问题:。要在PyTorch中启用MPS支持,请在运行测试之前设置环境变量PYTORCH_ENABLE_MPS_FALLBACK=1:

PYTORCH_ENABLE_MPS_FALLBACK=1 pytest -k "array_api" -v
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485