PyTorch torch稀疏

2020-09-15 11:33 更新

原文: PyTorch torch稀疏

警告

該 API 目前處于實(shí)驗(yàn)階段,可能會(huì)在不久的將來進(jìn)行更改。

Torch 支持 COO(rdinate)格式的稀疏張量,該稀疏張量可以有效地存儲(chǔ)和處理大多數(shù)元素為零的張量。

稀疏張量表示為一對(duì)密集張量:一個(gè)值張量和一個(gè) 2D 索引張量。 可以通過提供這兩個(gè)張量以及稀疏張量的大小(無法從這些張量推斷出)來構(gòu)造稀疏張量假設(shè)我們要定義一個(gè)稀疏張量,其入口 3 位于位置(0,2) ,位置(1、0)處的條目 4 和位置(1、2)處的條目 5。 然后我們將寫:

>>> i = torch.LongTensor([[0, 1, 1],
                          [2, 0, 2]])
>>> v = torch.FloatTensor([3, 4, 5])
>>> torch.sparse.FloatTensor(i, v, torch.Size([2,3])).to_dense()
 0  0  3
 4  0  5
[torch.FloatTensor of size 2x3]

請(qǐng)注意,LongTensor 的輸入不是索引元組的列表。 如果要以這種方式編寫索引,則應(yīng)在將索引傳遞給稀疏構(gòu)造函數(shù)之前進(jìn)行轉(zhuǎn)置:

>>> i = torch.LongTensor([[0, 2], [1, 0], [1, 2]])
>>> v = torch.FloatTensor([3,      4,      5    ])
>>> torch.sparse.FloatTensor(i.t(), v, torch.Size([2,3])).to_dense()
 0  0  3
 4  0  5
[torch.FloatTensor of size 2x3]

您還可以構(gòu)造混合稀疏張量,其中僅前 n 個(gè)維是稀疏的,其余維是密集的。

>>> i = torch.LongTensor([[2, 4]])
>>> v = torch.FloatTensor([[1, 3], [5, 7]])
>>> torch.sparse.FloatTensor(i, v).to_dense()
 0  0
 0  0
 1  3
 0  0
 5  7
[torch.FloatTensor of size 5x2]

可以通過指定大小來構(gòu)造一個(gè)空的稀疏張量:

>>> torch.sparse.FloatTensor(2, 3)
SparseFloatTensor of size 2x3 with indices:
[torch.LongTensor with no dimension]
and values:
[torch.FloatTensor with no dimension]
SparseTensor has the following invariants:

  1. sparse_dim + density_dim = len(SparseTensor.shape)
  2. SparseTensor._indices()。shape =(sparse_dim,nnz)
  3. SparseTensor._values()。shape =(nnz,SparseTensor.shape [sparse_dim:])

由于 SparseTensor._indices()始終是 2D 張量,因此最小的 sparse_dim =1。因此,sparse_dim = 0 的 SparseTensor 的表示只是一個(gè)密集的張量。

注意

我們的稀疏張量格式允許不分眾的稀疏張量,其中索引中可能有重復(fù)的坐標(biāo); 在這種情況下,解釋是該索引處的值是所有重復(fù)值條目的總和。 張量張量允許我們更有效地實(shí)施某些運(yùn)算符。

在大多數(shù)情況下,您不必?fù)?dān)心稀疏張量是否合并,因?yàn)樵诤喜⒒蛭春喜⑾∈鑿埩康那闆r下,大多數(shù)操作都可以相同地工作。 但是,在兩種情況下,您可能需要注意。

首先,如果您反復(fù)執(zhí)行可能產(chǎn)生重復(fù)項(xiàng)的操作(例如 torch.sparse.FloatTensor.add()),則應(yīng)偶爾合并稀疏張量以防止它們變得太大。

其次,某些運(yùn)算符會(huì)根據(jù)是否合并而產(chǎn)生不同的值(例如 torch.sparse.FloatTensor._values()torch.sparse.FloatTensor._indices() 以及 torch.Tensor.sparse_mask())。 這些運(yùn)算符以下劃線作為前綴,表示它們揭示了內(nèi)部實(shí)現(xiàn)細(xì)節(jié),因此應(yīng)謹(jǐn)慎使用,因?yàn)榕c合并的稀疏張量一起使用的代碼可能不適用于未合并的稀疏張量; 一般來說,與這些運(yùn)營(yíng)商合作之前,明確合并是最安全的。

例如,假設(shè)我們想通過直接在 torch.sparse.FloatTensor._values() 上進(jìn)行操作來實(shí)現(xiàn)一個(gè)運(yùn)算符。 標(biāo)量乘法可以很明顯地實(shí)現(xiàn),因?yàn)槌朔ǚ植荚诩臃ㄉ稀?但是,平方根不能直接實(shí)現(xiàn),因?yàn)?code>sqrt(a + b) != sqrt(a) + sqrt(b)(如果給定非張量的張量,將計(jì)算出平方根)。

class torch.sparse.FloatTensor?

add()?

add_()?

clone()?

dim()?

div()?

div_()?

get_device()?

hspmm()?

mm()?

mul()?

mul_()?

narrow_copy()?

resizeAs_()?

size()?

spadd()?

spmm()?

sspaddmm()?

sspmm()?

sub()?

sub_()?

t_()?

to_dense()?

transpose()?

transpose_()?

zero_()?

coalesce()?

is_coalesced()?

_indices()?

_values()?

_nnz()?

功能

torch.sparse.addmm(mat, mat1, mat2, beta=1, alpha=1)?

該函數(shù)與 torch.addmm() 的功能完全相同,只是它支持稀疏矩陣mat1的向后功能。 mat1需要具有 <cite>sparse_dim = 2</cite> 。 請(qǐng)注意,mat1的梯度是合并的稀疏張量。

參數(shù)

  • (tensor)–要添加的密集矩陣
  • mat1 (SparseTensor )–要相乘的稀疏矩陣
  • mat2 (tensor)–密矩陣相乘
  • beta (數(shù)字 , 可選)– mat(img)的乘數(shù)
  • alpha (編號(hào) , 可選)– img(img)的乘數(shù)

torch.sparse.mm(mat1, mat2)?

對(duì)稀疏矩陣mat1與密集矩陣mat2進(jìn)行矩陣乘法。 與 torch.mm() 相似,如果mat1img張量,mat2img張量,則輸出將是img密集張量。 mat1需要具有 <cite>sparse_dim = 2</cite> 。 此功能還支持兩個(gè)矩陣的向后。 請(qǐng)注意,mat1的梯度是合并的稀疏張量。

Parameters

  • mat1 (SparseTensor )–第一個(gè)要相乘的稀疏矩陣
  • mat2 (tensor)–要相乘的第二個(gè)密集矩陣

例:

>>> a = torch.randn(2, 3).to_sparse().requires_grad_(True)
>>> a
tensor(indices=tensor([[0, 0, 0, 1, 1, 1],
                       [0, 1, 2, 0, 1, 2]]),
       values=tensor([ 1.5901,  0.0183, -0.6146,  1.8061, -0.0112,  0.6302]),
       size=(2, 3), nnz=6, layout=torch.sparse_coo, requires_grad=True)


>>> b = torch.randn(3, 2, requires_grad=True)
>>> b
tensor([[-0.6479,  0.7874],
        [-1.2056,  0.5641],
        [-1.1716, -0.9923]], requires_grad=True)


>>> y = torch.sparse.mm(a, b)
>>> y
tensor([[-0.3323,  1.8723],
        [-1.8951,  0.7904]], grad_fn=<SparseAddmmBackward>)
>>> y.sum().backward()
>>> a.grad
tensor(indices=tensor([[0, 0, 0, 1, 1, 1],
                       [0, 1, 2, 0, 1, 2]]),
       values=tensor([ 0.1394, -0.6415, -2.1639,  0.1394, -0.6415, -2.1639]),
       size=(2, 3), nnz=6, layout=torch.sparse_coo)

torch.sparse.sum(input, dim=None, dtype=None)?

返回給定維度dim中 SparseTensor input每行的總和。 如果dim是尺寸列表,請(qǐng)縮小所有尺寸。 當(dāng)對(duì)所有sparse_dim求和時(shí),此方法返回張量而不是 SparseTensor。

壓縮所有求和的dim(請(qǐng)參見 torch.squeeze()),從而使輸出張量的尺寸比input小。

在向后期間,僅inputnnz位置處的梯度將傳播回去。 注意,input的梯度是合并的。

Parameters

  • 輸入 (tensor)–輸入 SparseTensor
  • 暗淡的 (python:int python:ints 的元組)–一個(gè)要減小的尺寸或尺寸列表。 默認(rèn)值:減少所有暗淡。
  • dtype (torch.dtype,可選)–返回的 Tensor 的所需數(shù)據(jù)類型。 默認(rèn)值:input的 dtype。

Example:

>>> nnz = 3
>>> dims = [5, 5, 2, 3]
>>> I = torch.cat([torch.randint(0, dims[0], size=(nnz,)),
                   torch.randint(0, dims[1], size=(nnz,))], 0).reshape(2, nnz)
>>> V = torch.randn(nnz, dims[2], dims[3])
>>> size = torch.Size(dims)
>>> S = torch.sparse_coo_tensor(I, V, size)
>>> S
tensor(indices=tensor([[2, 0, 3],
                       [2, 4, 1]]),
       values=tensor([[[-0.6438, -1.6467,  1.4004],
                       [ 0.3411,  0.0918, -0.2312]],


                      [[ 0.5348,  0.0634, -2.0494],
                       [-0.7125, -1.0646,  2.1844]],


                      [[ 0.1276,  0.1874, -0.6334],
                       [-1.9682, -0.5340,  0.7483]]]),
       size=(5, 5, 2, 3), nnz=3, layout=torch.sparse_coo)


## when sum over only part of sparse_dims, return a SparseTensor
>>> torch.sparse.sum(S, [1, 3])
tensor(indices=tensor([[0, 2, 3]]),
       values=tensor([[-1.4512,  0.4073],
                      [-0.8901,  0.2017],
                      [-0.3183, -1.7539]]),
       size=(5, 2), nnz=3, layout=torch.sparse_coo)


## when sum over all sparse dim, return a dense Tensor
## with summed dims squeezed
>>> torch.sparse.sum(S, [0, 1, 3])
tensor([-2.6596, -1.1450])
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)