如何用 Python 计算大矩阵的奇异值分解

计算科学 Python 矩阵 稀疏矩阵 svd 内存管理
2021-12-10 03:04:21

语言:Python3

问题:我有一个形状为 [51200 rows x 51200 cols] 的矩阵 Q 存储在二进制文件中,该矩阵中的每个元素的数据类型为 complex64。因此,要将数据加载到内存中,我需要 ~20GB 的 RAM,从getsizeof(Q). 我确实可以在 LINUX 机器上访问具有 120GB RAM 的服务器。

我的目标是用 SVD 分解矩阵。

  1. Python 中最简单的方法是使用np.linalg.svd(Q). 为此,我首先使用np.fromfile()加载 Q,然后执行 svd 函数。这里的问题是,我不知道计算这个函数到底需要多少内存。我确实收到了警告init_zgesdd failed init虽然这不会停止计算,但最终 U,S,V* 的值都为零。经检查,此警告是由于内存分配造成的。

  2. 我尝试的第二种方法是使用scipy.sparse.linalg.svds库。由于有很多零(大约 20%),我认为将矩阵定义为稀疏矩阵会更好地使用内存。我发现在运行时,内存消耗从 50GB 到 100GB 波动,但在运行大约 15-20 分钟后被杀死。

  3. 我还研究了如何降低矩阵元素的精度。到目前为止,我正在使用 complex64(每个实部和图像部分都是 32 位浮点数),我没有看到任何使其成为 complex32 的选项。

我想知道为这种矩阵计算 SVD 的最佳方法。

1个回答

你试过 Dask 吗?

https://examples.dask.org/machine-learning/svd.html

您可以管理非常大的矩阵。还有一篇关于它的不错的博客文章https://blog.dask.org/2020/05/13/large-svds