做一些类似的事情
import numpy as np
a = np.random.rand(10**4, 10**4)
b = np.dot(a, a)
使用多个内核,运行良好。
a = np.random.randint(2, size=(n, n)).astype(np.int8)
array: np.random.randint(2, size=shape).astype(dtype)
dtype shape %time (average)
float32 (2000, 2000) 62.5 ms
float32 (3000, 3000) 219 ms
float32 (4000, 4000) 328 ms
float32 (10000, 10000) 4.09 s
int8 (2000, 2000) 13 seconds
int8 (3000, 3000) 3min 26s
int8 (4000, 4000) 12min 20s
int8 (10000, 10000) It didn't finish in 6 hours
float16 (2000, 2000) 2min 25s
float16 (3000, 3000) Not tested
float16 (4000, 4000) Not tested
float16 (10000, 10000) Not tested
import scipy.linalg.blas as blas
a = np.random.randint(2, size=(n, n)).astype(np.int8)
b = blas.sgemm(alpha=1.0, a=a, b=a)
所以,如果我要做整数矩阵乘法,我得做下面的一个:
np.dot
并庆幸我可以保留8位整数。SGEMM
并使用4倍内存。np.float16
并且只使用2倍内存,但要注意的是,np.dot
在float16数组上的速度要比在float32数组上慢得多,比int8慢得多。我能按方案4做吗?这样的图书馆存在吗?
注意,当这个答案变老时,numpy可能会获得优化的整数支持。请验证此答案是否在您的安装程序中运行得更快。
numpy.dot
来计算子产品,它释放全局解释器锁。因此,可以使用相对轻量级的线程,并且可以从主线程访问阵列以提高内存效率。实施:
import numpy as np
from numpy.testing import assert_array_equal
import threading
from time import time
def blockshaped(arr, nrows, ncols):
"""
Return an array of shape (nrows, ncols, n, m) where
n * nrows, m * ncols = arr.shape.
This should be a view of the original array.
"""
h, w = arr.shape
n, m = h // nrows, w // ncols
return arr.reshape(nrows, n, ncols, m).swapaxes(1, 2)
def do_dot(a, b, out):
#np.dot(a, b, out) # does not work. maybe because out is not C-contiguous?
out[:] = np.dot(a, b) # less efficient because the output is stored in a temporary array?
def pardot(a, b, nblocks, mblocks, dot_func=do_dot):
"""
Return the matrix product a * b.
The product is split into nblocks * mblocks partitions that are performed
in parallel threads.
"""
n_jobs = nblocks * mblocks
print('running {} jobs in parallel'.format(n_jobs))
out = np.empty((a.shape[0], b.shape[1]), dtype=a.dtype)
out_blocks = blockshaped(out, nblocks, mblocks)
a_blocks = blockshaped(a, nblocks, 1)
b_blocks = blockshaped(b, 1, mblocks)
threads = []
for i in range(nblocks):
for j in range(mblocks):
th = threading.Thread(target=dot_func,
args=(a_blocks[i, 0, :, :],
b_blocks[0, j, :, :],
out_blocks[i, j, :, :]))
th.start()
threads.append(th)
for th in threads:
th.join()
return out
if __name__ == '__main__':
a = np.ones((4, 3), dtype=int)
b = np.arange(18, dtype=int).reshape(3, 6)
assert_array_equal(pardot(a, b, 2, 2), np.dot(a, b))
a = np.random.randn(1500, 1500).astype(int)
start = time()
pardot(a, a, 2, 4)
time_par = time() - start
print('pardot: {:.2f} seconds taken'.format(time_par))
start = time()
np.dot(a, a)
time_dot = time() - start
print('np.dot: {:.2f} seconds taken'.format(time_dot))
通过这个实现,我获得了大约x4的加速,这是我的机器中的内核的物理数量:
running 8 jobs in parallel
pardot: 5.45 seconds taken
np.dot: 22.30 seconds taken
主要内容:逐元素矩阵乘法,矩阵乘积运算,矩阵点积矩阵乘法是将两个矩阵作为输入值,并将 A 矩阵的行与 B 矩阵的列对应位置相乘再相加,从而生成一个新矩阵,如下图所示: 注意:必须确保第一个矩阵中的行数等于第二个矩阵中的列数,否则不能进行矩阵乘法运算。 图1:矩阵乘法 矩阵乘法运算被称为向量化操作,向量化的主要目的是减少使用的 for 循环次数或者根本不使用。这样做的目的是为了加速程序的计算。 下面介绍 NumPy 提供的三种矩阵乘法,从而进一步
问题内容: 在numpy中,我有N个3x3矩阵的数组。这将是我如何存储它们的示例(我正在提取内容): 我也有一个由3个向量组成的数组,这将是一个示例: 我似乎无法弄清楚如何通过numpy将它们相乘,从而实现如下效果: 与的形状(在投射到阵列)是。但是,由于速度的原因,列表实现是不可能的。 我尝试了各种换位的np.dot,但最终结果没有得到正确的形状。 问题答案: 使用 脚步 : 1)保持第一根轴对
问题内容: 我有2个形状(5,1)的numpy数组,说:a = [1,2,3,4,5] b = [2,4,2,3,6] 我如何制作一个矩阵,将每个第i个元素与每个第j个元素相乘?喜欢: 不使用forloops?我可以使用重塑,缩小或乘法的任何组合吗? 现在,我沿着行和列创建每个数组的aa * b拼接,然后将元素明智地相乘,但是在我看来,肯定有一种更简单的方法。 问题答案: 使用numpy.oute
在使用numpy的python中,假设我有两个矩阵: 稀疏矩阵 密集的x*y矩阵 现在我想做,它将返回一个密集的矩阵。 但是,我只关心中非零的单元格,这意味着如果我这样做了,对我的应用程序不会有任何影响 <代码>S\u=S*S\u 显然,这将是对操作的浪费,因为我想把在
我怎样才能导入阶乘函数分别从Numpy和sippy为了看看哪一个更快? 我已经通过导入数学从python本身导入了阶乘。但是,它不适用于Numpy和smpy。
我正在计算两大组向量(具有相同特征)之间的余弦相似度。每组向量表示为一个scipy CSR稀疏矩阵a和B。我想计算一个x B^T,它不会稀疏。但是,我只需要跟踪超过某个阈值的值,例如0.8。我正试图用vanilla RDD在Pyspark中实现这一点,目的是使用为scipy CSR矩阵实现的快速向量操作。 A和B的行是标准化的,所以为了计算余弦相似度,我只需要找到A中每一行与B中每一行的点积。A的