Pytorch系列 1.张量基础知识

  • 1.线性代数引入:在线性代数中,常见的基本数学单元是:行列式、向量、矩阵。
    • 行列式:实质是指一个实数,它实际上是一种计算手段;
    • 向量:从表示形式上看有行向量和列向量两种(可以通过转置相互转换),简单点可以理解为一组数的有序排列(类似于各种编程语言中的列表,不过在这个列表中只能存放数字)。
    • 矩阵:是指一个按照长方形阵列排列的实数或虚数集合。可以理解为是一张表格。
  • 2.张量:在计算机中,只有线性代数中的行列式,向量,矩阵是不够的,因为实际情况中我们会遇到超过维度数为2的数学单元,所以引入张量;个人理解:张量就是一个名字,但他可以表示从0维到n维的数学数据。
    • 0维张量:就是标量,在深度学习分类任务中,可用表示类别
    • 1维张量:也就是向量,可抽象的表示一个数据,向量中的每一个元素就是这个数据抽象出来的特征。
    • 2维张量:矩阵,可以用来表示黑白图像或者灰度图像。
    • 3维张量:可以用来表示单张彩色图片,在二维张量上扩张了通道这一维度(注意:通道数不一定是3,例如在遥感图像中可能有更多的维度);虽然3维张量也可以表示一个批次的灰度图像,但在实际的应用中,我们经常将一个批次的灰度图像也用一个批次的彩色图像表示,不过在通道数上是1而不是3.
      • (width, height, channel) = 3D;
    • 4维张量:可以理解为单个的视频,亦或者是一个批次的3维张量。
      • (batch_size, width, height, channel) = 4D
  • 3.tensor基本操作:
    • 1)创建:
      • a.随机初始化:
        • torch.rand()方法
          import torch
          
          a = torch.rand(5, 6, 3)   # 创建一个5通道,6行,3列的张量
          print(a)        # 打印a
          print(a.shape)  # 或print(a.size())

          输出:其打印的tensor中的每一个值都是从区间[0, 1]的均匀分布中抽取的随机数

          tensor([[[0.2512, 0.0754, 0.5254],
                   [0.7569, 0.5339, 0.1608],
                   [0.7013, 0.6424, 0.5533],
                   [0.3275, 0.2094, 0.8940],
                   [0.0358, 0.6873, 0.3650],
                   [0.1200, 0.9824, 0.9345]],
          
                  [[0.5813, 0.3151, 0.3075],
                   [0.5461, 0.9380, 0.4024],
                   [0.4387, 0.1736, 0.6139],
                   [0.5841, 0.1288, 0.6711],
                   [0.0482, 0.6064, 0.3039],
                   [0.6604, 0.1150, 0.8711]],
          
                  [[0.4828, 0.6829, 0.2325],
                   [0.3047, 0.3977, 0.6882],
                   [0.5027, 0.0049, 0.3798],
                   [0.8563, 0.4973, 0.6633],
                   [0.8528, 0.3553, 0.9099],
                   [0.3714, 0.1334, 0.8464]],
          
                  [[0.8258, 0.4027, 0.1122],
                   [0.0456, 0.1765, 0.1347],
                   [0.4605, 0.1179, 0.3105],
                   [0.7372, 0.0663, 0.2409],
                   [0.1751, 0.2907, 0.9303],
                   [0.6384, 0.1184, 0.7696]],
          
                  [[0.7160, 0.2935, 0.2707],
                   [0.0643, 0.4972, 0.0936],
                   [0.3103, 0.7884, 0.0406],
                   [0.1640, 0.5265, 0.9636],
                   [0.8147, 0.0701, 0.1994],
                   [0.5739, 0.4212, 0.7736]]])
          torch.Size([5, 6, 3])
        • torch.randn()方法
          import torch
          
          b = torch.randn(6, 3)
          print(b)
          print(b.shape)  # 或print(b.size())

          输出:其打印的tensor中的每一个数值都服从标准正态分布。

          tensor([[-0.5691, -0.1960,  0.0624],
                  [ 0.3880, -0.5484,  0.0718],
                  [-0.1414, -0.4525, -0.1813],
                  [ 3.0790,  0.8768, -2.5193],
                  [ 1.2124,  0.6179, -1.0690],
                  [ 0.7950, -0.1661,  0.4205]])
          torch.Size([6, 3])
      • b.全零矩阵构建:torch.zeros()方法:
        import torch
        
        c = torch.zeros(5, 5, dtype=torch.float32)  # dtype是指tensor中数值的类型
        print(c)
        print(c.shape)  # 或print(c.size())

        输出:

        tensor([[0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.]])
        torch.Size([5, 5])
      • dtype说明:pytorch中一共有8种不同的数据类型
        Data typedtypeTensor types
        32-bit floating pointtorch.float32 or torch.floattorch.*.FloatTensor
        64-bit floating pointtorch.float64 or torch.doubletorch.*.DoubleTensor
        16-bit floating pointtorch.float16 or torch.halftorch.*.HalfTensor
        8-bit integer (unsigned)torch.uint8torch.*.ByteTensor
        8-bit integer (signed)torch.int8torch.*.CharTensor
        16-bit integer (signed)torch.int16 or torch.shorttorch.*.ShortTensor
        32-bit integer (signed)torch.int32 or torch.inttorch.*.IntTensor
        64-bit integer (signed)torch.int64 or torch.longtorch.*.LongTensor
      • c.全一矩阵构建:torch.ones()方法:
        import torch
        
        a = torch.ones(3, 2)
        print(a)
        print(a.shape)  # 或print(a.size())

        输出:

        tensor([[1., 1.],
                [1., 1.],
                [1., 1.]])
        torch.Size([3, 2])
      • d.单位矩阵构建:torch.eye()方法:
        import torch
        
        a = torch.eye(3, 3)
        print(a)
        print(a.shape)  # 或print(a.size())

        输出:

        tensor([[1., 0., 0.],
                [0., 1., 0.],
                [0., 0., 1.]])
        torch.Size([3, 3])

        注意:该方法并未要求张量形状一定为方阵,如:

        import torch
        
        a = torch.eye(3, 5)
        print(a)
        print(a.shape)  # 或print(a.size())

        输出则为:

        tensor([[1., 0., 0., 0., 0.],
                [0., 1., 0., 0., 0.],
                [0., 0., 1., 0., 0.]])
        torch.Size([3, 5])
      • e.正态分布矩阵:torch.normal(mean, std)方法(均值为mean,标准差为std):
        import torch
        
        a = torch.normal(mean=0, std=1, size=(3, 3))
        print(a)
        print(a.shape)  # 或print(a.size())

        输出:

        tensor([[ 1.7324, -0.9390,  0.7721],
                [ 0.0488,  1.0510,  0.7274],
                [ 0.5267,  0.1345, -1.1278]])
        torch.Size([3, 3])
      • f.创建同型的矩阵:基于一个已经存在的张量数据,创建一个和他形状相同的张量数据;方法:_like(已有张量)
        import torch
        
        a = torch.ones(size=(5, 5))
        print(f"a:{a}")
        print(f"a的形状:{a.shape}")
        
        b = torch.zeros_like(a)
        print(f"b:{b}")
        print(f"b的形状:{b.shape}")

        输出:

        a: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.]])
        a的形状:torch.Size([5, 5])
        b:tensor([[0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.]])
        b的形状:torch.Size([5, 5])
      • g.有序排列矩阵创建:torch.arange(s,e,step)方法:
        import torch
        
        a = torch.arange(start=0, end=10, step=1)
        print(f"a:{a}")
        print(f"a的形状:{a.shape}")

        输出:

        a:tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        a的形状:torch.Size([10])

        注意:该方法中生成张量并不包含最后结束的数值。如果要改变张量的形状,可以用resize()方法或者reshape()方法,如:

        import torch
        
        a = torch.arange(start=0, end=10, step=1)
        print(f"a:{a}")
        print(f"a的形状:{a.shape}")
        
        b = a.resize(2, 5)
        print(f"b:{b}")
        print(f"b的形状:{b.shape}")
        
        c = a.reshape(5, 2)
        print(f"c:{c}")
        print(f"c的形状:{c.shape}")

        输出:

        a:tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
        a的形状:torch.Size([10])
        b:tensor([[0, 1, 2, 3, 4],
                [5, 6, 7, 8, 9]])
        b的形状:torch.Size([2, 5])
        c:tensor([[0, 1],
                [2, 3],
                [4, 5],
                [6, 7],
                [8, 9]])
        c的形状:torch.Size([5, 2])
    • 2)基本操作:
      • 加减乘除:太简单了,小学数学水平,最多考虑一下数据的类型,此处不再赘述。
      • 索引:此处参考numpy,注意:索引出来的结果是原数据本身,修改索引出来的值就是修改原数据;当然,可以换一种思路,将原数据进行拷贝,方法:clone()
        import torch
        
        a = torch.arange(start=0, end=10, step=1).reshape(2, 5)
        print(f"a:{a}")
        print(f"a的形状:{a.shape}")
        
        b = a[:, 2:4]
        print(f"b:{b}")
        print(f"b的形状:{b.shape}")
        
        b[1][1] = 0
        print(f"b:{b}")
        print(f"a:{a}")

        输出:

        a:tensor([[0, 1, 2, 3, 4],
                [5, 6, 7, 8, 9]])
        a的形状:torch.Size([2, 5])
        b:tensor([[2, 3],
                [7, 8]])
        b的形状:torch.Size([2, 2])
        b:tensor([[2, 3],
                [7, 0]])
        a:tensor([[0, 1, 2, 3, 4],
                [5, 6, 7, 0, 9]])
        
        

        clone()方法:

        import torch
        
        a = torch.arange(start=0, end=10, step=1).reshape(2, 5)
        print(f"a:{a}")
        print(f"a的形状:{a.shape}")
        
        b = a[:, 2:4]
        c = b.clone()
        print(f"c:{c}")
        print(f"c的形状:{c.shape}")
        
        c[1][1] = 0
        print(f"c:{c}")
        print(f"a:{a}")

        输出:

        a:tensor([[0, 1, 2, 3, 4],
                [5, 6, 7, 8, 9]])
        a的形状:torch.Size([2, 5])
        c:tensor([[2, 3],
                [7, 8]])
        c的形状:torch.Size([2, 2])
        c:tensor([[2, 3],
                [7, 0]])
        a:tensor([[0, 1, 2, 3, 4],
                [5, 6, 7, 8, 9]])
        
      • 维度变换:
        • reshape()方法:注意:此方法共享内存
          import torch
          
          a = torch.arange(start=0, end=10, step=1)
          print(f"a:{a}")
          print(f"a的形状:{a.shape}")
          
          b = a.reshape(5, 2)
          b[1][1] = 9
          print(f"b:{b}")
          print(f"b的形状:{b.shape}")
          print(f"a:{a}")
          print(f"a的形状:{a.shape}")

          输出:

          a:tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
          a的形状:torch.Size([10])
          b:tensor([[0, 1],
                  [2, 9],
                  [4, 5],
                  [6, 7],
                  [8, 9]])
          b的形状:torch.Size([5, 2])
          a:tensor([0, 1, 2, 9, 4, 5, 6, 7, 8, 9])
          a的形状:torch.Size([10])
          
        • view()方法:注意,此方法共享内存
          import torch
          
          a = torch.arange(start=0, end=10, step=1).reshape(2, 5)
          print(f"a:{a}")
          print(f"a的形状:{a.shape}")
          
          b = a.view(5, 2)
          b[1][1] = 9
          print(f"b:{b}")
          print(f"b的形状:{b.shape}")
          print(f"a:{a}")
          print(f"a的形状:{a.shape}")

          输出:

          a:tensor([[0, 1, 2, 3, 4],
                  [5, 6, 7, 8, 9]])
          a的形状:torch.Size([2, 5])
          b:tensor([[0, 1],
                  [2, 9],
                  [4, 5],
                  [6, 7],
                  [8, 9]])
          b的形状:torch.Size([5, 2])
          a:tensor([[0, 1, 2, 9, 4],
                  [5, 6, 7, 8, 9]])
          a的形状:torch.Size([2, 5])
          

          若要不改变原数据,可以将原数据先clone()再进行相应维度转换。

      • 广播机制:抱歉,强迫症犯了,虽然大概理解这个方法的具体操作,但基于数学的严谨性,我一般不用这个(个人建议初学者一般也不要用这个,有坑),有需求的请看吴恩达老师的机器学习的相关课程,里面有详细的讲解。
  • 4.pytorch中的自动求导
    • 1)深度学习模型在训练过程中,需要构建计算图(实际上就是各变量之间的函数关系),计算图的最后输出是一个损失函数的标量值,从标量值反推计算图权重张量的梯度,这个过程被称为自动求导。
    • 2)神经网络的核心是autograd包,它为张量上的所有操作提供了自动求导机制,支持对任意计算图的自动梯度计算。可以在创建tensor时设置requires_grad = True来支持梯度计算,或者后续使用.requires_grad_(True)来设置。
    • 3)例子:创建一个简单的计算图:Y = WX+b
      • 其中:输入:X,输出:Y,理想输出结果:Z
      • 代码:
        import torch
        
        x = torch.arange(0, 5, dtype=torch.float32)
        z = torch.ones(3, dtype=torch.float32)
        w = torch.randn(5, 3, requires_grad=True)    # 使用requires_grad=True来追踪计算历史
        b = torch.randn(3, requires_grad=True)
        y = torch.matmul(x, w)+b  # x 和 w 矩阵相乘,再加上 bias b
        loss = torch.nn.functional.binary_cross_entropy_with_logits(y, z)
        print('Gradient function for y =', y.grad_fn)  # 若上面未设置requires_grad=True,此处会报错
        print('Gradient function for loss =', loss.grad_fn)
        loss.backward()
        print(w.grad)
        print(b.grad)

        输出:

        Gradient function for y = <AddBackward0 object at 0x0000027E40BBFFC8>
        Gradient function for loss = <BinaryCrossEntropyWithLogitsBackward0 object at 0x0000027E40BBFFC8>
        tensor([[-0.0000, -0.0000, -0.0000],
                [-0.0058, -0.0826, -0.3307],
                [-0.0116, -0.1653, -0.6614],
                [-0.0173, -0.2479, -0.9922],
                [-0.0231, -0.3305, -1.3229]])
        tensor([-0.0058, -0.0826, -0.3307])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值