添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
谦虚好学的椰子  ·  C#Winform ...·  9 月前    · 
失恋的滑板  ·  js blob转为byte数组-掘金·  1 年前    · 
无邪的猴子  ·  张岳博士·  1 年前    · 

PyTorch 提供了 torch.Tensor 来表示一个包含单一数据类型元素的多维数组。 默认情况下,数组元素连续存储在内存中,从而可以有效地实现各种数组处理算法,这些算法依赖于对数组元素的快速访问。

然而,存在一类重要的多维数组,即所谓的稀疏数组,其中数组元素的连续内存存储被证明是次优的。 稀疏数组具有大部分元素为零的特性 ,这意味着如果仅存储或/和处理非零元素,则可以节省大量内存和处理器资源。

1 构造稀疏矩阵

import torch
i = torch.LongTensor([[0, 1, 1],[2, 0, 2]])   #row, col
v = torch.FloatTensor([3, 4, 5])    #data
torch.sparse.FloatTensor(i, v, torch.Size([2,3])).to_dense()   #torch.Size
tensor([[0., 0., 3.],
        [4., 0., 5.]])

构造方法和 scipy笔记:scipy.sparse_UQI-LIUWJ的博客-CSDN博客 2.2 coo矩阵 的类似

  • 在 PyTorch 中,稀疏张量的填充值不能明确指定,一般假定为零
  • 但是,存在可能以不同方式解释填充值的操作。 例如,torch.sparse.softmax() 计算 softmax 时假设填充值为负无穷大。

1.1 稀疏COO tensor

  •  在 COO 格式(coordinate)中,指定的元素存储为元素索引和相应值的元组。 
    • 元素索引的类型是torch.int64,size是(ndim,nse)
    • 数值类型是任何类型,size是(nse,)
import torch
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [3, 4, 5]
s = torch.sparse_coo_tensor(i, v, (2, 3))
tensor(indices=tensor([[0, 1, 1],
                       [2, 0, 2]]),
       values=tensor([3, 4, 5]),
       size=(2, 3), nnz=3, layout=torch.sparse_coo)
s.is_sparse
#True
s.layout
#torch.sparse_coo

 x坐标为0,y坐标为2的元素是3;x坐标为1,y坐标为1的元素是4.。。。 

1.1.0 稀疏矩阵转换成正常Tensor

s.to_dense()
tensor([[0, 0, 3],
        [4, 0, 5]])

1.1.1 COO tensor和正常tensor(strided tensor)空间复杂度对比

  • COO tensor:ndim*8*nse+<element_size>*nse
  • 正常tensor: <tensor_size>*<element_size>
  • 举例 一个10,000*10,000的 float32 Tensor,其中有100,000个非零元素
    • 正常Tensor的话,需要10 000 * 10 000 * 4 = 400 000 000 比特
    • 使用COO tensor的话,需要(2 * 8 + 4) * 100 000 = 2 000 000比特

1.2.3 创建空的COO tensor

torch.sparse_coo_tensor(size=(2, 3))
tensor(indices=tensor([], size=(2, 0)),
       values=tensor([], size=(0,)),
       size=(2, 3), nnz=0, layout=torch.sparse_coo)

1.2.4 混合稀疏COO Tensor

  • 我们可以将前面value值为标量的稀疏张量扩展到value值为连续张量的稀疏张量。
  • 这种张量称为混合张量。
    • 元素索引的类型是torch.int64,size是(ndim,nse)
    • 数值类型是任何类型,size是(nse,dense_dims)
  • 对应的稀疏矩阵的维度是n_dim+dense_dims
import torch
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [[3,2],[4,1],[5,3]]
s = torch.sparse_coo_tensor(i, v, (2, 3,2))
s,s.to_dense()
(tensor(indices=tensor([[0, 1, 1],
                        [2, 0, 2]]),
        values=tensor([[3, 2],
                       [4, 1],
                       [5, 3]]),
        size=(2, 3, 2), nnz=3, layout=torch.sparse_coo),
 tensor([[[0, 0],
          [0, 0],
          [3, 2]],
         [[4, 1],
          [0, 0],
          [5, 3]]]))

1.2.5 未合并的稀疏COO 张量

  • PyTorch 稀疏 COO 张量格式允许未合并的稀疏张量,其中索引中可能存在重复坐标;
  • 在这种情况下,该索引处的值是所有重复值条目的总和。
  • 例如,可以为同一个索引 1 指定多个值 3 和 4,这会导致未合并张量:
i = [[1, 1]]
v =  [3, 4]
s=torch.sparse_coo_tensor(i, v, (3,))
tensor(indices=tensor([[1, 1]]),
       values=tensor([3, 4]),
       size=(3,), nnz=2, layout=torch.sparse_coo)
s.is_coalesced()
#False

合并(结果仍为稀疏张量) 

s.coalesce()
tensor(indices=tensor([[1]]),
       values=tensor([7]),
       size=(3,), nnz=1, layout=torch.sparse_coo)
s.coalesce().is_coalesced()
# True
s.to_dense()
#tensor([0, 7, 0])

1.2.6 是否需要合并? 

  •  在大多数情况下,不用关心稀疏张量是否被合并,因为在给定合并或未合并稀疏张量的情况下,大多数操作的工作方式相同。
  • 但是,一些操作可以在未合并的张量上更有效地实现,而一些操作可以在合并的张量上更有效地实现。
  • 例如,通过简单地连接索引和值张量来实现稀疏 COO 张量的添加:
a = torch.sparse_coo_tensor([[1, 1]], [5, 6], (2,))
b = torch.sparse_coo_tensor([[0, 0]], [7, 8], (2,))
a + b
tensor(indices=tensor([[0, 0, 1, 1]]),
       values=tensor([7, 8, 5, 6]),
       size=(2,), nnz=4, layout=torch.sparse_coo)

1.2.7 查看indice和value

1)不用事先合并

import torch
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [3, 4, 5]
s = torch.sparse_coo_tensor(i, v, (2, 3))
print(s)
print(s._indices())
print(s._values())
tensor(indices=tensor([[0, 1, 1],
                       [2, 0, 2]]),
       values=tensor([3, 4, 5]),
       size=(2, 3), nnz=3, layout=torch.sparse_coo)
tensor([[0, 1, 1],
        [2, 0, 2]])
tensor([3, 4, 5])

 2) 需要事先合并

print(s.indices())
print(s.values())
RuntimeError                              Traceback (most recent call last)
<ipython-input-27-b4753553cd54> in <module>
      8 s = torch.sparse_coo_tensor(i, v, (2, 3))
      9 print(s)
---> 10 print(s.indices())
     11 print(s.values())
RuntimeError: Cannot get indices on an uncoalesced tensor, please call .coalesce() first
print(s.coalesce().indices())
print(s.coalesce().values())
tensor(indices=tensor([[0, 1, 1],
                       [2, 0, 2]]),
       values=tensor([3, 4, 5]),
       size=(2, 3), nnz=3, layout=torch.sparse_coo)
tensor([[0, 1, 1],
        [2, 0, 2]])
tensor([3, 4, 5])

 1.2.6 sparse_dim 和dense_dim

一个是index的dim,一个是value的dim

import torch
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [3, 4, 5]
s = torch.sparse_coo_tensor(i, v, (2, 3))
print(s.sparse_dim(),s.dense_dim())
#(2,0)
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [[3,2],[4,1],[5,3]]
s = torch.sparse_coo_tensor(i, v, (2, 3,2))
print(s.sparse_dim(),s.dense_dim())
#(2,1)

1.2.7 切片和索引

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

 在sparse维度(index部分)和dense部分(value部分)都可以索引

tensor(indices=tensor([[0, 1, 1], [2, 0, 2]]), values=tensor([[3, 2], [4, 1], [5, 3]]), size=(2, 3, 2), nnz=3, layout=torch.sparse_coo) s[1,0,1] #tensor(1)

切片只能在dense部分切 

s[1,0,1:],s[1,0,0:]
#(tensor([1]), tensor([4, 1]))

2 稀疏矩阵的基本运算

基本上都是第一个参数是sparse的,第二个是正常Tensor

先构造两个稀疏矩阵

import torch
i = torch.LongTensor([[0, 1, 1],[2, 0, 2]])   #row, col
v = torch.FloatTensor([3, 4, 5])    #data
x1=torch.sparse.FloatTensor(i, v, torch.Size([2,3]))
x1,x1.to_dense()  
(tensor(indices=tensor([[0, 1, 1],
                        [2, 0, 2]]),
        values=tensor([3., 4., 5.]),
        size=(2, 3), nnz=3, layout=torch.sparse_coo),
 tensor([[0., 0., 3.],
         [4., 0., 5.]]))
import torch
i = torch.LongTensor([[0, 1, 1],[1, 0, 1]])   #row, col
v = torch.FloatTensor([3, 4, 5])    #data
x2=torch.sparse.FloatTensor(i, v, torch.Size([3,2]))
x2,x2.to_dense() 
(tensor(indices=tensor([[0, 1, 1],
                        [1, 0, 1]]),
        values=tensor([3., 4., 5.]),
        size=(3, 2), nnz=3, layout=torch.sparse_coo),
 tensor([[0., 3.],
         [4., 5.],
         [0., 0.]]))

 2.0 不支持dense * sparse!

pytorch不支持M[strided] @ M[sparse_coo]

如果需要,可以这么整:D @ S == (S.t() @ D.t()).t()

2.1 稀疏矩阵的乘法

2.1.1 torch.mm

只支持第二个参数是dense(即dense*dense,或者sparse*dense),输出是dense

dense*dense
dense*sparse
sparse*sparse
sparse*dense

 2.1.2 torch.sparse.mm

 同样地,只支持第二个参数是dense(即dense*dense,或者sparse*dense) 

dense*dense
dense*sparse
sparse*sparse
sparse*dense

2.1.3 torch.mv

矩阵和向量的乘法,第二个也只能是dense的

import torch
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [3, 4, 5]
s = torch.sparse_coo_tensor(i, v, (2, 3))
print(s.to_dense())
tensor([[0, 0, 3],
        [4, 0, 5]])
t=torch.LongTensor([1,2,3])
torch.mv(s,t),s@t
(tensor([ 9, 19]), tensor([ 9, 19]))

2.1.4 torch.matmul

和torch.mm 类似,第二个也是只能dense

import torch
i = [[0, 1, 1],
    [2, 0, 2]]
v =  [3, 4, 5]
s = torch.sparse_coo_tensor(i, v, (2, 3))
t=torch.LongTensor([[1],[2],[3]])
torch.matmul(s,t),s@t
(tensor([[ 9],
         [19]]),
 tensor([[ 9],
         [19]]))

2.2 转置

 t()即可

x2,x2.to_dense()
(tensor(indices=tensor([[0, 1, 1],
                        [1, 0, 1]]),
        values=tensor([3., 4., 5.]),
        size=(3, 2), nnz=3, layout=torch.sparse_coo),
 tensor([[0., 3.],
         [4., 5.],
         [0., 0.]]))
x2.t(),x2.t().to_dense()
(tensor(indices=tensor([[1, 0, 1],
                        [0, 1, 1]]),
        values=tensor([3., 4., 5.]),
        size=(2, 3), nnz=3, layout=torch.sparse_coo),
 tensor([[0., 4., 0.],
         [3., 5., 0.]]))

 2.3 索引

稀疏矩阵支持整行索引,支持Sparse.matrix[row_index];

x2,x2.to_dense()
(tensor(indices=tensor([[0, 1, 1],
                        [1, 0, 1]]),
        values=tensor([3., 4., 5.]),
        size=(3, 2), nnz=3, layout=torch.sparse_coo),
 tensor([[0., 3.],
         [4., 5.],
         [0., 0.]]))
x2[1],x2[1].to_dense()
(tensor(indices=tensor([[0, 1]]),
        values=tensor([4., 5.]),
        size=(2,), nnz=2, layout=torch.sparse_coo),
 tensor([4., 5.]))

稀疏矩阵不支持具体位置位置索引Sparse.matrix[row_index,col_index]

x2[1][1],x2[1][1].to_dense()

 2.4 相加

a = torch.sparse.FloatTensor(
    torch.tensor([[0,1,2],[2,3,4]]), 
    torch.tensor([1,1,1]), 
    torch.Size([5,5]))
a.to_dense()
tensor([[0, 0, 1, 0, 0],
        [0, 0, 0, 1, 0],
        [0, 0, 0, 0, 1],
        [0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0]])
a1=torch.sparse.FloatTensor(
    torch.tensor([[0,3,2],[2,3,2]]), 
    torch.tensor([1,1,1]), 
    torch.Size([5,5]))
a1.to_dense()
tensor([[0, 0, 1, 0, 0],
        [0, 0, 0, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0]])

 只支持sparse+sparse

torch.add(a,a1) ,torch.add(a,a1).to_dense()
(tensor(indices=tensor([[0, 1, 2, 3, 2],
                        [2, 3, 4, 3, 2]]),
        values=tensor([2, 1, 1, 1, 1]),
        size=(5, 5), nnz=5, layout=torch.sparse_coo),
 tensor([[0, 0, 2, 0, 0],
         [0, 0, 0, 1, 0],
         [0, 0, 1, 0, 1],
         [0, 0, 0, 1, 0],
         [0, 0, 0, 0, 0]]))
a.add(a1),a.add(a1).to_dense()
                    1 构造稀疏矩阵import torchi = torch.LongTensor([[0, 1, 1],[2, 0, 2]])   #row, colv = torch.FloatTensor([3, 4, 5])    #datatorch.sparse.FloatTensor(i, v, torch.Size([2,3])).to_dense()   #torch.Size'''tensor([[0., 0., 3.],        [4., 0., 5.]])'''构造方法和
应该是库和库之间依赖的问题!版本要对应起来!
pip install torch_geometric==1.4.1
pip install torch_sparse==0.4.4
pip install torch_sca
				
  torch.sparse是一个专门处理稀疏张量的模块。通常,张量会按一定的顺序连续地进行存取。但是,对于一个存在很多空值的稀疏张量来说,顺序存储的效率显得较为低下。因此,pytorch推出了稀疏张量的处理模块。在这里,有意义的值被称为specified elements,而无意义的值(空值,通常为0,但是也可以是其他值)则被称为fill value。只有足够稀疏的张量使用这种方式进行存储才能获得更高的效率。 Sparse COO tensors 1 Coordinate format
torch-sparse安装 运行环境需要torch-geometric,下载安装完之后,再 pip install torch-sparse时,一直出错,安装不上 可能原因:需要先安装torch-sparsetorch_scatter,再安装torch-geometric才可以 找了很多解决方法,终于找到个可以解决的了,亲测有效 wget https://pytorch-geometric.com/whl/torch-1.5.0/torch_scatter-2.0.5%2Bcpu-cp37-c
<h3>回答1:</h3><br/>第1关:torch.nn.module torch.nn.module是PyTorch中的一个基,用于定义神经网络模型。它提供了许多有用的方法和属性,例如parameters()和zero_grad(),可以方便地管理模型的参数和梯度。我们可以通过继承torch.nn.module来定义自己的神经网络模型,并在训练过程中使用它们。 <h3>回答2:</h3><br/>第1关:torch.nn.module torch.nn.module 是 PyTorch 中用于构建神经网络模型的基。每个神经网络模型都是由多个层(layer)组成的,每个层都是由不同的参数(如权重和偏置)构成的,并且需要进行训练以优化这些参数,以使其在给定任务上表现最佳。 torch.nn.module 提供了各种方法和属性来管理这些网络层和参数,使得模型的设计、构建、训练和评估变得非常简单。在这个基中,所有的子层都可以通过访问 nn.Module 的属性和方法来获取和访问其参数,同时也可以轻松地控制它们的训练过程。 在构建神经网络时,你需要继承 nn.Module 并定义模型的前向传递函数 forward。在 forward 函数中,你可以将网络的多个层连接在一起来执行特定的计算,从而生成模型的输出。同时,你还需要在 __init__ 函数中定义所有层和参数,并将它们设置为 nn.Parameter 或 nn.ModuleList 对象。这将使你可以使用 nn.Module 的方法来访问、管理和训练它们。 对于每次前向传递,nn.Module 的对象都会自动调用各个层的 forward 函数,并沿着网络的方向反向传播误差,以更新参数和优化模型。在训练过程中,你还可以指定不同的优化方法和损失函数来优化模型的性能,以使模型可以更高效地学习并适应数据。 总之,torch.nn.module 是 PyTorch 中构建深度神经网络模型的基础,提供了一种非常灵活和易用的方式来设计、构建、训练和评估神经网络,在实现复杂的模型时非常实用。 <h3>回答3:</h3><br/>PyTorch中的torch.nn.module是深度学习中常见的模型组件,它是构建神经网络的基本组件。torch.nn.module在PyTorch中被广泛使用,可以用于创建各种深度学习模型,如卷积神经网络、循环神经网络、transformer等。 torch.nn.module的主要作用是简化神经网络的构建过程。它对于神经网络的构建提供了更高层次的抽象,可以仅使用少量的代码来搭建复杂的神经网络。使用torch.nn.module可以更加方便地管理网络中的参数、权重以及偏置项。 当使用torch.nn.module的时候,需要将每个层或者组件写成一个继承自nn.Module的Python。每个继承自nn.Module的都必须实现init函数和forward函数。init函数用于初始化模型层的参数,forward函数定义了模型的前向传播过程。 除了init和forward函数,nn.Module还具有其他常用的方法和属性。其中包括paramters方法,它可以用于获取所有模型层的权重和偏置项;zero_grad方法,用于将所有的梯度清零;还包括train和eval方法,可以用于控制模型处于训练或者评估状态。 总之,torch.nn.module是PyTorch中非常重要的组件,在深度学习中被广泛应用。它的抽象级别可以使得深度学习的构建变得更加简单和快捷,同时还提供了方便的参数管理和训练流程管理方法。
论文笔记:A Multi-source Trajectory Correlation Algorithm based on Spatial-temporal Similarity CSDN-Ada助手: 你好,CSDN 开始提供 #论文阅读# 的列表服务了。请看:https://blog.csdn.net/nav/advanced-technology/paper-reading?utm_source=csdn_ai_ada_blog_reply 。如果你有更多需求,请来这里 https://gitcode.net/csdn/csdn-tags/-/issues/34?utm_source=csdn_ai_ada_blog_reply 给我们提。 论文笔记: Spatiotemporal Recurrent Convolutional Networks for Traffic Prediction in Transportation Netwo CSDN-Ada助手: 你好,CSDN 开始提供 #论文阅读# 的列表服务了。请看:https://blog.csdn.net/nav/advanced-technology/paper-reading?utm_source=csdn_ai_ada_blog_reply 。如果你有更多需求,请来这里 https://gitcode.net/csdn/csdn-tags/-/issues/34?utm_source=csdn_ai_ada_blog_reply 给我们提。 pyecharts 应用5:视觉映射配置项VisualMapOpts UQI-LIUWJ: 方便看一下那几行代码嘛 论文笔记:MEASURING DISENTANGLEMENT: A REVIEW OF METRICS CSDN-Ada助手: 你好,CSDN 开始提供 #论文阅读# 的列表服务了。请看:https://blog.csdn.net/nav/advanced-technology/paper-reading?utm_source=csdn_ai_ada_blog_reply 。如果你有更多需求,请来这里 https://gitcode.net/csdn/csdn-tags/-/issues/34?utm_source=csdn_ai_ada_blog_reply 给我们提。 pyecharts 应用5:视觉映射配置项VisualMapOpts godKnoows: 如何指定 视觉映射配置项 中显示的数字精度,我用了precision,结果不反馈在 数字label中,推测可能只是在分组计算时起效 论文笔记:A Multi-source Trajectory Correlation Algorithm based on Spatial-temporal Similarity 论文笔记: Spatiotemporal Recurrent Convolutional Networks for Traffic Prediction in Transportation Netwo 论文笔记:MEASURING DISENTANGLEMENT: A REVIEW OF METRICS