【稀疏矩阵】使用torch.sparse模块

news/2024/9/19 22:33:08/文章来源:https://www.cnblogs.com/UnderTurrets/p/18397077

@

目录
  • 稀疏矩阵的格式
    • coo
    • csr
    • csc
  • Construction of Sparse COO tensors
  • Construction of CSR tensors
  • Linear Algebra operations(稀疏与稠密之间混合运算)
  • Tensor methods and sparse(与稀疏有关的tensor成员函数)
    • coo张量可用的tensor成员函数(经实测,csr也有一些可以用,比如dim())
  • Torch functions specific to sparse Tensors(与稀疏有关的torch函数)
  • 支持稀疏张量的常规torch函数
  • 支持稀疏张量的一元函数


稀疏矩阵的格式

目前,torch.sparse和scipy.sparse模块比较支持的主流的稀疏矩阵格式有coo格式、csr格式和csc格式,这三种格式中可供使用的API也最多。

coo

将矩阵中非零元素的坐标和值分开存储在3个数组中,3个数组长度必须相同,表示有n个非零元素。

csr

Index PointersIndicesData3个数组存储。

  • Index Pointers:第 i个元素记录这个矩阵的第 i行的第1个非零值在 Data数组的起始位置,第 i+1个元素记录这个矩阵的第 i行的最后一个非零值在 Data数组的终止位置(不包含右边界)。因此,这个矩阵的行数等于 len(Index Pointers)-1,第 i行非零值的个数等于 Index Pointers[i+1]-Index Pointers[i]
  • Indices:第 i个元素记录这个矩阵的第 i个非零值的列坐标。
  • Data:第 i个元素记录这个矩阵的第 i个非零值的具体数值,排列顺序严格按照行优先,列次先

csc

与csr唯一的不同在于列优先,其他规则一模一样。

Construction of Sparse COO tensors

  1. 常规构建
>>> i = [[0, 1, 1],[2, 0, 2]]
>>> v =  [3, 4, 5]
>>> s = torch.sparse_coo_tensor(i, v, (2, 3))
>>> s
tensor(indices=tensor([[0, 1, 1],[2, 0, 2]]),values=tensor([3, 4, 5]),size=(2, 3), nnz=3, layout=torch.sparse_coo)
>>> s.to_dense()
tensor([[0, 0, 3],[4, 0, 5]])

torch中,稀疏矩阵的存储方式记录在 tensor.layout中,可以通过检查 torch.layout == torch.sparse_coo来判断是否是coo张量。此外,稠密张量的 layout等于 strided

  1. 稠密混合的coo张量
>>> i = [[0, 1, 1],[2, 0, 2]]
>>> v =  [[3, 4], [5, 6], [7, 8]]
>>> s = torch.sparse_coo_tensor(i, v, (2, 3, 2))
>>> s
tensor(indices=tensor([[0, 1, 1],[2, 0, 2]]),values=tensor([[3, 4],[5, 6],[7, 8]]),size=(2, 3, 2), nnz=3, layout=torch.sparse_coo)

此方案与常规的coo构建方式不同,values中每个元素可以是一个向量,表示对应坐标的稠密张量,因此,创建出的coo张量也多出了一个维度。

  1. 带有重复坐标的coo张量
>>> i = [[1, 1]]
>>> v =  [3, 4]
>>> s=torch.sparse_coo_tensor(i, v, (3,))
>>> s
tensor(indices=tensor([[1, 1]]),values=tensor(  [3, 4]),size=(3,), nnz=2, layout=torch.sparse_coo)
>>> s.to_dense()
tensor([0, 7, 0])

如果输入的坐标有重复,则创建出的coo张量会自动把坐标重复的元素值相加。此外,可以通过成员函数 .coalesce()把重复坐标的元素值相加,将这个coo转换成一个不重复的张量;也可以通过 .is_coalesced()检查这个coo是否存在重复的坐标。

Construction of CSR tensors

按照 Index PointersIndicesData三个数组的定义构建即可。

>>> 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)

Linear Algebra operations(稀疏与稠密之间混合运算)

M表示2-D张量,V表示1-D张量,f表示标量,*表示逐元素乘法,@表示矩阵乘法。M[SparseSemiStructured]表示一种半结构化的稀疏矩阵,此处不再展开,可以自行去torch官网察看。

PyTorch operation Sparse grad Layout signature
torch.mv() no M[sparse_coo] @ V[strided] -> V[strided]
torch.mv() no M[sparse_csr] @ V[strided] -> V[strided]
torch.matmul() no M[sparse_coo] @ M[strided] -> M[strided]
torch.matmul() no M[sparse_csr] @ M[strided] -> M[strided]
torch.matmul() no M[SparseSemiStructured] @ M[strided] -> M[strided]
torch.matmul() no M[strided] @ M[SparseSemiStructured] -> M[strided]
torch.mm() no M[strided] @ M[SparseSemiStructured] -> M[strided]
torch.mm() no M[sparse_coo] @ M[strided] -> M[strided]
torch.mm() no M[SparseSemiStructured] @ M[strided] -> M[strided]
torch.sparse.mm() yes M[sparse_coo] @ M[strided] -> M[strided]
torch.smm() no M[sparse_coo] @ M[strided] -> M[sparse_coo]
torch.hspmm() no M[sparse_coo] @ M[strided] -> M[hybrid sparse_coo]
torch.bmm() no T[sparse_coo] @ T[strided] -> T[strided]
torch.addmm() no f * M[strided] + f * (M[sparse_coo] @ M[strided]) -> M[strided]
torch.addmm() no f * M[strided] + f * (M[SparseSemiStructured] @ M[strided]) -> M[strided]
torch.addmm() no f * M[strided] + f * (M[strided] @ M[SparseSemiStructured]) -> M[strided]
torch.sparse.addmm() yes f * M[strided] + f * (M[sparse_coo] @ M[strided]) -> M[strided]
torch.sspaddmm() no f * M[sparse_coo] + f * (M[sparse_coo] @ M[strided]) -> M[sparse_coo]
torch.lobpcg() no GENEIG(M[sparse_coo]) -> M[strided], M[strided]
torch.pca_lowrank() yes PCA(M[sparse_coo]) -> M[strided], M[strided], M[strided]
torch.svd_lowrank() yes SVD(M[sparse_coo]) -> M[strided], M[strided], M[strided]

以上API中,如果 Layout signature中提供了 @或者 *操作符,就不需要记住API,直接通过操作符即可隐式调用对应的API。如:

>>> a = torch.tensor([[0, 0, 1, 0], [1, 2, 0, 0], [0, 0, 0, 0]], dtype=torch.float64)
>>> sp = a.to_sparse_csr()
>>> vec = torch.randn(4, 1, dtype=torch.float64)
>>> sp.matmul(vec)
tensor([[ 0.4788],[-3.2338],[ 0.0000]], dtype=torch.float64)
>>> sp @ vec
tensor([[ 0.4788],[-3.2338],[ 0.0000]], dtype=torch.float64)

需要注意的是,使用操作符在稀疏张量和稠密张量之间乘法运算时,返回的都是稠密张量。如果想要返回稀疏张量,需要显式使用torch.smm()

torch同样支持稀疏与稀疏之间的运算,但要求输入的稀疏张量必须具有相同的稀疏结构,否则会报错,返回的稀疏张量的稀疏结构也与输入相同。

乘法运算:

>>> a = torch.tensor([[0, 0, 1, 0], [1, 2, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]], dtype=torch.float64)
>>> b = torch.tensor([[0, 0, 2, 0], [3, 1, 0, 0], [0, 0, 4, 0], [1, 0, 0, 1]], dtype=torch.float64)
>>> sp1 = a.to_sparse_coo()
>>> sp2 = b.to_sparse_coo()
>>> sp1 @ sp2
tensor(indices=tensor([[0, 1, 1, 1, 2, 2, 3],[2, 0, 1, 2, 0, 1, 2]]),values=tensor([4., 6., 2., 2., 3., 1., 2.]),size=(4, 4), nnz=7, dtype=torch.float64, layout=torch.sparse_coo)

加法运算

>>> a = torch.tensor([[0, 0, 1, 0], [1, 2, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]], dtype=torch.float64)
>>> b = torch.tensor([[0, 0, 2, 0], [3, 1, 0, 0], [0, 0, 4, 0], [1, 0, 0, 1]], dtype=torch.float64)
>>> sp1 = a.to_sparse_coo()
>>> sp2 = b.to_sparse_coo()
>>> sp3 = b.to_sparse_csr()
>>> sp1 + sp2
tensor(indices=tensor([[0, 1, 1, 2, 2, 3, 3],[2, 0, 1, 1, 2, 0, 3]]),values=tensor([3., 4., 3., 1., 4., 2., 1.]),size=(4, 4), nnz=7, dtype=torch.float64, layout=torch.sparse_coo)
>>> sp1 + sp3
UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at C:\actions-runner\_work\pytorch\pytorch\builder\windows\pytorch\aten\src\ATen\SparseCsrTensorImpl.cpp:55.)sp3 = b.to_sparse_csr()
Traceback (most recent call last):File "C:\Users\Xu Han\Desktop\pycharm-projects\MD_notes\main.py", line 18, in <module>print(sp1 + sp3)
RuntimeError: memory format option is only supported by strided tensors

Tensor methods and sparse(与稀疏有关的tensor成员函数)

PyTorch operation return
Tensor.is_sparse IsTrue if the Tensor uses sparse COO storage layout, False otherwise.
Tensor.is_sparse_csr IsTrue if the Tensor uses sparse CSR storage layout, False otherwise.
Tensor.dense_dim Return the number of dense dimensions in a sparse tensorself.
Tensor.sparse_dim Return the number of sparse dimensions in a sparse tensorself.

这里打断一下表格,讲解一下dense_dim和sparse_dim的含义。上文中,我们曾构建过稠密混合的coo张量,如下:

>>> i = [[0, 1, 1],[2, 0, 2]]
>>> v =  [[3, 4], [5, 6], [7, 8]]
>>> s = torch.sparse_coo_tensor(i, v, (2, 3, 2))
>>> s
tensor(indices=tensor([[0, 1, 1],[2, 0, 2]]),values=tensor([[3, 4],[5, 6],[7, 8]]),size=(2, 3, 2), nnz=3, layout=torch.sparse_coo)

那么,对于这个tensor,它的dense_dim为1,sparse_dim为2。

此外,在进行稀疏与稀疏之间的数学运算时,一定要保证稀疏张量的sparse_dim等于2.

继续表格。

PyTorch operation return
Tensor.sparse_mask Returns a new sparse tensor with values from a strided tensorself filtered by the indices of the sparse tensor mask.
Tensor.to_sparse Returns a sparse copy of the tensor.
Tensor.to_sparse_coo Convert a tensor to coordinate format.
Tensor.to_sparse_csr Convert a tensor to compressed row storage format (CSR).
Tensor.to_sparse_csc Convert a tensor to compressed column storage (CSC) format.
Tensor.to_sparse_bsr Convert a tensor to a block sparse row (BSR) storage format of given blocksize.
Tensor.to_sparse_bsc Convert a tensor to a block sparse column (BSC) storage format of given blocksize.
Tensor.to_dense Creates a strided copy ofself if self is not a strided tensor, otherwise returns self.
Tensor.values Return the values tensor of a sparse COO tensor.

以下是仅限coo张量的成员:

PyTorch operation return
Tensor.coalesce Returns a coalesced copy ofself if self is an uncoalesced tensor.
Tensor.sparse_resize_ Resizesself sparse tensor to the desired size and the number of sparse and dense dimensions.
Tensor.sparse_resize_and_clear_ Removes all specified elements from a sparse tensorself and resizes self to the desired size and the number of sparse and dense dimensions.
Tensor.is_coalesced ReturnsTrue if self is a sparse COO tensor that is coalesced, False otherwise.
Tensor.indices Return the indices tensor of a sparse COO tensor.

以下是仅限csr和bsr张量的成员:

PyTorch operation return
Tensor.crow_indices Returns the tensor containing the compressed row indices of theself tensor when self is a sparse CSR tensor of layout sparse_csr.
Tensor.col_indices Returns the tensor containing the column indices of theself tensor when self is a sparse CSR tensor of layout sparse_csr.

以下是仅限csc和bsc张量的成员:

PyTorch operation return
Tensor.row_indices ...
Tensor.ccol_indices ...

coo张量可用的tensor成员函数(经实测,csr也有一些可以用,比如dim())

add() add_() addmm() addmm_() any() asin() asin_() arcsin() arcsin_() bmm() clone() deg2rad() deg2rad_() detach() detach_() dim() div() div_() floor_divide() floor_divide_() get_device() index_select() isnan() log1p() log1p_() mm() mul() mul_() mv() narrow_copy() neg() neg_() negative() negative_() numel() rad2deg() rad2deg_() resize_as_() size() pow() sqrt() square() smm() sspaddmm() sub() sub_() t() t_() transpose() transpose_() zero_()

Torch functions specific to sparse Tensors(与稀疏有关的torch函数)

PyTorch operation return
sparse_coo_tensor Constructs a sparse tensor in COO(rdinate) format with specified values at the givenindices.
sparse_csr_tensor Constructs a sparse tensor in CSR (Compressed Sparse Row) with specified values at the givencrow_indices and col_indices.
sparse_csc_tensor Constructs a sparse tensor in CSC (Compressed Sparse Column) with specified values at the givenccol_indices and row_indices.
sparse_bsr_tensor Constructs a sparse tensor in BSR (Block Compressed Sparse Row)) with specified 2-dimensional blocks at the givencrow_indices and col_indices.
sparse_bsc_tensor Constructs a sparse tensor in BSC (Block Compressed Sparse Column)) with specified 2-dimensional blocks at the givenccol_indices and row_indices.
sparse_compressed_tensor Constructs a sparse tensor in Compressed Sparse format - CSR, CSC, BSR, or BSC - with specified values at the givencompressed_indices and plain_indices.
sparse.sum Return the sum of each row of the given sparse tensor.
sparse.addmm This function does exact same thing as torch.addmm() in the forward, except that it supports backward for sparse COO matrixmat1.
sparse.sampled_addmm Performs a matrix multiplication of the dense matricesmat1 and mat2 at the locations specified by the sparsity pattern of input.
sparse.mm Performs a matrix multiplication of the sparse matrixmat1
sspaddmm Matrix multiplies a sparse tensormat1 with a dense tensor mat2, then adds the sparse tensor input to the result.
hspmm Performs a matrix multiplication of a sparse COO matrixmat1 and a strided matrix mat2.
smm Performs a matrix multiplication of the sparse matrixinput with the dense matrix mat.
sparse.softmax Applies a softmax function.
sparse.log_softmax Applies a softmax function followed by logarithm.
sparse.spdiags Creates a sparse 2D tensor by placing the values from rows ofdiagonals along specified diagonals of the output

支持稀疏张量的常规torch函数

cat() dstack() empty() empty_like() hstack() index_select() is_complex() is_floating_point() is_nonzero() is_same_size() is_signed() is_tensor() lobpcg() mm() native_norm() pca_lowrank() select() stack() svd_lowrank() unsqueeze() vstack() zeros() zeros_like()

支持稀疏张量的一元函数

The following operators currently support sparse COO/CSR/CSC/BSR tensor inputs.

abs() asin() asinh() atan() atanh() ceil() conj_physical() floor() log1p() neg() round() sin() sinh() sign() sgn() signbit() tan() tanh() trunc() expm1() sqrt() angle() isinf() isposinf() isneginf() isnan() erf() erfinv()

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/792211.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Serverless 应用引擎 SAE 助力袋拉拉研发提效 70%

“我们调研和准备了半年,一次性迁移到了新版 SAE 上,主要看中了 SAE 的弹性能力和运维简单的特点,而且现在新版的使用体验越来越好了,控制台界面的操作比原来都要流畅很多。但我们还在持续摸索中,看如何能更好地应用 SAE。”作者:百潼 医院环保 IOT 设备的引领者:机汽猫…

2面准备记录

1、自我介绍 2、设计测试用例 3、购物车测试 4、输入框测试 5、GIT 常用命令

Altium designer软件介绍

Altium Designer 是原Protel软件开发商Altium公司推出的一体化的电子产品开发系统,主要运行在Windows操作系统。这套软件通过把原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技术的完美融合,为设计者提供了全新的设计解决方案,使设计者…

2024.7.5-2024.7.20 HA省学会集训游记(焦作一中)

这是一篇长篇小说 DAY1 除了DAY4-DAY5个别内容以外,这些都是补的,但是全写完有太多了qwq,挑题写了 树状数组和线段树基础很多都是一些模板题,太模板的题不再做太多解释 题目:P4062 P6619 P3688 P3157 P10497 P3374 P3368 P4223 P10589 P10688 CF1667B P10463 SP1716 CF718…

win11+docker desktop导入镜像运行容器

一:配置环境 前置条件:Win11环境,docker注册账号 1.安装WSL (1)在windows store安装Ubuntu 20.04.6 (2)设置“控制面板”-“程序”-“程序和功能”-左侧“启用或关闭Windows功能”-打开“适用于Linux的Windows子系统”,“Windows虚拟机监控程序平台” (3)终端执行: …

该如何做参数校验

该如何做参数校验技术架构springboot首先每一个接口都要有controller service mapper这种参数校验也是有很多种做法的,分享我的做法。那么入参是必须要做校验的比如 实体类 用Optional.ofNullable Optional.ofNullable 是Java 8引入的一个用于处理空值的类 Optional 中的一个静…

升级程序后报错 :Parse error: syntax error, unexpected :, expecting

当您看到类似“Parse error: syntax error, unexpected :, expecting ...”这样的错误时,这通常是因为 PHP 代码中存在语法错误。具体来说,这通常是因为某个语法特性在当前 PHP 版本中不被支持。 常见原因PHP 版本不兼容:新代码可能使用了较新版本的 PHP 语法特性,而当前服…

网站上传图片被压缩怎么解决

当网站上传图片被压缩导致质量下降时,可以通过以下几种方式来解决这个问题: 1. 了解平台压缩机制 首先了解平台对图片压缩的具体机制,比如压缩算法、压缩比例等。这有助于针对性地采取措施。 2. 优化图片上传前的准备按照规定尺寸设计素材:确保上传的图片符合平台要求的尺寸…

网站打开提示:”未检测到您服务器环境的sqlite3数据库扩展...“

当网站打开时提示“未检测到您服务器环境的sqlite3数据库扩展”,这表明您的服务器上缺少 SQLite3 扩展,或者虽然安装了 SQLite3 扩展,但是 PHP 并未正确配置来使用它。以下是一些排查和解决这个问题的方法: 1. 检查 SQLite3 扩展是否安装 首先,您需要确认 SQLite3 扩展是否…

IIS相关错误报错汇总整理及解决方案

解决方案400 Bad Request:检查请求是否包含错误的信息或格式。 401 Unauthorized:确认是否已经进行了身份验证。 403 Forbidden:检查是否有足够的权限访问资源。 404 Not Found:确认请求的URL是否正确,资源是否存在。 500 Internal Server Error:检查服务器日志,寻找错误…

中华财险60%研发人员用通义灵码全面提效,“越用越上瘾”

保险业被看成是社会“稳定器”和经济“助推器”,近年来已驶入数字化发展快车道。在 AI、大模型当道的今天,保险行业的研发流程、产品设计、场景拓展等业务链条各环节,都值得用大模型进行重塑。点击查看中华财险视频采访! 保险业被看成是社会“稳定器”和经济“助推器”,近…

安全:nginx安装modsecurity

一,modsecurity官网:官网: https://modsecurity.org/ 如图: 官方代码站: https://github.com/owasp-modsecurity/ModSecurity 二,安装环境准备: 1,安装依赖库: [root@localhost source]# yum install -y gcc make pcre-devel libxml2 libxml2-devel curl-devel httpd-dev…