首页 > 解决方案 > 如何忽略矩阵乘法中的零?

问题描述

假设我有一个带有随机数的 10000 x 10000 矩阵 W,以及两个 10000 个暗淡向量 U 和 V,U 中有随机数,V 用零填充。使用 numpy 或 pytorch,计算 U @ W 和 V @ W 需要相同的时间。我的问题是,有没有办法优化矩阵乘法,使其在计算过程中跳过或忽略零,这样 V @ W 之类的计算速度会更快?

import numpy as np
W = np.random.rand(10000, 10000)

U = np.random.rand(10000)
V = np.zeros(10000)

y1 = U @ W
y2 = V @ W
# computing y2 should take less amount of time than y1 since it always returns zero vector.

标签: pythonnumpymath

解决方案


您可以使用scipy.sparse类来提高性能,但这完全取决于矩阵。例如,使用V稀疏矩阵获得的性能会很好。通过转换U为稀疏矩阵获得的结果不会很好,或者实际上可能会降低性能(在这种情况下U实际上是密集的)。

import numpy as np
import scipy.sparse as sps

W = np.random.rand(10000, 10000)
U = np.random.rand(10000)
V = np.zeros(10000)

%timeit U @ W
125 ms ± 1.45 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit V @ W
128 ms ± 6.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Vsp = sps.csr_matrix(V)
Usp = sps.csr_matrix(U)
Wsp = sps.csr_matrix(W)

%timeit Vsp.dot(Wsp)
1.34 ms ± 15.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
%timeit Vsp @ Wsp
1.39 ms ± 37.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit Usp @ Wsp
2.37 s ± 84.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

正如您所看到的,使用稀疏方法对 有很大改进V @ W,但实际上您会降低性能,U @ W因为 U 或 W 中的所有条目都不为零。


推荐阅读