我经历过以前被问过的类似问题(例如1(https://stackoverflow.com/questions/41942115/numpy-efficient-large-dot-products) 2(https://stackoverflow.com/questions/20983882/efficient-dot-products-of-large-memory-mapped-arrays))。但是,没有一个与我的问题完全相关。
我试图计算两个大矩阵之间的点积,我有一些内存限制,我必须满足。
我有一个numpy稀疏矩阵,形状为(10000,600000)。例如,
from scipy import sparse as sps
x = sps.random(m=10000, n=600000, density=0.1).toarray()
第二个numpy矩阵的大小为(600000,256),它仅由(-1,1)组成。
import numpy as np
y = np.random.choice([-1,1], size=(600000, 256))
我需要x
和y
的点积在尽可能低的内存要求。速度不是主要关注。
以下是我迄今为止尝试过的方法:
Scipy稀疏格式:
当然,我将numpy稀疏矩阵转换为scipy csr_matrix
。但是,由于内存问题,任务仍然被杀死。没有错误,我只是在终端上被杀死。
from scipy import sparse as sps
sparse_x = sps.csr_matrix(x, copy=False)
z = sparse_x.dot(y)
# killed
减小dtype精度+Scipy稀疏格式:
from scipy import sparse as sps
x = x.astype("float16", copy=False)
y = y.astype("int8", copy=False)
sparse_x = sps.csr_matrix(x, copy=False)
z = sparse_x.dot(y)
# Increases the memory requirement for some reason and dies
名词单数
不确定它是否对稀疏矩阵有帮助。在这个answer中发现了一些有趣的东西。但是,以下内容也没有帮助:
z = np.einsum('ij,jk->ik', x, y)
# similar memory requirement as the scipy sparse dot
建议?
如果你有任何改善的建议,请告诉我。此外,我正在考虑以下方向:
1.如果我能摆脱点积本身就太好了。我的第二个矩阵(即y
)是随机生成的,它只有[-1,1]。我希望有什么方法可以利用它的特性。
1.可将点积分成几个小的点积,然后聚合。
2条答案
按热度按时间yyhrrdl81#
M@x
的最深层Python代码(其中M
是稀疏csr矩阵,x
是密集数组)是:这里的
fn
是经过编译的代码,它获取csr
矩阵的属性数组,密集数组作为一维数组,预分配的result
数组也作为扁平的view
。我想知道在创建
result
时会发生内存错误。因为我怀疑fn
使用该内存作为其工作空间,并且没有尝试使用任何更多的内存。我知道sparse@sparse矩阵乘法在两个编译步骤中完成,第一步确定结果的维数和nnz,第二步实际执行计算,两步之间的python代码创建了
result
数组,与这里所做的差不多,并且@
的内存错误发生在result
分配中。v9tzhpje2#
如果你创建的数组没有任何内存问题(我为准备好的例子大小设置了内存问题),为什么不使用迭代呢?点积等价循环可能是一个解决方案,可以使用numba加速:
对于注解中提到的Warren这样的示例,结果将很容易放入内存中。