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

文章目录

  • 稀疏矩阵的格式
    • 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 operationSparse gradLayout signature
torch.mv()noM[sparse_coo] @ V[strided] -> V[strided]
torch.mv()noM[sparse_csr] @ V[strided] -> V[strided]
torch.matmul()noM[sparse_coo] @ M[strided] -> M[strided]
torch.matmul()noM[sparse_csr] @ M[strided] -> M[strided]
torch.matmul()noM[SparseSemiStructured] @ M[strided] -> M[strided]
torch.matmul()noM[strided] @ M[SparseSemiStructured] -> M[strided]
torch.mm()noM[strided] @ M[SparseSemiStructured] -> M[strided]
torch.mm()noM[sparse_coo] @ M[strided] -> M[strided]
torch.mm()noM[SparseSemiStructured] @ M[strided] -> M[strided]
torch.sparse.mm()yesM[sparse_coo] @ M[strided] -> M[strided]
torch.smm()noM[sparse_coo] @ M[strided] -> M[sparse_coo]
torch.hspmm()noM[sparse_coo] @ M[strided] -> M[hybrid sparse_coo]
torch.bmm()noT[sparse_coo] @ T[strided] -> T[strided]
torch.addmm()nof * M[strided] + f * (M[sparse_coo] @ M[strided]) -> M[strided]
torch.addmm()nof * M[strided] + f * (M[SparseSemiStructured] @ M[strided]) -> M[strided]
torch.addmm()nof * M[strided] + f * (M[strided] @ M[SparseSemiStructured]) -> M[strided]
torch.sparse.addmm()yesf * M[strided] + f * (M[sparse_coo] @ M[strided]) -> M[strided]
torch.sspaddmm()nof * M[sparse_coo] + f * (M[sparse_coo] @ M[strided]) -> M[sparse_coo]
torch.lobpcg()noGENEIG(M[sparse_coo]) -> M[strided], M[strided]
torch.pca_lowrank()yesPCA(M[sparse_coo]) -> M[strided], M[strided], M[strided]
torch.svd_lowrank()yesSVD(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 operationreturn
Tensor.is_sparseIsTrue if the Tensor uses sparse COO storage layout, False otherwise.
Tensor.is_sparse_csrIsTrue if the Tensor uses sparse CSR storage layout, False otherwise.
Tensor.dense_dimReturn the number of dense dimensions in a sparse tensorself.
Tensor.sparse_dimReturn 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 operationreturn
Tensor.sparse_maskReturns a new sparse tensor with values from a strided tensorself filtered by the indices of the sparse tensor mask.
Tensor.to_sparseReturns a sparse copy of the tensor.
Tensor.to_sparse_cooConvert a tensor to coordinate format.
Tensor.to_sparse_csrConvert a tensor to compressed row storage format (CSR).
Tensor.to_sparse_cscConvert a tensor to compressed column storage (CSC) format.
Tensor.to_sparse_bsrConvert a tensor to a block sparse row (BSR) storage format of given blocksize.
Tensor.to_sparse_bscConvert a tensor to a block sparse column (BSC) storage format of given blocksize.
Tensor.to_denseCreates a strided copy ofself if self is not a strided tensor, otherwise returns self.
Tensor.valuesReturn the values tensor of a sparse COO tensor.

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

PyTorch operationreturn
Tensor.coalesceReturns 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_coalescedReturnsTrue if self is a sparse COO tensor that is coalesced, False otherwise.
Tensor.indicesReturn the indices tensor of a sparse COO tensor.

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

PyTorch operationreturn
Tensor.crow_indicesReturns the tensor containing the compressed row indices of theself tensor when self is a sparse CSR tensor of layout sparse_csr.
Tensor.col_indicesReturns the tensor containing the column indices of theself tensor when self is a sparse CSR tensor of layout sparse_csr.

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

PyTorch operationreturn
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 operationreturn
sparse_coo_tensorConstructs a sparse tensor in COO(rdinate) format with specified values at the givenindices.
sparse_csr_tensorConstructs a sparse tensor in CSR (Compressed Sparse Row) with specified values at the givencrow_indices and col_indices.
sparse_csc_tensorConstructs a sparse tensor in CSC (Compressed Sparse Column) with specified values at the givenccol_indices and row_indices.
sparse_bsr_tensorConstructs a sparse tensor in BSR (Block Compressed Sparse Row)) with specified 2-dimensional blocks at the givencrow_indices and col_indices.
sparse_bsc_tensorConstructs a sparse tensor in BSC (Block Compressed Sparse Column)) with specified 2-dimensional blocks at the givenccol_indices and row_indices.
sparse_compressed_tensorConstructs a sparse tensor in Compressed Sparse format - CSR, CSC, BSR, or BSC - with specified values at the givencompressed_indices and plain_indices.
sparse.sumReturn the sum of each row of the given sparse tensor.
sparse.addmmThis function does exact same thing as torch.addmm() in the forward, except that it supports backward for sparse COO matrixmat1.
sparse.sampled_addmmPerforms a matrix multiplication of the dense matricesmat1 and mat2 at the locations specified by the sparsity pattern of input.
sparse.mmPerforms a matrix multiplication of the sparse matrixmat1
sspaddmmMatrix multiplies a sparse tensormat1 with a dense tensor mat2, then adds the sparse tensor input to the result.
hspmmPerforms a matrix multiplication of a sparse COO matrixmat1 and a strided matrix mat2.
smmPerforms a matrix multiplication of the sparse matrixinput with the dense matrix mat.
sparse.softmaxApplies a softmax function.
sparse.log_softmaxApplies a softmax function followed by logarithm.
sparse.spdiagsCreates 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()

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

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

相关文章

E32.【C语言 】练习:蓝桥杯题 懒羊羊字符串

1.题目 【问题描述】 “懒羊羊”字符串是一种特定类型的字符串&#xff0c;它由三个字符组成&#xff0c;具有以下特点: 1.字符串长度为 3. 2.包含两种不同的字母。 3.第二个字符和第三个字符相同 换句话说&#xff0c;“懒羊羊”字符串的形式应为 ABB&#xff0c;其中A和B是不…

Python去中心化身份验证指南

随着区块链技术的发展,去中心化身份验证系统成为了保护个人数据安全和确保数字身份不被篡改的重要工具。本文将介绍如何利用Python和区块链技术构建一个简单的去中心化身份验证系统,包括基本概念、实现步骤和代码示例。 什么是去中心化身份验证系统? 去中心化身份验证系统…

SpringBoot学习(8)RabbitMQ详解

RabbitMQ 即一个消息队列&#xff0c;主要是用来实现应用程序的异步和解耦&#xff0c;同时也能起到消息缓冲&#xff0c;消息分发的作用。 消息中间件最主要的作用是解耦&#xff0c;中间件最标准的用法是生产者生产消息传送到队列&#xff0c;消费者从队列中拿取消息并处理&…

【网易低代码】第3课,页面表格删除功能

你好&#xff01; 这是一个新课程 CodeWave网易低代码 通过自然语言交互式智能编程&#xff0c;同时利用机器学 习&#xff0c;帮助低代码开发者进一步降低使用门槛、提高应用开发效率 【网易低代码】第3课&#xff0c;页面表格删除功能 1.拖拽组件link链接到表格中&#xff0c…

一文读懂在线学习凸优化技术

一文读懂在线学习凸优化技术 在当今的数据驱动时代&#xff0c;机器学习算法已成为解决复杂问题的关键工具。在线学习凸优化作为机器学习中的一项核心技术&#xff0c;不仅在理论研究上具有重要意义&#xff0c;还在实际应用中展现出巨大的潜力。本文将深入浅出地介绍在线学习…

初识C++|继承

&#x1f36c; mooridy-CSDN博客 &#x1f9c1;C专栏&#xff08;更新中&#xff01;&#xff09; 目录 1. 继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承父类成员访问方式的变化 1.3继承类模板 2. 父类和子类对象赋值兼容转换 3. 继承中的…

使用docker配置wordpress

docker的安装 配置docker yum源 sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo下载最新版本docker sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-…

arxiv 首次投稿注意事项记录

文章目录 注册用教育邮箱&#xff0c;不用背书latex&#xff1a; 主tex和bib文件放在最外层&#xff0c;重命名为arxiv.tex和arxiv.bib &#xff08;没测试过不重命名会怎么样&#xff09;在overleaf右上方点submmit&#xff0c;选arxiv&#xff08;这样会自动生成一个bbl文件&…

苹果的“AI茅”之路只走了一半

今年苹果发布会最大的亮点&#xff0c;也许是和华为“撞档”&#xff0c;又或者是替腾讯“发布”新手游&#xff0c;但肯定不是iPhone 16。 9月10日&#xff0c;苹果秋季新品发布会与华为见非凡品牌盛典相继举行&#xff0c;iPhone 16系列也与HUAWEI Mate XT同日发布。 不过&…

QT之QML学习五:添加自定义Qml组件

开发环境: 1、Qt 6.7.2 2、Pyside6 3、Python 3.11.4 4、Windows 10 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!! 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!! 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!!…

基于vue框架的城市智慧地铁管理系统73c2d(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,站点查询,车次线路,站点周边 开题报告内容 基于Vue框架的城市智慧地铁管理系统开题报告 一、研究背景与意义 1.1 研究背景 随着城市化进程的加速和人口的不断增长&#xff0c;城市交通压力日益增大。地铁作为城市公共交通的重要…

【QT】常用类

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;QMediaPlayer&#x1f449;&#x1f3fb;QMediaPlaylistsetPlaybackMode &#x1f449;&#x1f3fb;QDir&#x1f449;…

SparkSQL SET和RESET

前言 我们在用代码写spark程序的时候,如果要设置一些配置参数,可以通过: SparkConf val conf = new SparkConf().setMaster("local[2]").setAppName("CountingSheep") val sc = new SparkContext(conf)spark-submit ./bin/spark-submit --name "M…

虚幻5|知识点(1)寻找查看旋转,击打敌人后朝向主角

举例说明&#xff0c;我们想让角色一直朝着摄像头&#xff0c;我们控制角色任意位置&#xff0c;都能自行旋转都能朝向摄像头 下面是敌人一直朝向角色&#xff0c;无论主角走向哪个位置&#xff0c;敌人都能朝向主角 start是获取敌人的位置向量大小&#xff0c;Target是获取主…

使用LSTM(长短期记忆网络)模型预测股票价格的实例分析

一&#xff1a;LSTM与RNN的区别 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种特殊的循环神经网络&#xff08;RNN&#xff09;架构。LSTM是为了解决传统RNN在处理长序列数据时遇到的梯度消失或梯度爆炸问题而设计的。 在传统的RNN中&#xff0c;信息通过隐藏状…

Android SystemUI组件(06)导航栏创建分析虚拟按键

该系列文章总纲链接&#xff1a;专题分纲目录 Android SystemUI组件 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节持续迭代之前章节的思维导图&#xff0c;主要关注左侧SystemBars分析中导航栏部分即可。 1 导航栏创建之makeStatusBarView 通过上一篇文章的…

Java综合实践——学生成绩查询系统

此系列文章收录大量Java经典代码题&#xff08;也可以算是leetcode刷题指南&#xff09;&#xff0c;剩余文章指路Java题集。希望可以与大家一起探索Java的神秘。3、2、1&#xff0c;请看&#xff01; 本篇文章将带大家一起来写一个学生成绩查询系统。 目录 系统呈现效果 前…

一些硬件知识(二十二)

二极管&#xff08;Diode&#xff09;伏安特性、技术参数和项目中的应用 在正向偏置下&#xff0c;二极管呈现出良好的导电性能&#xff0c;可以允许电流通过&#xff1b;而在反向偏置下&#xff0c;二极管具有很高的阻断能力&#xff0c;几乎不允许电流通过。这是由构成二极管…

new String(),toString()和Arrays.toString()的区别

下面写了一段代码来展示结果 import javax.sound.midi.Soundbank; import java.util.Arrays; import java.util.Scanner;public class Main {public static void main(String[] args) {String str "abc";System.out.println("str:"str);char[] chars st…

Linux编译器-gcc/g++使用

1. 背景知识 1. 预处理&#xff08;进行宏替换) 2. 编译&#xff08;生成汇编) 3. 汇编&#xff08;生成机器可识别代码&#xff09; 4. 连接&#xff08;生成可执行文件或库文件) 2. gcc如何完成 格式 gcc [选项] 要编译的文件 [选项] [目标文件] 预处理(进行宏替换) 编…