📜  Pytorch——基于索引的操作

📅  最后修改于: 2022-05-13 01:55:43.164000             🧑  作者: Mango

Pytorch——基于索引的操作

PyTorch是 Facebook 开发的Python库,用于运行和训练深度学习和机器学习算法。张量是机器或深度学习算法的基本数据结构,为了处理它们,我们执行了多种操作,PyTorch 库为此提供了许多功能。

处理某些特定行或列上的索引以复制、添加、填充值/张量的张量操作被称为基于索引的开发操作。 PyTorch 中有两种基于索引的操作,一种是就地操作,另一种是非就地操作。两者之间的基本区别是就地操作直接更改张量的值而不进行任何复制,而异地操作则不会。以下是操作:-

  1. index_add_
  2. 索引添加
  3. index_copy_
  4. index_copy
  5. index_fill_
  6. 索引填充
  7. index_put_
  8. index_put
  9. 索引选择

现在我们用适当的例子讨论每个函数。

1. index_add_:按照矩阵中给定的顺序将给定的张量元素添加到自张量中。

句法:



index_add_(dim,index,ensor)---> Tensor

参数:

  • 暗淡:沿哪个索引添加的维度。 “0”代表列,“1”代表行。
  • index:要从中选择的张量的索引。它可以是LongTensorIntTensor
  • 张量:包含要添加的值的张量。

示例 1:我们采用零向量 'x'、大小为 (3,5) 的te张量和索引张量。沿行累积结果向量,我们得到输出。

Python3
#importing libraries
import torch
  
x=torch.zeros(5,5)
te=torch.tensor([[1,3,5,7,9],[1,3,5,7,9],[1,3,5,7,9]],dtype=torch.float32)
index0=torch.tensor([0,2,4])
#adding tensor te to x along row of the given order
x.index_add_(0,index0,te)


Python3
#importing libraries
import torch
  
y=torch.ones(5,5)#unitvector
index2=torch.tensor([0,1,1,1,2])
ten=torch.randn(1,5)
#adding values to y along the column with given order
y.index_add_(1,index2,ten)


Python3
import torch
  
y=torch.ones(5,5)
  
index2=torch.tensor([0,1,1,1,2])
ten=torch.randn(1,5)
print("Indexed Matrix:\n",y.index_add(1,index2,ten))
print ("Printing Indexed Matrix again:\n",y)


Python3
#importing libraries
import torch
  
a=torch.ones(4,4)#unit vector
t1=torch.randn(2,4)
index3=torch.tensor([1,3])
  
#copying elements of t1 ensor to 'a' in given order of index
a.index_copy_(0,index3,t1)


Python3
#importing libraries
import torch
  
y=torch.ones(5,5)
index1=torch.tensor([0,1,2,3,4])
te=torch.tensor([[1,3,5,7,9],[1,3,5,7,9],[1,3,5,7,9]],dtype=torch.float32)
y.index_copy_(1,index1,te)


Python3
import torch
  
b=torch.ones(4,4)
t2=torch.randn(4,2)
  
index4=torch.tensor([0,1])
b.index_copy_(1,index4,t2)


Python3
#importing libraries
import torch
c=torch.randn(4,4)
  
index5=torch.tensor([0,2])
  
#filling 4 within the elements of the tensor 'c' along the indices 0,2
c.index_fill_(0,index5,4)
print(c)


Python3
d=torch.randn(5,5)
  
d.index_fill(1,index5,2)
print(d)


Python3
#importing libraries
import torch
   
target=torch.zeros([4,4])
indices = torch.LongTensor([[0,1],[1,2],[3,1],[1,0]])#indices to which values to be put
value = torch.ones(indices.shape[0])
#tuple of the index tensor is passed along with the value
target.index_put_(tuple(indices.t()), value)


Python3
e=torch.ones([4,4])
indices2=torch.LongTensor([[0,1],[0,1],[2,1]])
value2=torch.zeros(indices2.shape[0])
  
e.index_put_(tuple(indices2.t()),value2,accumulate=True)


Python3
#importing libraries
import torch
  
m=torch.randn(3,4)
print('Original matrix:\n',m)
indices=torch.tensor([0,1])
print("Indexed Matrix:\n",torch.index_select(m, 0, indices))


输出:

tensor([[1., 3., 5., 7., 9.],
        [0., 0., 0., 0., 0.],
        [1., 3., 5., 7., 9.],
        [0., 0., 0., 0., 0.],
        [1., 3., 5., 7., 9.]])

示例 2:

蟒蛇3

#importing libraries
import torch
  
y=torch.ones(5,5)#unitvector
index2=torch.tensor([0,1,1,1,2])
ten=torch.randn(1,5)
#adding values to y along the column with given order
y.index_add_(1,index2,ten)

输出:

tensor([[0.9460, 0.4762, 1.2219, 1.0000, 1.0000],
        [0.9460, 0.4762, 1.2219, 1.0000, 1.0000],
        [0.9460, 0.4762, 1.2219, 1.0000, 1.0000],
        [0.9460, 0.4762, 1.2219, 1.0000, 1.0000],
        [0.9460, 0.4762, 1.2219, 1.0000, 1.0000]])

2.index_add:是上述函数的异地版本。这会暂时将给定的张量添加到张量。参数和语法与上面相同。

示例 3:

蟒蛇3

import torch
  
y=torch.ones(5,5)
  
index2=torch.tensor([0,1,1,1,2])
ten=torch.randn(1,5)
print("Indexed Matrix:\n",y.index_add(1,index2,ten))
print ("Printing Indexed Matrix again:\n",y)

输出:



Indexed Matrix:
 tensor([[-0.2811, -1.0776,  2.2697,  1.0000,  1.0000],
        [-0.2811, -1.0776,  2.2697,  1.0000,  1.0000],
        [-0.2811, -1.0776,  2.2697,  1.0000,  1.0000],
        [-0.2811, -1.0776,  2.2697,  1.0000,  1.0000],
        [-0.2811, -1.0776,  2.2697,  1.0000,  1.0000]])
Printing Indexed Matrix again:
 tensor([[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]])

3.index_copy_:通过按'index'中给出的顺序选择索引,将给定张量的元素复制到输入张量。

句法:

index_copy_(dim,index,tensor)---> Tensor

参数:

  • 暗淡:沿哪个索引复制的维度。它是“int”格式。
  • index:要从中选择的张量的索引。它可以是IntTensorLongTensor。
  • 张量:包含要复制的值的张量。

示例 4:这里的 'a' 元素按照 'index3' 中给出的顺序被 't1' 张量替换。

蟒蛇3

#importing libraries
import torch
  
a=torch.ones(4,4)#unit vector
t1=torch.randn(2,4)
index3=torch.tensor([1,3])
  
#copying elements of t1 ensor to 'a' in given order of index
a.index_copy_(0,index3,t1)

输出:

tensor([[ 1.0000,  1.0000,  1.0000,  1.0000],
        [-0.1918, -1.2089,  0.3229, -0.1831],
        [ 1.0000,  1.0000,  1.0000,  1.0000],
        [ 0.7521,  0.8424, -0.8698, -0.3908]])

示例 5:在下面的示例中,我们将收到一个错误。这是因为张量的dim 维不等于索引的长度。所以我们必须记住,张量的dim 维度必须与索引的长度具有相同的大小。

蟒蛇3

#importing libraries
import torch
  
y=torch.ones(5,5)
index1=torch.tensor([0,1,2,3,4])
te=torch.tensor([[1,3,5,7,9],[1,3,5,7,9],[1,3,5,7,9]],dtype=torch.float32)
y.index_copy_(1,index1,te)

输出:

RuntimeError                              Traceback (most recent call last)
 in 
      1 y=torch.ones(5,5)
      2 index1=torch.tensor([0,1,2,3,4])
----> 3 y.index_copy_(1,index1,te)

RuntimeError: index_copy_(): Source/destination tensor must have same slice shapes.
Destination slice shape: 5 at dimension 1 and source slice shape: 3 at dimension 0.

示例 6:在此,我们将给定的张量复制到自张量,记住张量的dim 维度必须与索引的长度具有相同的大小。

蟒蛇3

import torch
  
b=torch.ones(4,4)
t2=torch.randn(4,2)
  
index4=torch.tensor([0,1])
b.index_copy_(1,index4,t2)

输出:

tensor([[-0.3964, -0.3859,  1.0000,  1.0000],
        [ 2.6910, -0.9394,  1.0000,  1.0000],
        [ 0.3591, -0.2262,  1.0000,  1.0000],
        [ 1.2102, -0.8340,  1.0000,  1.0000]])

4.index_copy:这是一种基于索引的异地操作,用于用给定的张量替换输入张量的元素。语法、参数同上。



5.index_fill_: 'Val' 值由 'x' 的元素以及向量 'index' 中给出的索引顺序填充。

句法:

index_fill_(dim, index, val) → Tensor

参数:

  • 暗淡:沿其填充的维度。它是“int”格式。
  • 索引:按此索引向量中给出的索引的顺序填充。它可以是 IntTensor 或 LongTensor。
  • val(float): 要填充的值。

例 7:在本例中,我们将声明一个带有随机元素的张量,然后用 '4' 和给定的索引填充它。

蟒蛇3

#importing libraries
import torch
c=torch.randn(4,4)
  
index5=torch.tensor([0,2])
  
#filling 4 within the elements of the tensor 'c' along the indices 0,2
c.index_fill_(0,index5,4)
print(c)

输出:

tensor([[ 4.0000,  4.0000,  4.0000,  4.0000],
        [ 0.4762,  0.0056,  0.3258,  1.1345],
        [ 4.0000,  4.0000,  4.0000,  4.0000],
        [-0.1490, -0.6543,  0.9755,  1.8087]])

示例 8:类似地,我们与列一起执行填充操作。

蟒蛇3

d=torch.randn(5,5)
  
d.index_fill(1,index5,2)
print(d)

输出:

tensor([[ 0.5978, -1.2461, -0.8794, -1.0175,  0.8938],
        [-0.6374,  1.0848,  0.1291,  0.6658,  0.3081],
        [-0.9686, -0.8212, -0.5223, -0.3208, -1.7718],
        [-0.1153, -1.2552, -0.4119, -1.1293,  0.2266],
        [ 1.2610,  0.2618, -1.5528,  0.7805,  1.3730]])

6. index_fill:这是一种不合适的基于索引的操作,用于用带有“val”的张量填充元素。语法、参数同上。

7.index_put_:此操作使用给定“index”的索引将“val”的值放入自张量中。

句法:



index_put_(indices, values, accumulate=False) → Tensor

参数:

  • 索引:它是 LongTensor 的元组,用于索引自我。
  • values:具有需要放入目标的值的张量。
  • 累积:是否累积。

例 9:这里我们取目标向量,并替换了前面提到的值张量的值

蟒蛇3

#importing libraries
import torch
   
target=torch.zeros([4,4])
indices = torch.LongTensor([[0,1],[1,2],[3,1],[1,0]])#indices to which values to be put
value = torch.ones(indices.shape[0])
#tuple of the index tensor is passed along with the value
target.index_put_(tuple(indices.t()), value)

输出:

tensor([[0., 1., 0., 0.],
       [1., 0., 1., 0.],
       [0., 0., 0., 0.],
       [0., 1., 0., 0.]])

注意:我们必须对索引张量进行转置,否则会发生错误。

示例 10:在此示例中,我们将累加函数保持为 true,这意味着将 value 中的元素添加到目标中。

蟒蛇3

e=torch.ones([4,4])
indices2=torch.LongTensor([[0,1],[0,1],[2,1]])
value2=torch.zeros(indices2.shape[0])
  
e.index_put_(tuple(indices2.t()),value2,accumulate=True)
Output:
tensor([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])

8. index_fill:这是index_fill_ 的不合适版本。语法、参数同上。

9. index_select:通过从目标张量中选择,返回一个带有索引的张量。

句法:

torch.index_select(input, dim, index, out=None) 

参数:

  • 输入(张量):从中选择索引的张量。
  • dim(int):要选择的维度。
  • index:它包含索引的索引。

示例 11:我们沿 dim=0 即行拾取张量 'm' 的 0,1 个索引并打印输出。

蟒蛇3

#importing libraries
import torch
  
m=torch.randn(3,4)
print('Original matrix:\n',m)
indices=torch.tensor([0,1])
print("Indexed Matrix:\n",torch.index_select(m, 0, indices))

输出:

Original matrix:
 tensor([[ 0.2008, -0.2637,  2.1216, -0.2892],
        [-0.4059, -1.6054, -2.5022, -0.2912],
        [-0.3246,  0.4751, -0.1018, -0.6707]])
Indexed Matrix:
 tensor([[ 0.2008, -0.2637,  2.1216, -0.2892],
        [-0.4059, -1.6054, -2.5022, -0.2912]])

参考: https : //pytorch.org/docs/stable/tensors.html