【问题标题】:SVD calculation error from lapack function when using scikit-learn's Linear Discriminant Analysis class使用 scikit-learn 的线性判别分析类时来自 lapack 函数的 SVD 计算错误
【发布时间】:2023-04-02 18:40:01
【问题描述】:

我在我创建的机器学习管道中使用 scikit-learn 的 LDA 分类器对 2 类一维数据进行分类。发生以下异常:

ValueError:内部工作数组大小计算失败:-10

在以下行:

LinearDiscriminantAnalysis.fit(X,y)

其中 X = [-5e15, -5e15, -5e15, 5.7e16] 和 y = [0, 0, 0, 1],均为 float64 数据类型

另外,控制台还打印了以下错误:

英特尔 MKL 错误:进入 DGESDD 时参数 10 不正确

通过 Google 快速搜索后,dgesdd 是 LAPACK 中的一个函数,其中 scikit-learn relies upondgesdd documentation 告诉我们该函数计算实数 M×N 矩阵 A 的 singular value decomposition (SVD)。

回到最初的异常,我发现它是在 _compute_lwork 函数的scipy.linalg.lapack.py 中引发的。这个函数将一个函数作为输入,在这种情况下我相信它是 dgesdd 函数。 dgesdd 文档页面上的 CTRL-F "-10" 给出了这个错误代码背后的逻辑,但我不知道 Fortran,所以我不确定它的含义。

我想打赌 SVD 计算失败是由于 (1) X 数组中的大值,或 (2) X 数组中的 3 个值是完全相同的数字这一事实。

我将继续阅读 SVD 及其局限性。任何有关如何避免此错误的见解将不胜感激。

这是error的截图

【问题讨论】:

  • 您能否提供一个失败的示例。最近,由于过时的 BLAS 例程,人们开始遇到 scipy 问题。但是,它与 OpenBLAS 相关,而不是 MKL。
  • 抱歉,您所说的“示例”具体是什么意思?我已在我收到的错误帖子中添加了屏幕截图。
  • 我的意思是,有一段代码可以很容易地复制粘贴并给出完全相同的错误,这很好。此外,很高兴知道您拥有什么环境(库版本等)

标签: python scipy lapack svd intel-mkl


【解决方案1】:

这是DGESDD的定义:

subroutine  dgesdd (JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)

您遇到的错误表明传递给 MKL 的第 10 个参数 LDVT 的例程实现的值,V**T 矩阵的前导维度不符合所述路由的预期。

这可能是英特尔实施中的一个错误,不太可能,假设有电池在测试压力测试此例程,但并非不可能。这是哪个版本的MKL?或者这是 LDA 代码中的错误,很有可能:

LDVT is INTEGER
      The leading dimension of the array VT.  LDVT >= 1;
      if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
      if JOBZ = 'S', LDVT >= min(M,N).

请打印 M、N、LDA、LDU 和 LDVT?

如果您正确设置 LDVT,工作区分析将运行良好。

【讨论】:

  • >这是哪个版本的 MKL? version=2019.1 感谢您的解释,Kaveh,非常感谢您的帮助!但是,我不确定如何打印这些来自 Python 的值。我的一个想法是转到该 scipy.linalg.lapack.py 文件(链接在原始帖子中),然后在调用 DGESDD 的行之后,我认为是: wi =routine(*args, **kwargs)我可以打印 *args 和 **kwargs 来获取您请求的那些值。还可能必须编译该 .py 源文件。您如何看待这种方法?
  • 以上与版本无关。这是一个标准,每个供应商/开源项目都必须以相同的方式实现上述接口。
  • 看看传递给函数的内容真的很有帮助。你有源代码,对吧?只需使用额外的输出重建它。
  • 好的,之前,我在 lapack.py 中指出了以下行:wi =routine(*args, **kwargs)。将这些打印到控制台给出:args = (2, 0) 和 kwargs = {'compute_uv': True, 'full_matrices': 0}。查看输出的其余部分,这是 args[1] 第一次为 0,在之前的每次迭代中始终为正。此外,我尝试打印“例程”,这是一个 Fortran 对象,我认为它是 DGESDD 函数。
【解决方案2】:

关于英特尔 MKL 错误:参数 10 在进入 DGESDD 问题时不正确。实际上这个问题已经在 MKL v.2018 u4(2018 年 9 月)中得到修复。这是link to MKL 2018 bug fix list。 通过将环境变量 MKL_VERBOSE=1 设置为系统环境并查看将包含此类信息的输出,您可能更容易检查您使用的 MKL 版本。 前任: MKL_VERBOSE Intel(R) MKL 2019.0 Update 2 Product build 20190118 for Intel(R) 64 架构 Intel(R) Advanced Vector Extensions (Intel(R) AVX) 启用处理器,Lnx 2.80GHz lp64 intel_thread MKL_VERBOSE ZGETRF(85,85,0x13e66f0,85,0x13e1080,0) 6.18ms CNR:OFF Dyn:1 FastMM:1 TID:0 NThr:20

【讨论】:

    猜你喜欢
    • 2019-05-21
    • 2014-06-10
    • 1970-01-01
    • 2011-08-03
    • 2015-01-01
    • 2018-02-07
    • 2011-08-20
    • 2018-09-26
    • 2013-06-19
    相关资源
    最近更新 更多