[PyTorch] 笔记01:张量及基本操作

源自 PyTorch 1.4教程

[PyTorch] 笔记01:张量及基本操作

Outline

  • 张量
    • 基础语法
    • Torch张量转化为NumPy数组
    • NumPy数组转化为Torch张量
    • arange,range,linspace
  • 基本操作
    • 运算
    • 重排
    • 部分数据选择
    • 扩张与拼接

1 张量

  • Tensor(张量)类似于NumPy的ndarray
  • ndarray 对象是用于存放同类型元素的多维数组。
    numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
  • 参数说明
    • ndmin 指定生成数组的最小维度
    • dtype 数组元素的数据类型,可选
    • order创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)

1.1 基础语法

  • 创建一个随机初始化矩阵
    import torch
    x=torch.rand(5,3)
    print(x)

输出

    tensor([[0.3277, 0.8547, 0.0091],
            [0.2796, 0.6905, 0.9170],
            [0.8286, 0.8237, 0.4714],
            [0.6104, 0.1064, 0.5559],
            [0.2203, 0.8231, 0.2608]])
  • 直接构造张量
    import torch
    x = torch.tensor([5.5, 3])
    print(x)
    #获取张量的形状
    print(x.size())

输出

    tensor([5.5000, 3.0000])
    torch.Size([2])

torch.Size本质上是tuple元组,支持tuple的一切操作,元组一旦创建后不能被修改,起到保护数据的作用,可用于固定搭配的场景。

关于元组的操作可参见python元组操作详解

1.2 Torch张量转化为NumPy数组

对张量进行操作,转化的numpy数组也随之改变

    import torch
    a=torch.zeros(5)
    print(a)
    #torch转化成numpy
    b=a.numpy()
    print(b)
    print(a.add_(1))
    print(b)

输出

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

1.3 NumPy数组转化为Torch张量

    import numpy as np
    import torch
    a=np.zeros(5)
    print(a)
    b=torch.from_numpy(a)
    print(b)
    np.add(a,1,out=a)
    print(a)
    print(b)

输出

    [0. 0. 0. 0. 0.]
    tensor([0., 0., 0., 0., 0.], dtype=torch.float64)
    [1. 1. 1. 1. 1.]
    tensor([1., 1., 1., 1., 1.], dtype=torch.float64)

numpy中原位操作加法add即可,torch中add_

1.4 arange,range,linspace

  • torch.arange(start, end, step)
    • 返回一个以start为首项, 以end为尾项,以step为公差的等差数列。不包含end。
    print(torch.arange(1,13,2))
    #输出
    tensor([ 1,  3,  5,  7,  9, 11])
  • torch.range(start, end, step)
    • 返回一个以start为首项, 以end为尾项,以step为公差的等差数列。但是包含end。
    print(torch.range(1,13,2))
    #输出
    tensor([ 1.,  3.,  5.,  7.,  9., 11., 13.])
  • torch.linspace(start, end, steps)
    • 返回一个以start为首项, 以end为尾项,以step为公差的等差数列。(包含start和end)
    print(torch.range(1,16,5))
    #输出
    tensor([ 1.,  6., 11., 16.])
      

2 基本操作

2.1 运算

    import torch
    x=torch.rand(3,2)
    y=torch.rand(3,2)
    #直接输出
    print(x+y)
    print(torch.add(x,y))
    #在原变量y上操作,y改变
    print(y.add_(x))
    print(y)
    #支持索引操作,取第二列
    print(y[:,1])
    print(y.size())
    #改变形状
    z=y.view(6)
    print(z.size())
    ```
    输出
    ```
    tensor([[1.4144, 0.6279],
            [1.3059, 1.0928],
            [0.2199, 1.0268]])
    tensor([[1.4144, 0.6279],
            [1.3059, 1.0928],
            [0.2199, 1.0268]])
    tensor([[1.4144, 0.6279],
            [1.3059, 1.0928],
            [0.2199, 1.0268]])
    tensor([[1.4144, 0.6279],
            [1.3059, 1.0928],
            [0.2199, 1.0268]])
    tensor([0.6279, 1.0928, 1.0268])
    torch.Size([3, 2])
    torch.Size([6])

2.2 重排

  • tensor.reshape(r, c, k)
    • 将张量tensor各个维度的大小改变为(r, c, k)
    x = torch.Tensor([[1], [2], [3]])
    print(x.size())
    y=x.reshape(1,3)  #原地操作 x.reshape(1,3) 输出x.size 还是torch.Size([3, 1])
    print(y.size())
    print(y)

    #输出
    torch.Size([3, 1])
    torch.Size([1, 3])  #二维
    tensor([[1., 2., 3.]]) 
  • tensor.squeeze()
    • 表示将张量tensor中大小为1的维度去掉
    x = torch.Tensor([[1], [2], [3]])
    print(x.size())
    y=x.squeeze()
    print(y.size())
    print(y)

    #输出
    torch.Size([3, 1])
    torch.Size([3])
    tensor([1., 2., 3.]) #一维
  • tensor.unsqueeze(dim)
    • 表示在张量tensor指定的维度dim上增加一个大小为1的维度
    #x为二维,unsqueeze里面的范围取值只能是0-2,包含2
    #即x为n维,取值范围为0-n
    x = torch.Tensor([[1], [2], [3]])
    print(x.size())
    y=x.unsqueeze(0)
    print(y.size())
    print(y)
    z=x.unsqueeze(2)
    print(z.size())
    print(z)

    #输出
    torch.Size([3, 1])
    torch.Size([1, 3, 1])
    tensor([[[1.],
             [2.],
             [3.]]])
    torch.Size([3, 1, 1])
    tensor([[[1.]],

            [[2.]],

            [[3.]]])

  • tensor.permute(2, 0, 1,3)
    • 表示对张量tensor的维度进行重新排列
    #x为三维,permute里面的三个数只能是0,1,2,且不能重复
    #即x为n维,取值范围为0-n,不包括n
    x = torch.Tensor([[[1,4], [2,5], [3,6]]])
    print(x.size())
    y=x.permute(2,0,1)
    print(y.size())
    print(y)

    #输出
    torch.Size([1, 3, 2])
    torch.Size([2, 1, 3])
    tensor([[[1., 2., 3.]],

            [[4., 5., 6.]]])
  • tensor.transpose(0, 2)
    • 表示将张量tensor指定的两个维度0 和 2 进行互换
    x = torch.Tensor([[[1,4], [2,5], [3,6]]])
    print(x.size())
    y=x.transpose(1,2)
    print(y.size())
    print(y)

    #输出
    torch.Size([1, 3, 2])
    torch.Size([1, 2, 3])
    tensor([[[1., 2., 3.],
             [4., 5., 6.]]])

2.3 数据选择

  • tensor.index_select(1, torch.tensor[1, 4, 5])
    • 表示将张量tensor第二个维度,索引为1,4,5的数据挑选出来,其余数据丢掉
    x = torch.Tensor([[[1,4], [2,5], [3,6]]])
    print(x.size())
    y=x.index_select(1,torch.tensor([1,2]))
    print(y.size())
    print(y)
    a = torch.linspace(1, 12, steps=12).view(3, 4)
    print(a)
    b = torch.index_select(a, 0, torch.tensor([0, 2]))
    print(b)

    #输出
    torch.Size([1, 3, 2])
    torch.Size([1, 2, 2])
    tensor([[[2., 5.],
             [3., 6.]]])
    tensor([[ 1.,  2.,  3.,  4.],
            [ 5.,  6.,  7.,  8.],
            [ 9., 10., 11., 12.]])
    tensor([[ 1.,  2.,  3.,  4.],
            [ 9., 10., 11., 12.]])
  • tensor.masked_select(x,x>0)
    • 选择x张量中大于0的元素输出,x>0这个条件可变
  x=torch.randn(3,4)
  print(x)
  print(torch.masked_select(x,x>0))
  
  #输出
  

2.4扩张与拼接

  • tensor.repeat(x, y, z)
    • 表示将张量tensor在三个维度上分别重复x, y, z次, 重复之后只是各个维度元素的数量增加了,原张量的维度并没有改变,若是复制给另一个张量维度改变
    x = torch.Tensor([[[1,4], [2,5], [3,6]]])
    print(x.repeat(1,2,3))
    print(x.size())
    
    #输出
    tensor([[[1., 4., 1., 4., 1., 4.],
         [2., 5., 2., 5., 2., 5.],
         [3., 6., 3., 6., 3., 6.],
         [1., 4., 1., 4., 1., 4.],
         [2., 5., 2., 5., 2., 5.],
         [3., 6., 3., 6., 3., 6.]]])
    torch.Size([1, 3, 2])
  • torch.cat([t1, t2], k)
    • 表示将张量t1和t2在维度k上进行拼接,注意:拼接完后张量的维度并没有变化。
    x = torch.Tensor([[1,4], [2,5], [3,6]])
    y=torch.Tensor([[1,1,0],[0,0,1],[1,1,1]])
    z=torch.cat([x,y],1)
    print(z)
    
    #输出
    tensor([[1., 4., 1., 1., 0.],
        [2., 5., 0., 0., 1.],
        [3., 6., 1., 1., 1.]])

注意在1维度拼接要保证两个张量在0维度相同

  • torch.stack([t1, t2], k)
    • 表示将张量t1和t2在维度k上进行拼接,拼接之后维度会增加1。 这种方式要求被拼接的张量t1, t2必须大小形状相同,增加的维度的大小等于拼接的张量的个数。
    • 假设t1的维度为n,k的取值范围是0-n,包括n
    x = torch.Tensor([[1,4], [2,5], [3,6]])
    y=torch.Tensor([[1,1],[0,0],[1,1]])
    z=torch.stack([x,y],2)
    print(z)
    print(z.size())
    
    #输出
    tensor([[[1., 1.],
         [4., 1.]],

        [[2., 0.],
         [5., 0.]],

        [[3., 1.],
         [6., 1.]]])
    torch.Size([3, 2, 2]) 
  • tensor.expand(x, y, z …)
    • 表示将张量tensor进行扩张,若张量是n,1,扩张n,m,最后变为n,m
    • 若张量是n,m(m不为1),扩张只能是n,m
    x = torch.Tensor([[1], [2], [3]])
    print(x.expand(3,5))

    #输出
    tensor([[1., 1., 1., 1., 1.],
            [2., 2., 2., 2., 2.],
            [3., 3., 3., 3., 3.]])
  • torch.Tensor scatter_(dim, index, src) → Tensor分散操作
    • 将张量src中的各个元素,按照index张量中指定的索引位置,写入到张量Tensor中。此函数中index张量的大小一般大于或等于src张量
    input = torch.randn(2, 4)
    print(input)
    output = torch.zeros(2, 4)
    index = torch.tensor([[3, 1, 2, 0], [1, 2, 0, 3]])
    print(index)
    #input数组中的数据只是在第1维上进行重新分配,第0维不变
    output = output.scatter(1, index, input)
    print(output)

    #input[1][0]->output[1][index[1][0]]->output[1][1]
    #input[1][1]->output[1][index[1][1]]->outpou[1][2]

    #输出
    tensor([[ 0.6964,  0.0709,  2.2572, -0.4595],
            [-0.8429, -1.5339,  2.0352,  1.2176]])
    tensor([[3, 1, 2, 0],
            [1, 2, 0, 3]])
    tensor([[-0.4595,  0.0709,  2.2572,  0.6964],
            [ 2.0352, -0.8429, -1.5339,  1.2176]])

参见pytorch中torch.Tensor.scatter用法

下节写Autograd 自动求导

欢迎批评指正,一起学习进步!!!

猜你喜欢

转载自blog.csdn.net/qq_38939991/article/details/108367661