美文网首页
[PyTorch中文文档]-Package参考-torch-索引

[PyTorch中文文档]-Package参考-torch-索引

作者: 六千宛 | 来源:发表于2021-08-06 11:09 被阅读0次

    torch.cat(inputs, dimension=0) → Tensor

    在给定维度上对输入的张量序列seq 进行连接操作。
    torch.cat()可以看做 torch.split() 和 torch.chunk()的反操作。 cat() 函数可以通过下面例子更好的理解。
    参数:
    inputs (sequence of Tensors) – 可以是任意相同Tensor 类型的python 序列
    dimension (int, optional) – 沿着此维连接张量序列。
    例子:

    >>> x = torch.randn(2, 3)
    >>> x
    
     0.5983 -0.0341  2.4918
     1.5981 -0.5265 -0.8735
    [torch.FloatTensor of size 2x3]
    
    >>> torch.cat((x, x, x), 0)
    
     0.5983 -0.0341  2.4918
     1.5981 -0.5265 -0.8735
     0.5983 -0.0341  2.4918
     1.5981 -0.5265 -0.8735
     0.5983 -0.0341  2.4918
     1.5981 -0.5265 -0.8735
    [torch.FloatTensor of size 6x3]
    
    >>> torch.cat((x, x, x), 1)
     0.5983 -0.0341  2.4918  0.5983 -0.0341  2.4918  0.5983 -0.0341  2.4918
     1.5981 -0.5265 -0.8735  1.5981 -0.5265 -0.8735  1.5981 -0.5265 -0.8735
    [torch.FloatTensor of size 2x9]
    

    torch.chunk(tensor, chunks, dim=0)

    torch.chunk(tensor, chunk_num, dim)与torch.cat()原理相反,它是将tensor按dim(行或列)分割成chunk_num个tensor块,返回的是一个元组。

    a = torch.Tensor([[1,2,4]])
    b = torch.Tensor([[4,5,7], [3,9,8], [9,6,7]])
    c = torch.cat((a,b), dim=0)
    print(c)
    print(c.size())
    print('********************')
    d = torch.chunk(c,4,dim=0)
    print(d)
    print(len(d))
    

    torch.gather(input, dim, index, out=None) → Tensor

    作用:收集输入的特定维度指定位置的数值
    参数:
    input(tensor): 待操作数。不妨设其维度为(x1, x2, …, xn)
    dim(int): 待操作的维度。
    index(LongTensor): 如何对input进行操作。其维度有限定,例如当dim=i时,index的维度为(x1, x2, …y, …,xn),既是将input的第i维的大小更改为y,且要满足y>=1(除了第i维之外的其他维度,大小要和input保持一致)。
    out: 注意输出和index的维度是一致的

    import torch
    a = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15] ])
    index = torch.tensor([[0, 2],[3, 4], [1, 4]])
    print(torch.gather(a, 1, index))
    #tensor([[ 1,  3],
    #                [ 9, 10],
    #                [12, 15]])
    

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

    沿着指定维度对输入进行切片,取index中指定的相应项(index为一个LongTensor),然后返回到一个新的张量, 返回的张量与原始张量Tensor有相同的维度(在指定轴上)。

    注意: 返回的张量不与原始张量共享内存空间。
    参数:
    input (Tensor) – 输入张量
    dim (int) – 索引的轴
    index (LongTensor) – 包含索引下标的一维张量
    out (Tensor, optional) – 目标张量

    >>> x = torch.randn(3, 4)
    >>> x
    
     1.2045  2.4084  0.4001  1.1372
     0.5596  1.5677  0.6219 -0.7954
     1.3635 -1.2313 -0.5414 -1.8478
    [torch.FloatTensor of size 3x4]
    
    >>> indices = torch.LongTensor([0, 2])
    >>> torch.index_select(x, 0, indices)
    
     1.2045  2.4084  0.4001  1.1372
     1.3635 -1.2313 -0.5414 -1.8478
    [torch.FloatTensor of size 2x4]
    
    >>> torch.index_select(x, 1, indices)
    
     1.2045  0.4001
     0.5596  0.6219
     1.3635 -0.5414
    [torch.FloatTensor of size 3x2]
    

    torch.masked_select(input, mask, out=None) → Tensor

    根据掩码张量mask中的二元值,取输入张量中的指定项( mask为一个 ByteTensor),将取值返回到一个新的1D张量,
    张量 mask须跟input张量有相同数量的元素数目,但形状或维度不需要相同。 注意: 返回的张量不与原始张量共享内存空间。
    参数:
    input (Tensor) – 输入张量
    mask (ByteTensor) – 掩码张量,包含了二元索引值
    out (Tensor, optional) – 目标张量

    >>> x = torch.randn(3, 4)
    >>> x
    tensor([[ 0.3552, -2.3825, -0.8297,  0.3477],
            [-1.2035,  1.2252,  0.5002,  0.6248],
            [ 0.1307, -2.0608,  0.1244,  2.0139]])
    >>> mask = x.ge(0.5)
    >>> mask
    tensor([[False, False, False, False],
            [False, True, True, True],
            [False, False, False, True]])
    >>> torch.masked_select(x, mask)
    tensor([ 1.2252,  0.5002,  0.6248,  2.0139])
    

    使用方法其实挺明显的,就是把input与mask相对应起来,取出mask中True所对应位置的数据,组成一维的tensor。
    注意:mask和input的形状可以不相同,但是它们必须是可以广播的。并且返回tensor和原tensor使用不同的内存,相互独立。

    torch.nonzero(input, out=None) → LongTensor

    找出tensor中非零的元素的索引。返回一个包含输入 input 中非零元素索引的张量.输出张量中的每行包含 input 中非零元素的索引。
    torch.nonzero(input, *, out=None, as_tuple=False)


    image.png
    import torch
     
    label = torch.tensor([[1,0,0],
                          [1,0,1]])
    print(label.nonzero())
     
    输出:
    tensor([[0, 0],
            [1, 0],
            [1, 2]])
    

    有时我们只想得到一种元素对应的索引,比如我们只想要1对应的索引:

    import torch
     
    label = torch.tensor([[1,0,0],
                          [3,0,1]])
    print((label==1).nonzero())
     
    输出:
    tensor([[0, 0],
            [1, 2]])
    

    或者,我们想要一定条件下的元素的索引,比如大于1的元素的索引:

    import torch
     
    label = torch.tensor([[1,0,0],
                          [3,0,1]])
    print((label>1).nonzero())
     
    输出:
    tensor([[1, 0]])
    

    torch.split(tensor, split_size, dim=0)

    将输入张量分割成相等形状的chunks(如果可分)。 如果沿指定维的张量形状大小不能被split_size 整分, 则最后一个分块会小于其它分块。
    参数:
    tensor (Tensor) – 待分割张量
    split_size (int) – 单个分块的形状大小
    dim (int) – 沿着此维进行分割

    split_size_or_sections为int型时

    import torch
     
    x = torch.rand(4,8,6)
    y = torch.split(x,2,dim=0) #按照4这个维度去分,每大块包含2个小块
    for i in y :
        print(i.size())
     
    output:
    torch.Size([2, 8, 6])
    torch.Size([2, 8, 6])
     
    y = torch.split(x,3,dim=0)#按照4这个维度去分,每大块包含3个小块
    for i in y:
        print(i.size())
     
    output:
    torch.Size([3, 8, 6])
    torch.Size([1, 8, 6])
    

    split_size_or_sections为list型时。

    import torch
     
    x = torch.rand(4,8,6)
    y = torch.split(x,[2,3,3],dim=1)
    for i in y:
        print(i.size())
     
    output:
    torch.Size([4, 2, 6])
    torch.Size([4, 3, 6])
    torch.Size([4, 3, 6])
     
     
    y = torch.split(x,[2,1,3],dim=1) #2+1+3 等于7,报错
    for i in y:
        print(i.size())
     
    output:
    split_with_sizes expects split_sizes to sum exactly to 8 (input tensor's size at dimension 1), but got split_sizes=[2, 1, 3]
    

    torch.squeeze(input, dim=None, out=None)

    核心功能:
    这个函数主要对数据的维度进行压缩,去掉维数为1的的维度。比如:是一行或者一列这种,一个一行三列(1,3)的数去掉第一个维数为一的维度之后就变成(3)行。b=torch.squeeze(a,N) 就是将a中所有为1的维度删掉,不为1的维度没有影响。

    参数说明:
    input (Tensor): 输入张量(the input tensor.)
    dim (int, optional): 将输入Tensor的第dim个维度位置进行压缩,如果输入Tensor此处维度为1则压缩成功,否则失败。如果该参数给定,则输入张量将仅在该维度上压缩(if given, the input will be squeezed only in this dimension.),如果该参数不给定,则默认将输入Tensor所有维度为1的进行压缩。参数dim的取值范围为:[-input.dim(), input.dim()-1] 。

    x = torch.zeros(2, 1, 2, 1, 2)
    x
    >>>
    tensor([[[[[0., 0.]],
    
              [[0., 0.]]]],
    
    
    
            [[[[0., 0.]],
    
              [[0., 0.]]]]])
    print(x.size())
    >>> torch.Size([2, 1, 2, 1, 2])
    y = torch.squeeze(x)
    y
    >>>
    tensor([[[0., 0.],
             [0., 0.]],
    
            [[0., 0.],
             [0., 0.]]])
    print(y.size())
    >>> torch.Size([2, 2, 2])
    
    # 如果第一个维度为一,则将其进行压缩;否则,不能压缩
    y = torch.squeeze(x, 0)  # 或者 y = torch.squeeze(x, dim=0)
    print(y.size())
    >>> torch.Size([2, 1, 2, 1, 2])
    
    # 如果第二个维度为一,则将其进行压缩
    y = torch.squeeze(x, 1)  # 或者 y = torch.squeeze(x, dim=1)
    print(y.size())
    >>> torch.Size([2, 2, 1, 2])
    
    # 如果第三个维度为一,则将其进行压缩;否则,不能压缩
    y = torch.squeeze(x, 2)  # 或者 y = torch.squeeze(x, dim=2)
    print(y.size())
    >>> torch.Size([2, 1, 2, 1, 2])
    
    # 如果第四个维度为一,则将其进行压缩
    y = torch.squeeze(x, dim=3)   # 或者 y = torch.squeeze(x, dim=3)
    print(y.size())
    torch.Size([2, 1, 2, 2])
    
    # 如果第五个维度为一,则将其进行压缩
    y = torch.squeeze(x, dim=4)   # 或者 y = torch.squeeze(x, dim=4)
    print(y.size())
    torch.Size([2, 1, 2, 1, 2])
    

    torch.unsqueeze(input, dim)

    核心功能:
    在tensor的某个维度上添加一个维数为1的维度,这个功能用view()函数也可以实现。比如:原本有个三行的数据(3),在0的位置加了一维就变成一行三列(1,3)。a.unsqueeze(N) 就是在a中指定位置N加上一个维数为1的维度。还有一种形式就是b=torch.unsqueeze(a,N) a就是在a中指定位置N加上一个维数为1的维度。这一功能尤其在神经网络输入单个样本时很有用,由于pytorch神经网络要求的输入都是mini-batch型的,维度为[batch_size, channels, w, h],而一个样本的维度为[c, w, h],此时用unsqueeze()增加一个维度变为[1, c, w, h]就很方便了。

    参数说明:
    input (Tensor):输入张量(the input tensor.)
    dim (int):插入维数为一的维度的位置(the index at which to insert the singleton dimension.)参数dim的取值范围为:[-input.dim() - 1, input.dim() + 1)

    备注: 以0为分界,正向取值和反向取值的效果相同,其原理类似DataFrame中的正向、反向切片操作。正向取值时,0表示行,1表示列;反向取值时,-1表示列,-2表示行。
    \quad
    例如:若input。dim()==1,此时,dim的取值范围为[-2,2),正向取值时——dim=0(表示:行维度为1,即:新生成Tensor的shape为 torch.Size([1, 100]) );dim=1(表示:列维度为1,即:新生成Tensor的shape为 torch.Size([100, 1]) ))。反向取值时——dim=-2(表示:行维度为1,即:新生成Tensor的shape为 torch.Size([1, 100]) );dim=-1(表示:列维度为1,即:新生成Tensor的shape为 torch.Size([100, 1]) )

    a = torch.linspace(-1, 1, 100)  # 生成-1到1的100个数构成的等差数列
    print(a.shape)
    >>> torch.Size([100])
    
    x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # dim=1,表示列方向维度为1
    print(x.shape)
    >>> torch.Size([100, 1])
    
    x = torch.tensor([1, 2, 3, 4])
    torch.unsqueeze(x, 0)
    >>> tensor([[ 1,  2,  3,  4]])
    torch.unsqueeze(x, 1)
    >>> tensor([[ 1],
                [ 2],
                [ 3],
                [ 4]])
    
    x = torch.zeros(2, 2, 2)
    print(x.shape)
    >>> torch.Size([2, 2, 2])
    # 在input的第三个维度上扩充维度1
    y = torch.unsqueeze(x, dim=2)
    print(y.shape)
    >>> torch.Size([2, 2, 1, 2])
    

    torch.stack(sequence, dim=0)

    torch.stack()函数和torch.cat()有所不同,torch.stack()并不在已有的维度进行拼接,而是沿着新的维度进行拼接。

    我在使用torch.stack()产生了两个问题:
    1.怎么确定新的维度产生在哪里?
    2.指定了新维度后要怎么拼接?

    下面我以两个张量来说明,分别是A和B

    A = torch.arange(6.0).reshape(2,3)
    B = torch.linspace(0,10,6).reshape(2,3)
    
    A= tensor([[0., 1., 2.],
            [3., 4., 5.]])       
    B= tensor([[ 0.,  2.,  4.],
            [ 6.,  8., 10.]])       
    

    既然知道函数会为张量产生一个新维度,那么我们可以假设,令A和B维度升级,从(2,3)变为(1,2,3),即:

    A1= tensor([[[0., 1., 2.],
            [3., 4., 5.]]])       
    B1= tensor([[[ 0.,  2.,  4.],
            [ 6.,  8., 10.]]])       
    #A1、B1比A、B在最外层多了一组括号[]
    

    这样,接下里就很好解释了。
    参数dim表示相连维度在这3维里的索引,如用link表示连接维度:
    dim=0时,(link,#,#)
    dim=1时,(#,link,#)
    dim=2时,(#,#,link)
    link所在的维度是哪个,就把A1和B1对应维度里的元素逐个相连。

    下面我对每个维度都演示一遍

    dim=0
    F1 = torch.stack((A,B),dim=0)
    print('F1=',F1)
    print('F1的维度是',F1.shape)
    
    F1= tensor([[[ 0.,  1.,  2.],
             [ 3.,  4.,  5.]],
            [[ 0.,  2.,  4.],
             [ 6.,  8., 10.]]])
    F1的维度是 torch.Size([2, 2, 3])
    
    用上面的说法来理解,这相当于在A1和B1的第0维度里,每个元素依次相连,每对连接元素用[ ]包装。
    A1的第0维度里只有A一个元素
    B1的第0维度里只有B一个元素
    因此如上所示,F1的结果其实就是[A,B]
    
    dim=1
    F2 = torch.stack((A,B),dim=1)
    print('F2=',F2)
    print('F2的维度是',F2.shape)
    
    F2= tensor([[[ 0.,  1.,  2.],
             [ 0.,  2.,  4.]],
            [[ 3.,  4.,  5.],
             [ 6.,  8., 10.]]])
    F2的维度是 torch.Size([2, 2, 3])
    

    沿用上面的理解
    A1的第1维度里的两个元素:[0. 1, 2],[3, 4, 5]
    B1的第1维度里的两个元素:[0, 2, 4],[6, 8, 10]
    [0. 1, 2]和[0, 2, 4]相连,[ ]包起来
    [3, 4, 5]和[6, 8, 10]相连,[ ]包起来
    最后给以上两组用[ ]包起来

    dim=2
    F3 = torch.stack((A,B),dim=2)
    print('F3=',F3)
    print('F3的维度是',F3.shape)
    
    F3= tensor([[[ 0.,  0.],
             [ 1.,  2.],
             [ 2.,  4.]],
            [[ 3.,  6.],
             [ 4.,  8.],
             [ 5., 10.]]])
    F3的维度是 torch.Size([2, 3, 2])
    

    A1和B1的第2维度里每个元素依次相连,每对连接元素用[]包装
    A1第2维度里的元素:0,1,2,3,4,5
    B1第2维度里的元素:0,2,4,6,8,10
    两两相连后打包[0,0] [1,2] [2,4] [3,6] [4,8] [5,10]
    由于[0,1,2]和[0,2,4]的第1维度属性是0
    [3,4,5]和[6,8,10]的第1维度属性是1
    所以把第一维度属性是0的和是1的单独打包
    即[[0,0],[1,2],[2,4]]和[[3,6],[4,8],[5,10]]
    最后将以上两组一起[]包起来

    torch.t(input, out=None) → Tensor

    输入一个矩阵(2维张量),并转置0, 1维。 可以被视为函数transpose(input, 0, 1)的简写函数。

    参数:
    input (Tensor) – 输入张量
    out (Tensor, optional) – 结果张量

    >>> x = torch.randn(2, 3)
    >>> x
    
     0.4834  0.6907  1.3417
    -0.1300  0.5295  0.2321
    [torch.FloatTensor of size 2x3]
    
    >>> torch.t(x)
    
     0.4834 -0.1300
     0.6907  0.5295
     1.3417  0.2321
    [torch.FloatTensor of size 3x2]
    

    torch.transpose(input, dim0, dim1, out=None) → Tensor

    返回输入矩阵input的转置。交换维度dim0和dim1。 输出张量与输入张量共享内存,所以改变其中一个会导致另外一个也被修改。

    参数:
    input (Tensor) – 输入张量
    dim0 (int) – 转置的第一维
    dim1 (int) – 转置的第二维

    >>> x = torch.randn(2, 3)
    >>> x
    
     0.5983 -0.0341  2.4918
     1.5981 -0.5265 -0.8735
    [torch.FloatTensor of size 2x3]
    
    >>> torch.transpose(x, 0, 1)
    
     0.5983  1.5981
    -0.0341 -0.5265
     2.4918 -0.8735
    [torch.FloatTensor of size 3x2]
    

    torch.unbind(tensor, dim=0)[source]

    移除指定维后,返回一个元组,包含了沿着指定维切片后的各个切片

    参数:
    tensor (Tensor) – 输入张量
    dim (int) – 删除的维度

    此方法就是将我们的input从dim进行切片,并返回切片的结果,返回的结果里面没有dim这个维度。
    例如维度为0的时候,如下所示:

    >>> torch.unbind(torch.tensor([[1, 2, 3],
    >>>                            [4, 5, 6],
    >>>                            [7, 8, 9]]))
    (tensor([1, 2, 3]), tensor([4, 5, 6]), tensor([7, 8, 9]))
    

    相关文章

      网友评论

          本文标题:[PyTorch中文文档]-Package参考-torch-索引

          本文链接:https://www.haomeiwen.com/subject/azmuvltx.html