【问题标题】:MemoryError in numpy matrix multiplication or einsum operationsnumpy 矩阵乘法或 einsum 操作中的 MemoryError
【发布时间】:2016-05-11 09:41:40
【问题描述】:

我正在处理大约几千个行和列的二进制(只有 0 和 1)矩阵。例如,行数在 2000 - 7000 之间,列数在 4000 - 15000 之间。我的电脑内存超过 100g。

令我惊讶的是,即使使用这些尺寸,我也收到了 MemoryError 以及以下代码。为了重现性,我提供了一个具有较小矩阵 (10*20) 的示例,请注意,以下两项均会引发此错误:

   import numpy as np

   my_matrix = np.random.randint(2,size=(10,20))
   tr, tc = np.triu_indices(my_matrix.shape[0],1)
   ut_sums = np.sum(my_matrix[tr] * my_matrix[tc], 1)

   denominator = 100
   value = 1 - ut_sums.astype(float)/denominator
   np.einsum('i->', value)

我尝试将上面代码中的元素乘法替换为 einsum,如下所示,但它也会生成相同的 MemoryError:

   import numpy as np

   my_matrix = np.random.randint(2,size=(10,20))
   tr, tc = np.triu_indices(my_matrix.shape[0],1)
   ut_sums = np.einsum('ij,ij->i', my_matrix[tr], my_matrix[tc])

   denominator = 100
   value = 1 - ut_sums.astype(float)/denominator
   np.einsum('i->', value)

在这两种情况下,打印的 Traceback 都指向正在计算 ut_sums 的行。

请注意,我的代码还有其他操作,还有其他统计数据是在类似大小的矩阵上计算的,但是超过 100 g,我认为应该没有问题。

【问题讨论】:

    标签: python numpy matrix out-of-memory


    【解决方案1】:

    仅仅因为您的计算机有 100 GB 的物理内存并不意味着您的操作系统愿意或能够分配如此大量的连续内存。它必须是连续的,因为 NumPy 数组通常是这样的。

    你应该弄清楚你的输出矩阵应该有多大,然后尝试自己创建一个类似的矩阵:

    arr = np.zeros((10000, 10000))
    

    看看你是否能够分配一个任意大的数组。

    【讨论】:

    • 我也可以使用 np.zeros((100000, 100000)) 创建矩阵,但是由于 MemoryError,无法创建大小为 1000000 * 1000000 的矩阵。但是,我的矩阵的大小要小得多。有什么我可以解决的吗?该矩阵是二进制的(仅 1 和 0)并且是稀疏的。我可以使用 scipy 的稀疏矩阵吗?元素乘法或 einsum 运算是否适用于稀疏矩阵?
    • 是的,如果你的数据是稀疏的,你应该利用 NumPy 和朋友中的稀疏矩阵特性。如果你的矩阵只有零和一:你在使用dtype=bool吗?
    • 不,我没有使用 dtype=bool。现在我想起来了,我可以在创建矩阵的过程中使用它,但我还没有想过如何用 bool 矩阵计算 ut_sums。另外,刚才我尝试了 scipy.sparse 的 lil_matrix,在上面的第一个代码块中进行元素乘法。但在一台相对强大的机器上,它运行了大约 15 分钟,然后出现 MemoryError 失败。 stacktrack 指向我从原始创建稀疏矩阵的行: my_matrix = scipy.sparse.lil_matrix(np.random.randint(2, size=(100000, 100000))) 这对我来说似乎有点不合理。
    • 好吧,如果你的值是 0 和 1,你真的需要弄清楚如何切换到 dtype=bool。它将节省大量内存。或者至少切换到 np.uint8。
    • M2C 这里,使用ulimit 增加进程可以从内核请求的内存量,参见。 stackoverflow.com/questions/12718148/… 其次,@JohnZwinck np.zero 可能不是一个很好的测试来检查您可以从内核获得的最大内存。查看stackoverflow.com/questions/27574881/…的答案
    猜你喜欢
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    相关资源
    最近更新 更多