Pytorch和Numpy中的稀疏矩阵sparse
写在前面,pytorch和numpy都有对稀疏矩阵的操作,最大的区别在于pytorch可以通过GPU进行加速;不过现在numpy这边也推出了智能AI来加速对稀疏矩阵的运算;下面就稍微梳理一下关于稀疏矩阵的相关知识点,以飨诸君~
0 稀疏矩阵类别
不管是pytorch还是numpy,他们对稀疏矩阵的处理都是根据稀疏矩阵类别来的;所以先简单介绍稀疏矩阵的类别,这里网上已经有大量针对这些类别的详细解释说明,我这边就做引用:
SciPy 中不同稀疏矩阵存储方式介绍 (这个博客经常更换地址,而且加载不出图;但是是原创,所以贴出来);
不同稀疏矩阵存储方式介绍(这是对上面博客的CSDN转载,可看图)。
0.1 coo_matrix
对角存储矩阵(Coordinate Matrix)的简称
优:
能与CSR / CSC格式的快速转换
(tobsr()、tocsr()、to_csc()、to_dia()、to_dok()、to_lil())
缺:
不支持切片和算术运算操作
0.2 dok_matrix
按键字典矩阵(Dictionary of Keys Matrix)的简称
优:
对于递增的构建稀疏矩阵很高效,比如定义该矩阵后,想进行每行每列更新值,可用该矩阵。
可以高效访问单个元素,只需要O(1)
缺:
不允许重复索引(coo中适用),但可以很高效的转换成coo后进行重复索引
0.3 csr_matrix
压缩稀疏行矩阵(Compressed Sparse Row Matrix )的简称
优:
高效的稀疏矩阵算术运算
快速地矩阵矢量积运算
缺:
转换到稀疏结构代价较高(可以考虑LIL,DOK)
0.4 csc_matrix
压缩稀疏列矩阵(Compressed Sparse Column Matrix )的简称
优缺:
同上
0.5 bsr_matrix
分块压缩稀疏行矩阵(Block Sparse Row Matrix )的简称
优:
更适合于适用于具有密集子矩阵的稀疏矩阵
0.6 bsc_matrix
分块压缩稀疏列矩阵(Block Sparse Column Matrix )的简称
优:
更适合于适用于具有密集子矩阵的稀疏矩阵
0.7 lil_matrix
链表矩阵(Linked List Matrix )的简称
优:
适合递增的构建成矩阵
转换成其它存储方式很高效
支持灵活的切片
缺:
算术操作,列切片,矩阵向量内积操作慢(考虑用coo)
0.8 dia_matrix
对角存储矩阵(Diagonal Matrix)的简称
1 pytorch中的稀疏矩阵
先上官网开发文档镇楼TORCH.SPARSE 1.13 开发文档。
值得说明的是目前pytorch 只支持 COO, CSR, CSC, BSR, 和 BSC五种矩阵,可以用numpy转完在用pytorch。
这里首先讲pytorch而不是numpy的原因是pytorch确实比numpy快,具体看这里这个测试numpy, torch.spmm和torch.spmm 速度测试;
常用的方法有如下
1.1 to_sparse()
a = torch.tensor([[0, 2.], [3, 0]])
a.to_sparse()
官网有例子,不再重复造轮子;
1.2 to_sparse_csr()
1.3 sparse_coo_tensor()
1.4 sparse_csr_tensor()
crow_indices = torch.tensor([0, 2, 4])
col_indices = torch.tensor([0, 1, 0, 1])
values = torch.tensor([1, 2, 3, 4])
csr = torch.sparse_csr_tensor(crow_indices, col_indices, values, dtype=torch.float64)
csr
"""
tensor(crow_indices=tensor([0, 2, 4]),
col_indices=tensor([0, 1, 0, 1]),
values=tensor([1., 2., 3., 4.]), size=(2, 2), nnz=4,
dtype=torch.float64)
"""
csr.to_dense()
"""
tensor([[1., 2.],
[3., 4.]], dtype=torch.float64)
"""
1.5 sparse.sum()
1.6 sparse.mm()
这里提一句,torch.sparse.mm()和torch.spmm()是一样的,映射到的底层函数函数一样;具体可看这个numpy, torch.spmm和torch.spmm 稀疏矩阵乘法 测试;
2 numpy中的稀疏矩阵
照例搬出官方文档镇楼,Sparse matrices 1.11.4 官方文档
numpy是高性能科学计算和数据分析的基础包,其对稀疏矩阵的操作主要依赖于scipy开发包。
此处仍然引开篇的博客SciPy 中不同稀疏矩阵存储方式介绍
关于使用智能AI来加速对稀疏矩阵的运算,可参考此链接一行代码加速 sklearn 运算上千倍
原汁原味的官方 -->Intel® Extension for Scikit-learn
PS:如果对numpy中的方法不熟,可以看这篇博客NumPy:数组批量计算
再贴一个numpy稀疏矩阵转pytorch的代码:
def sparse_mx_to_torch_sparse_tensor(sparse_mx):
"""Convert a scipy sparse matrix to a torch sparse tensor."""
if type(sparse_mx) != sp.coo_matrix:
sparse_mx = sparse_mx.tocoo().astype(np.float32)
indices = torch.from_numpy(
np.vstack((sparse_mx.row, sparse_mx.col)).astype(np.int64))
values = torch.from_numpy(sparse_mx.data).float()
shape = torch.Size(sparse_mx.shape)
return torch.sparse.FloatTensor(indices, values, shape)
参考博文及感谢
部分内容参考以下链接,这里表示感谢 Thanks♪(・ω・)ノ
参考博文1 Pytorch 关于稀疏矩阵 1.13 官方开发文档
https://pytorch.org/docs/1.13/sparse.html?highlight=sparse#module-torch.sparse
参考博文2 Numpy 关于稀疏矩阵 Sparse matrices 1.11.4 官方文档
https://docs.scipy.org/doc/scipy/reference/sparse.html
参考博文3 SciPy 中不同稀疏矩阵存储方式介绍
https://dreamhomes.github.io/posts/202012311027/
参考博文4 不同稀疏矩阵存储方式介绍
https://blog.csdn.net/DreamHome_S/article/details/111994423
参考博文5 numpy, torch.spmm和torch.spmm 稀疏矩阵乘法测试
https://github.com/rusty1s/pytorch_sparse/issues/356
参考博文6 一行代码加速 sklearn 运算上千倍
https://blog.csdn.net/dQCFKyQDXYm3F8rB0/article/details/125382907
参考博文7 Intel® Extension for Scikit-learn