当前位置: 首页 > news >正文

pytorch的基本运算,是不是共享了内存,有没有维度变化

  • 可以把PyTorch简单看成是Python的深度学习第三方库,在PyTorch中定义了适用于深度学习的基本数据结构——张量,以及张量的各类计算。其实也就相当于NumPy中定义的Array和对应的科学计算方法,正是这些基本数据类型和对应的方法函数,为我们进一步在PyTorch上进行深度学习建模提供了基本对象和基本工具。因此,在正式使用PyTorch进行深度学习建模之前,我们需要熟练掌握PyTorch中张量的基本操作方法。张量作为数组的衍生概念,其本身的定义和使用方法和NumPy中的Array非常类似,甚至,在复现一些简单的神经网络算法场景中,我们可以直接使用NumPy中的Array来进行操作。

  • 张量的最基本创建方法和NumPy中创建Array的格式一致,都是创建函数(序列)的格式:张量创建函数:torch.tensor()

    • t = torch.tensor([[0,1], [2,3]]) # 通过列表创建张量
      # 通过元组创建张量
      # torch.tensor((1, 2))
      # 通过数组创建张量
      # a = np.array((1, 2))
      # t = torch.tensor(a)
      # 整数型的数组默认创建int32(整型)类型,而张量则默认创建int64(长整型)类型。
      # 创建浮点型数组时,张量默认是float32(单精度浮点型),而Array则是默认float64(双精度浮点型)。
      print(t,t.data)
      print(id(t),id(t.data))
      ## 输出 ##
      tensor([[0, 1],[2, 3]]) tensor([[0, 1],[2, 3]])
      2036011697072 2036018540848
      
    • 两者返回不同的id,但是共享同一个内存

    • t[0][0]=10
      t.data[1][0]=20
      print(t,t.data)
      print(id(t),id(t.data))
      ## 输出 ##
      tensor([[10,  1],[20,  3]]) tensor([[10,  1],[20,  3]])
      2036011697072 2036019332576
      
    • 属性 grad(导数), grad-fn(张量所在的导数函数), requires_grad(是否执行可导的判定)。调用backward计算导数,导数是累加的,如果每次单独计算,需要清空梯度 optimiter.zero_grad()

    • 属性 is_leaf, retain_grad。判定该元素在计算图中是否为叶子节点,当为叶子节点时,它的属性requires_grad为False。当requires_grad为True,但是用户构建的Tensor,表示该张量不是计算结果,而是用户构建的初始化张量。在用backward后,仅只有 leaf tensor 才会有 grad 属性。如果不是 leaf tensor 需要retain_grad 函数开启grad。

    • 属性ndim和dim函数,查看tensor的维度;属性shape和size(),tensor的形状

    • t=torch.cat([t,t],0)
      print(t.ndim,len(t),t.dim())
      print(t.shape,t.size())
      ## 输出 ##
      2 8 2
      torch.Size([8, 2]) torch.Size([8, 2])
      
    • 和数组不同,对于张量而言,数值型和布尔型张量就是最常用的两种张量类型,相关类型总结如下。

      • 数据类型dtype
        32bit浮点数torch.float32或torch.float
        64bit浮点数torch.float64或torch.double
        16bit浮点数torch.float16或torch.half
        8bit无符号整数torch.unit8
        8bit有符号整数torch.int8
        16bit有符号整数torch.int16或torch.short
        32bit有符号整数torch.int32或torch.int
        64bit有符号整数torch.int64或torch.long
        布尔型torch.bool
        复数型torch.complex64
    • 创建int16整型张量; torch.tensor([1.1, 2.7], dtype = torch.int16)

    • 在PyTorch中也支持复数类型对象创建; a = torch.tensor(1 + 2j) # 1是实部、2是虚部; tensor(1.+2.j)

    • 和NumPy中array相同,当张量各元素属于不同类型时,系统会自动进行隐式转化。在使用方法进行类型转化时,方法名称则是double。(虽然torch.float和double都表示双精度浮点型。)

  • flatten拉平:将任意维度张量转化为一维张量,按行排列,拉平。注:如果将零维张量使用flatten,则会将其转化为一维张量。

  • reshape方法:任意变形;注意,reshape过程中维度的变化:reshape转化后的维度由该方法输入的参数“个数”决定。

  • 在很多数值科学计算的过程中,都会创建一些特殊取值的张量,用于模拟特殊取值的矩阵,如全0矩阵、对角矩阵等。因此,PyTorch中也存在很多创建特殊张量的函数。

    • torch.zeros([2, 3])            # 创建全是0的,两行、三列的张量(矩阵)
      torch.ones([2, 3]) # 注:由于zeros就已经确定了张量元素取值,因此该函数传入的参数实际上是决定了张量的形状
      
    • 单位矩阵

    • torch.eye(5)
      ## 
      tensor([[1., 0., 0., 0., 0.],[0., 1., 0., 0., 0.],[0., 0., 1., 0., 0.],[0., 0., 0., 1., 0.],[0., 0., 0., 0., 1.]])
      
    • 在PyTorch中,需要利用一维张量去创建对角矩阵。

    • t1 = torch.tensor([1, 2])
      torch.diag(t1) # 不能使用list直接创建对角矩阵,diag(): argument 'input' (position 1) must be Tensor, not list
      ## 
      tensor([[1, 0],[0, 2]])
      
    • rand:服从0-1均匀分布的张量

    • torch.randn(2, 3)
      torch.normal(2, 3, size = (2, 2))  # 均值为2,标准差为3的张量;normal:服从指定正态分布的张量
      torch.randint(1, 10, [2, 4]) # 在1-10之间随机抽取整数,组成两行四列的矩阵,randint:整数随机采样结果
      
    • arange/linspace:生成数列

    • torch.arange(5)  # 和range相同;tensor([0, 1, 2, 3, 4])
      torch.arange(1, 5, 0.5)  # 从1到5(左闭右开),每隔0.5取值一个
      torch.linspace(1, 5, 3)  # 从1到5(左右都包含),等距取三个数;tensor([1., 3., 5.])
      
    • empty:生成未初始化的指定形状矩阵

    • torch.empty(2, 3)
      ##
      tensor([[6.8664e-44, 6.8664e-44, 1.1771e-43],[6.7262e-44, 7.0065e-44, 8.1275e-44]])
      torch.full([2, 4], 2)   
      tensor([[2, 2, 2, 2],[2, 2, 2, 2]])
      
    • 还能根据指定对象的形状进行数值填充,只需要在上述函数后面加上_like即可。

    • torch.full_like(t1, 2)             # 根据t1形状,填充数值2
      torch.randint_like(t2, 1, 10) # 根据t1形状,填充数值1-10,不包括10的整数
      t1 = torch.tensor([1, 2])
      torch.randn_like(t1)  # t1是整数,而转化后将变为浮点数,此时代码将报错,"normal_kernel_cpu" not implemented for 'Long'
      
    • 张量、数组和列表是较为相似的三种类型对象,在实际操作过程中,经常会涉及三种对象的相互转化。在此前张量的创建过程中,我们看到torch.tensor函数可以直接将数组或者列表转化为张量,而我们也可以将张量转化为数组或者列表。

    • t1 = torch.tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
      t1.numpy() # array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10], dtype=int64)
      import numpy as np
      # 当然,也可以通过np.array函数直接转化为array
      np.array(t1) # array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10], dtype=int64)
      t1# tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
      # .tolist方法:张量转化为列表
      t1.tolist() # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      
    • list函数:张量转化为列表

    • [tensor(1),tensor(2),tensor(3),tensor(4),tensor(5),tensor(6),tensor(7),tensor(8),tensor(9),tensor(10)] # 需要注意的是,此时转化的列表是由一个个零维张量构成的列表,而非张量的数值组成的列表。
      
    • 在很多情况下,我们需要将最终计算的结果张量转化为单独的数值进行输出,此时需要使用.item()方法来执行。

    • Python中其他对象类型一样,等号赋值操作实际上是浅拷贝,需要进行深拷贝,则需要使用clone方法

  • 张量作为有序的序列,也是具备数值索引的功能,并且基本索引方法和Python原生的列表、NumPy中的数组基本一致,当然,所有不同的是,PyTorch中还定义了一种采用函数来进行索引的方式。张量也是有序序列,我们可以根据每个元素在系统内的顺序“编号”,来找出特定的元素,也就是索引。张量索引出来的结果还是零维张量, 而不是单独的数。要转化成单独的数,需要使用item()方法。在张量的索引中,step位必须大于0

  • 二维张量的索引逻辑和一维张量的索引逻辑基本相同,二维张量可以视为两个一维张量组合而成,而在实际的索引过程中,需要用逗号进行分隔,分别表示对哪个一维张量进行索引、以及具体的一维张量的索引。对二维张量来说,基本可以视为是对矩阵的索引,并且行、列的索引遵照相同的索引规范,并用逗号进行分隔

    • import torch
      t2 = torch.arange(1, 10).reshape(3, 3)
      t2
      t2[0, 1]   # 表示索引第一行、第二个(第二列的)元素 tensor(2)
      t2[0][1]# 表示索引第一行、第二个(第二列的)元素 tensor(2)
      t2[0, ::2]# 表示索引第一行、每隔两个元素取一个 tensor([1, 3])
      t2[0, [0, 2]] # 索引结果同上
      t2[::2, ::2] # 表示每隔两行取一行、并且每一行中每隔两个元素取一个
      tensor([[1, 3],[7, 9]])
      
  • 在二维张量索引的基础上,三维张量拥有三个索引的维度。我们将三维张量视作矩阵组成的序列,则在实际索引过程中拥有三个维度,分别是索引矩阵、索引矩阵的行、索引矩阵的列

    • t3 = torch.arange(1, 28).reshape(3, 3, 3)
      t3
      ##
      tensor([[[ 1,  2,  3],[ 4,  5,  6],[ 7,  8,  9]],[[10, 11, 12],[13, 14, 15],[16, 17, 18]],[[19, 20, 21],[22, 23, 24],[25, 26, 27]]])
      t3[1, ::2, ::2]      # 索引第二个矩阵,行和列都是每隔两个取一个
      tensor([[10, 12],[16, 18]])
      t3[:: 2, :: 2, :: 2]      # 每隔两个取一个矩阵,对于每个矩阵来说,行和列都是每隔两个取一个
      tensor([[[ 1,  3],[ 7,  9]],[[19, 21],[25, 27]]])
      
  • 在PyTorch中,我们还可以使用index_select函数,通过指定index来对张量进行索引。在index_select函数中,第二个参数实际上代表的是索引的维度。对于t1这个一维向量来说,由于只有一个维度,因此第二个参数取值为0,就代表在第一个维度上进行索引。

    • t1 = torch.arange(10) 
      indices = torch.tensor([1, 2]) # 需要tensor
      torch.index_select(t1, 0, indices)
      ## tensor([1, 2])
      t2 = torch.arange(12).reshape(4, 3)
      ##
      tensor([[ 0,  1,  2],[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]])
      torch.index_select(t2, 0, indices)   
      ##
      tensor([[3, 4, 5],[6, 7, 8]])
      
  • 在正式介绍张量的切分方法之前,需要首先介绍PyTorch中的.view()方法。该方法会返回一个类似视图的结果,该结果和原张量对象共享一块数据存储空间,并且通过.view()方法,还可以改变对象结构,生成一个不同结构,但共享一个存储空间的张量。当然,共享一个存储空间,也就代表二者是“浅拷贝”的关系,修改其中一个,另一个也会同步进行更改。“视图”的作用就是节省空间,而值得注意的是,在接下来介绍的很多切分张量的方法中,返回结果都是“视图”,而不是新生成一个对象

  • chunk函数能够按照某维度,对张量进行均匀切分,并且返回结果是原张量的视图。

    • t2 = torch.arange(12).reshape(4, 3)
      tc = torch.chunk(t2, 4, dim=0)           # 在第零个维度上(按行),进行四等分
      ##  返回类型是元组
      (tensor([[0, 1, 2]]),tensor([[3, 4, 5]]),tensor([[6, 7, 8]]),tensor([[ 9, 10, 11]]))# chunk返回结果是一个视图,不是新生成了一个对象# 修改tc中的值,原张量也会对应发生变化
      
    • 当原张量不能均分时,chunk不会报错,但会返回其他均分的结果

    • torch.chunk(t2, 3, dim=0)            # 次一级均分结果
      ## 
      (tensor([[0, 1, 2],[3, 4, 5]]),tensor([[ 6,  7,  8],[ 9, 10, 11]]))
      
  • split既能进行均分,也能进行自定义切分。当然,需要注意的是,和chunk函数一样,split返回结果也是view

    • t2 = torch.arange(12).reshape(4, 3)
      torch.split(t2, 2, 0) # 第二个参数只输入一个数值时表示均分,第三个参数表示切分的维度
      torch.split(t2, [1, 3], 0)# 第二个参数输入一个序列时,表示按照序列数值进行切分,也就是1/3分
      ## 
      (tensor([[0, 1, 2]]),tensor([[ 3,  4,  5],[ 6,  7,  8],[ 9, 10, 11]]))
      torch.split(t2, [1, 1, 2], 0) 
      ##
      (tensor([[0, 1, 2]]),tensor([[3, 4, 5]]),tensor([[ 6,  7,  8],[ 9, 10, 11]]))
      
    • 注意,当第二个参数位输入一个序列时,序列的各数值的和必须等于对应维度下形状分量的取值。例如,上述代码中,是按照第一个维度进行切分,而t2总共有4行,因此序列的求和必须等于4,也就是1+3=4,而序列中每个分量的取值,则代表切块大小。tensor的split方法和array的split方法有很大的区别,array的split方法是根据索引进行切分。

    • import numpy as np
      x = np.array([0,1,2,3,4,5,6,7,8])
      print (np.split(x,[3,5,6,9]))
      ## [array([0, 1, 2]), array([3, 4]), array([5]), array([6, 7, 8]), array([], dtype=int32)]
      
  • 张量的合并操作类似与列表的追加元素,可以拼接、也可以堆叠。PyTorch中,可以使用cat函数实现张量的拼接。

    • a = torch.zeros(2, 3)
      b = torch.ones(2, 3)
      c = torch.full((3, 3),2)
      torch.cat([a, b])    # 按照行进行拼接,dim默认取值为0
      ##
      tensor([[0., 0., 0.],[0., 0., 0.],[1., 1., 1.],[1., 1., 1.]])
      torch.cat([a, b], 1)               # 按照列进行拼接
      tensor([[0., 0., 0., 1., 1., 1.],[0., 0., 0., 1., 1., 1.]])
      torch.cat([a, c], 1)               # 形状不匹配时将报错
      # Sizes of tensors must match except in dimension 1. Expected size 2 but got size 3 for tensor number 1 in the list.
      
    • 拼接的本质是实现元素的堆积,也就是构成a、b两个二维张量的各一维张量的堆积,最终还是构成二维向量。

  • 堆叠函数:stack;和拼接不同,堆叠不是将元素拆分重装,而是简单的将各参与堆叠的对象分装到一个更高维度的张量里。

    • torch.stack([a, b])                 # 堆叠之后,生成一个三维张量
      tensor([[[0., 0., 0.],[0., 0., 0.]],[[1., 1., 1.],[1., 1., 1.]]])
      torch.stack([a, b]).shape # torch.Size([2, 2, 3])
      torch.stack([a, c])               # 维度不匹配时也会报错
      # stack expects each tensor to be equal size, but got [2, 3] at entry 0 and [3, 3] at entry 1
      
  • 通过reshape方法,能够灵活调整张量的形状。而在实际操作张量进行计算时,往往需要另外进行降维和升维的操作,当我们需要除去不必要的维度时,可以使用squeeze函数,而需要手动升维时,则可采用unsqueeze函数

    • t = torch.zeros(1, 1, 3, 1) #t张量解释:一个包含一个三维的四维张量,三维张量只包含一个三行一列的二维张量。
      ##
      tensor([[[[0.],[0.],[0.]]]])
      torch.squeeze(t) # tensor([0., 0., 0.])
      torch.squeeze(t).shape # torch.Size([3])
      t1 = torch.zeros(1, 1, 3, 2, 1, 2)
      ##
      tensor([[[0., 0.],[0., 0.]],[[0., 0.],[0., 0.]],[[0., 0.],[0., 0.]]])
      torch.squeeze(t1).shape # torch.Size([3, 2, 2])
      
    • 简单理解,squeeze就相当于提出了shape返回结果中的1。unsqeeze函数:手动升维

    • torch.unsqueeze(t, dim = 0)              # 在第1个维度索引上升高1个维度
      torch.unsqueeze(t, dim = 2).shape         # 在第3个维度索引上升高1个维度
      torch.unsqueeze(t, dim = 4).shape          # 在第5个维度索引上升高1个维度
      
    • 注意理解维度和shape返回结果一一对应的关系,shape返回的序列有几个元素,张量就有多少维度。

  • 作为PyTorch中执行深度学习的基本数据类型,张量(Tensor)也拥有非常多的数学运算函数和方法,以及对应的一系列计算规则。在PyTorch中,能够作用与Tensor的运算,被统一称作为算子。并且相比于NumPy,PyTorch给出了更加规范的算子(运算)的分类,从而方便用户在不同场景下调用不同类型的算子(运算)。PyToch总共为Tensor设计了六大类数学运算,分别是:

    • 逐点运算(Pointwise Ops):指的是针对Tensor中每个元素执行的相同运算操作;

    • 规约运算(Reduction Ops):指的是对于某一张量进行操作得出某种总结值;

    • 比较运算(Comparison Ops):指的是对多个张量进行比较运算的相关方法;

    • 谱运算(Spectral Ops):指的是涉及信号处理傅里叶变化的操作;

    • BLAS和LAPACK运算:指的是基础线性代数程序集(Basic Linear Algeria Subprograms)和线性代数包(Linear Algeria Package)中定义的、主要用于线性代数科学计算的函数和方法;

    • 其他运算(Other Ops):其他未被归类的数学运算。

    • t1 = torch.arange(3)
      t = t1+t1 # tensor([0, 2, 4])
      a=[2,3,4]+[1,2,3] # [2, 3, 4, 1, 2, 3]
      import numpy as np
      b=np.arange(3)+np.arange(3) # array([0, 2, 4])
      
    • 广播的特性是在不同形状的张量进行计算时,一个或多个张量通过隐式转化,转化成相同形状的两个张量,从而完成计算的特性。但并非任何两个不同形状的张量都可以通过广播特性进行计算,因此,我们需要了解广播的基本规则及其核心依据。标量可以和任意形状的张量进行计算,计算过程就是标量和张量的每一个元素进行计算。

    • t1 + 1 # 1是标量,可以看成是零维 tensor([1, 2, 3])
      t1 + torch.tensor(1) #tensor([1, 2, 3])
      
    • 相同维度、不同形状的张量之间计算;两个张量的形状上有两个分量不同时,只要不同的分量仍然有一个取值为1,则仍然可以广播

    • 在这里插入图片描述

    • 在理解相同维度、不同形状的张量广播之后,对于不同维度的张量之间的广播其实就会容易很多,因为对于不同维度的张量,我们首先可以将低维的张量升维,然后依据相同维度不同形状的张量广播规则进行广播。而低维向量的升维也非常简单,只需将更高维度方向的形状填充为1即可

  • 逐点运算主要包括数学基本运算、数值调整运算和数据科学运算三块,相关函数如下:

    • 函数描述
      torch.add(t1,t2 )t1、t2两个张量逐个元素相加,等效于t1+t2
      torch.subtract(t1,t2)t1、t2两个张量逐个元素相减,等效于t1-t2
      torch.multiply(t1,t2)t1、t2两个张量逐个元素相乘,等效于t1*t2
      torch.divide(t1,t2)t1、t2两个张量逐个元素相除,等效于t1/t2
    • 函数描述
      torch.abs(t)返回绝对值
      torch.ceil(t)向上取整
      torch.floor(t)向下取整
      torch.round(t)四舍五入取整
      torch.neg(t)返回相反的数
    • 虽然此类型函数是数值调整函数,但并不会对原对象进行调整,而是输出新的结果。而若要对原对象本身进行修改,则可考虑使用方法_()的表达形式,对对象本身进行修改。此时方法就是上述同名函数。

    • 数学运算函数数学公式描述
      幂运算
      torch.exp(t)$ y_{i} = e^{x_{i}} $返回以e为底、t中元素为幂的张量
      torch.expm1(t)$ y_{i} = e^{x_{i}} $ - 1对张量中的所有元素计算exp(x) - 1
      torch.exp2(t)$ y_{i} = 2^{x_{i}} $逐个元素计算2的t次方。
      torch.pow(t,n)$\text{out}_i = x_i ^ \text{exponent} $返回t的n次幂
      torch.sqrt(t)$ \text{out}{i} = \sqrt{\text{input}{i}} $返回t的平方根
      torch.square(t)$ \text{out}_i = x_i ^ \text{2} $返回输入的元素平方。
      对数运算
      torch.log10(t)$ y_{i} = \log_{10} (x_{i}) $返回以10为底的t的对数
      torch.log(t)$ y_{i} = \log_{e} (x_{i}) $返回以e为底的t的对数
      torch.log2(t)$ y_{i} = \log_{2} (x_{i}) $返回以2为底的t的对数
      torch.log1p(t)$ y_i = \log_{e} (x_i $ + 1)返回一个加自然对数的输入数组。
      三角函数运算
      torch.sin(t)三角正弦。
      torch.cos(t)元素余弦。
      torch.tan(t)逐元素计算切线。
    • 在数值科学计算中,expm1函数和log1p函数是一对对应的函数关系,后面再介绍log1p的时候会讲解这对函数的实际作用。开根号也就相当于0.5次幂

    • log1p是进行$ y_i = \log_{e} (x_i $ + 1)计算,而expm则是进行$ y_{i} = e^{x_{i}} $ - 1计算,二者互为逆运算。

  • 需要注意的是,虽然Python是动态编译的编程语言,但在PyTorch中,由于会涉及GPU计算,因此很多时候元素类型不会在实际执行函数计算时进行调整。此处的科学运算大多数都要求对象类型是浮点型,我们需要提前进行类型转化

  • 而log1p的实际应用场景有两个,其一是进行数据分布转化操作,另一种则是防止极小的数在进行对数运算时丢失有效位数。

    • 大多数的数理统计分析,在建模过程中,都对数据的分布有较为严格的要求,但真实的数据往往不能满足特定的分布,因此很多时候我们会先对其进行一定程度上的数值转化,而log运算就是常用的将偏态分布的数据转化为高斯分布所使用的函数,并且在此过程中,log1p的效果往往会好于log的效果

    • 另一种使用场景,当处理的数据数值非常小时,使用对数运算往往会因为精度不够而使得计算无法进行(log0没有数学意义),此时使用log1p则可很好的避免这种情况

    • m = torch.tensor(-2.6529) * 1e-20 # tensor(-2.6529e-20)
      # 转化为一个趋近于1的数再运算
      torch.log1p(m) 	# tensor(-2.6529e-20)
      # 此时直接使用log无法执行运算
      torch.log(m) # tensor(nan)
      # 无法运算就无法还原
      torch.exp(torch.log(m)) # tensor(nan)
      # 无损还原
      torch.expm1(torch.log1p(m)) # tensor(-2.6529e-20)
      
    • 在很多场景中,由于计算精度问题导致无法计算,并进一步导致数据信息损失,将会是非常致命的,典型场景如PCA主成分分析,相关问题会在算法讲解中进一步讨论

  • 在PyTorch中,sort排序函数将同时返回排序结果和对应的索引值的排列。

    • t = torch.tensor([1.0, 3.0, 2.0])
      # 升序排列
      torch.sort(t)
      ##
      torch.return_types.sort(
      values=tensor([1., 2., 3.]),
      indices=tensor([0, 2, 1]))
      # 降序排列
      torch.sort(t, descending=True)
      ##
      torch.return_types.sort(
      values=tensor([3., 2., 1.]),
      indices=tensor([1, 2, 0]))
      
  • 规约运算指的是针对某张量进行某种总结,最后得出一个具体总结值的函数。此类函数主要包含了数据科学领域内的诸多统计分析函数,如均值、极值、方差、中位数函数等等。

    • 函数描述
      torch.mean(t)返回张量均值
      torch.var(t)返回张量方差
      torch.std(t)返回张量标准差
      torch.var_mean(t)返回张量方差和均值
      torch.std_mean(t)返回张量标准差和均值
      torch.max(t)返回张量最大值
      torch.argmax(t)返回张量最大值索引
      torch.min(t)返回张量最小值
      torch.argmin(t)返回张量最小值索引
      torch.median(t)返回张量中位数
      torch.sum(t)返回张量求和结果
      torch.logsumexp(t)返回张量各元素求和结果,适用于数据量较小的情况
      torch.prod(t)返回张量累乘结果
      torch.dist(t1, t2)计算两个张量的闵式距离,可使用不同范式; torch.dist(t1, t2, 2)
      torch.topk(t)返回t中最大的k个值对应的指标; torch.topk(t, 2)
  • dist函数可计算闵式距离(闵可夫斯基距离),通过输入不同的p值,可以计算多种类型的距离,如欧式距离、街道距离等。闵可夫斯基距离公式如下: $ D(x,y) = (\sum{n}_{u=1}|x_u-y_u|{p})^{1/p}$

  • 由于规约运算是一个序列返回一个结果,因此若是针对高维张量,则可指定某维度进行计算。

    • # 创建一个3*3的二维向量
      t2 = torch.arange(12).float().reshape(3, 4)
      # 按照第一个维度求和(每次计算三个)、按列求和
      torch.sum(t2, dim = 0) # tensor([12., 15., 18., 21.])
      # 按照第二个维度求和(每次计算四个)、按行求和
      torch.sum(t2, dim = 1) # tensor([ 6., 22., 38.])
  • 比较运算是一类较为简单的运算类型,和Python原生大的布尔运算类似,常用于不同张量之间的逻辑运算,最终返回逻辑运算结果(逻辑类型张量)。基本比较运算函数如下所示:

    • 函数描述
      torch.eq(t1, t2)比较t1、t2各元素是否相等,等效==
      torch.equal(t1, t2)判断两个张量是否是相同的张量
      torch.gt(t1, t2)比较t1各元素是否大于t2各元素,等效>
      torch.lt(t1, t2)比较t1各元素是否小于t2各元素,等效<
      torch.ge(t1, t2)比较t1各元素是否大于或等于t2各元素,等效>=
      torch.le(t1, t2)比较t1各元素是否小于等于t2各元素,等效<=
      torch.ne(t1, t2)比较t1、t2各元素是否不相同,等效!=

相关文章:

pytorch的基本运算,是不是共享了内存,有没有维度变化

可以把PyTorch简单看成是Python的深度学习第三方库&#xff0c;在PyTorch中定义了适用于深度学习的基本数据结构——张量&#xff0c;以及张量的各类计算。其实也就相当于NumPy中定义的Array和对应的科学计算方法&#xff0c;正是这些基本数据类型和对应的方法函数&#xff0c;…...

Visual Studio 2022新建项目时没有ASP.NET项目

一、Visual Studio 2022新建项目时没有ASP.NET项目 1、打开VS开发工具&#xff0c;选择工具菜单&#xff0c;点击“获取工具和功能” 2、选择“ASP.NET和Web开发”和把其他项目模板&#xff08;早期版本&#xff09;勾选上安装即可...

nuiapp项目实战:导航栏动态切换效果实践案例树

测试软件的百忙之中去进行软件开发的工作&#xff0c;开展开发软件的工作事情&#xff0c;也真是繁忙至极点的了。 不到一刻钟的课程内容&#xff0c;个人用了三次去写串联的知识点&#xff0c;然后这是第三次&#xff0c;还是第四次了才完全写出来一个功能的效果。 一刻钟的功…...

【机器学习】集成学习(以随机森林为例)

文章目录 集成学习随机森林随机森林回归填补缺失值实例&#xff1a;随机森林在乳腺癌数据上的调参附录参数 集成学习 集成学习&#xff08;ensemble learning&#xff09;是时下非常流行的机器学习算法&#xff0c;它本身不是一个单独的机器学习算法&#xff0c;而是通过在数据…...

主机jvisualvm连接到tomcat服务器查看jvm状态

​使用JMX方式连接到tomcat&#xff0c;连接后能够查看前边的部分内容&#xff0c;但是不能查看Visual GC&#xff0c;显示不受此JVM支持&#xff0c; 对了&#xff0c;要显示Visual GC&#xff0c;首先要安装visualvm工具&#xff0c;具体安装方式就是根据自己的jdk版本下载…...

uniapp 自定义tabbar页面不刷新

最近在做自定义tabbar时&#xff0c;每次切换页面都要刷新&#xff0c;页面渲染很慢&#xff0c;需要实现切换页面不刷新问题。 结局思路&#xff0c;原生的tabbar切换页面时就不选新&#xff0c;用switchTab来跳转 1.pages.json中配置tabbar&#xff0c;如下,设置高度为0&am…...

3.1 SQL概述

思维导图&#xff1a; 前言&#xff1a; 前言笔记&#xff1a;第3章 关系数据库标准语言SQL - **SQL的定义**&#xff1a; - 关系数据库的标准和通用语言。 - 功能强大&#xff0c;不仅限于查询。 - 功能覆盖&#xff1a;数据库模式创建、数据插入/修改、数据库安全性与…...

xray安装与bp组合使用-被动扫描

xray安装与bp组合使用-被动扫描 文章目录 xray安装与bp组合使用-被动扫描1 工具官方文档&#xff1a;2 xray官网3 工具使用4 使用指令说明5 此为设置被动扫描6 被动扫描-启动成功7 启动bp7.1 设置bp的上层代理7.2 添加上层代理7777 --》指向的是xray7.3 上层代理设置好后&#…...

Java 中Maven 和 ANT

Java 中Maven 和 ANT Maven 和 Ant 都是用于构建和管理Java项目的工具&#xff0c;但它们在设计和功能上有一些重要的区别。以下是关于 Maven 和 Ant 的区别、优缺点以及它们的作用&#xff0c;以及示例说明&#xff1a; Maven&#xff1a; 设计理念&#xff1a; Maven 是基于…...

Flutter通过Pigeon插件与Android同步异步交互

Flutter 调用原生&#xff08;Android&#xff09;方法以及数据传输_flutter调用原生sdk_TDSSS的博客-CSDN博客 https://www.cnblogs.com/baiqiantao/p/16340272.html 可以同时参考这两篇文章...

GTW验厂是什么?GTW验厂评级分类

【GTW验厂是什么&#xff1f;GTW验厂评级分类】 GTW验厂是什么&#xff1f; 全称叫GreenToWear。是为了集合所有环境和产品健康方面的要求&#xff0c;Inditex集团开发的可持续发展准则&#xff08;简称GTW&#xff09;此准则适用于Inditex集 及其供应链中所包含的湿加工厂&…...

CVE-2017-12615 Tomcat远程命令执行漏洞

漏洞简介 2017年9月19日&#xff0c;Apache Tomcat官方确认并修复了两个高危漏洞&#xff0c;漏洞CVE编号&#xff1a;CVE-2017-12615和CVE-2017-12616&#xff0c;其中 远程代码执行漏洞&#xff08;CVE-2017-12615&#xff09; 当 Tomcat 运行在 Windows 主机上&#xff0c;…...

灿芯股份将上会:计划募资6亿元,董事长、总经理均为外籍

10月11日&#xff0c;上海证券交易所披露的信息显示&#xff0c;灿芯半导体&#xff08;上海&#xff09;股份有限公司&#xff08;下称“灿芯股份”&#xff09;将于10月18日接受上市审核委员会审议会议的现场审议。目前&#xff0c;该公司已递交了招股书&#xff08;上会稿&a…...

Spring Cloud Gateway 搭建网关

新建一个module添加依赖&#xff1a; <!--Spring Cloud Gateway依赖--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency><!-- nacos客户端依赖…...

ETL数据转换方式有哪些

ETL数据转换方式有哪些 ETL&#xff08;Extract&#xff0c; Transform&#xff0c; Load&#xff09;是一种常用的数据处理方式&#xff0c;用于从源系统中提取数据&#xff0c;进行转换&#xff0c;并加载到目标系统中。 数据清洗&#xff08;Data Cleaning&#xff09;&am…...

CVE-2017-15715 apache换行解析文件上传漏洞

影响范围 httpd 2.4.0~2.4.29 复现环境 vulhub/httpd/CVE-2017-15715 docker-compose 漏洞原理 在apache2的配置文件&#xff1a; /etc/apache2/conf-available/docker-php.conf 中&#xff0c;php的文件匹配以正则形式表达 ".php$"的正则匹配模式意味着以.ph…...

振弦采集仪应用水坝安全监测的方案

振弦采集仪应用水坝安全监测的方案 随着工业化和城市化的快速发展&#xff0c;水资源的开发和利用越来越广泛。由于水坝在水利工程中起着至关重要的作用&#xff0c;因此对水坝进行安全监测变得越来越必要。为了实现对水坝的安全监测&#xff0c;振弦采集仪可以作为一种有效的…...

【Java】查找jdk步骤

需求描述 解决方法 第一步 第二步 第三步 第四步 参考文章...

【mysql】Mysql自定义变量 @rownum使用

Mysql自定义变量 rownum 这个可以赋值&#xff1f;这是初始化&#xff1f; 先看表结构 有五条数据。执行前半段语句发现。rownum的起始值等于行数 这里from后面可以加person与 r这连个组成 如果这里的rownum打错了呢。发现这个变量就没有初始值。 可见&#xff0c;没有必要…...

命令行启动android模拟器

有时候不想打开android studio就能方便的启动模拟器&#xff0c;探索一番后发现可以通过命令行来启动&#xff0c;方便快捷。 环境准备 首先安装好android studio&#xff0c;android sdk&#xff0c;从android studio中安装好模拟器。 命令启动 如果直接在终端输入emulato…...

Three.js如何计算3DObject的2D包围框?

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 在Three.js应用开发中&#xff0c;有时你可能需要为3D场景中的网格绘制2D的包围框&#xff0c;应该怎么做&#xff1f; 朴素的想法是把网格的3D包围框投影到屏幕空间&#xff0c;例如&#xff0c;下图中的绿色框 3D包围框…...

【LeetCode热题100】--347.前K个高频元素

347.前K个高频元素 方法&#xff1a;堆 首先遍历整个数组&#xff0c;并使用哈希表记录每个数字出现的次数&#xff0c;并形成一个「出现次数数组」。找出原数组的前 k 个高频元素&#xff0c;就相当于找出「出现次数数组」的前 k 大的值 利用堆的思想&#xff1a;建立一个小…...

解决服务器80端口无法连接的办法

云服务器是现代企业建立应用程序和存储数据的理想选择。但是在使用云服务器的过程中&#xff0c;会遇到80端口无法连接的问题。这个问题可能会导致网站无法正常运行&#xff0c;从而给企业带来负面影响。因此&#xff0c;在这篇文章中&#xff0c;我们将探讨如何解决云服务器80…...

040:mapboxGL鼠标hover更换选中feature颜色

第040个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中通过鼠标hover的方式来更换选中feature颜色。这里面利用了mousemove和mouseleave的方法,通过选中图层的feature,来设置hover的true或者false,从而通过opacity的case状态来判断透明度用哪一个值。 直接复…...

【C++心愿便利店】No.8---C++之重识类和对象

文章目录 前言一、再谈构造函数二、static成员三、友元四、内部类五、匿名对象六、再次理解类和对象 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到我的乱七八糟小星球&#x1f31d; &#x1f4cb;专栏&#xff1a;C 心愿便利店 &…...

【AI视野·今日NLP 自然语言处理论文速览 第五十二期】Wed, 11 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 11 Oct 2023 Totally 81 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers LongLLMLingua: Accelerating and Enhancing LLMs in Long Context Scenarios via Prompt Compression Author…...

优雅而高效的JavaScript——模板字面量

&#x1f928;博主&#xff1a;小猫娃来啦 &#x1f928;文章核心&#xff1a;优雅而高效的JavaScript——模板字面量 文章目录 什么是模板字面量使用模板字面量插入变量处理多文本模板字面量的高级应用标签模板字量自定义模板字面量函数 常见应用场景拼接字符串HTML模板SQL查询…...

Python一步到位实现图像转PDF自动化处理详解

什么是 img2pdf 库&#xff1f; img2pdf 是一个 Python 库&#xff0c;它可以让你轻松地把多张图像转换为 PDF 文件。它支持多种图像格式&#xff0c;如 JPG, PNG, GIF, BMP 等&#xff0c;并且可以自动调整图像的大小和方向&#xff0c;以适应 PDF 的页面大小和方向。它还可以…...

基于IDEA集成环境---Nacos安装

Nacos服务器是独立安装部署的&#xff0c;因此我们需要下载最新的Nacos服务端程序&#xff0c;下载地址&#xff1a;https://github.com/alibaba/nacos。 将文件进行解压&#xff0c;得到以下内容&#xff1a; 直接将其拖入到项目文件夹下&#xff0c;便于我们一会在IDEA内部…...

使用 puppeteer 加载 html 文件来运行 js 文件

遇到一个需求, 在浏览器环境下来运行 js sdk 文件, 这个 js 文件是不能运行在 nodejs 环境下的; 所以通过 puppeteer 无头浏览器来运行代码获取对应的结果。 首先是安装插件 puppeteer&#xff0c;然后创建一个项目, 我这里是express&#xff1b; 这里是主要的代码。 const p…...

Java 操作 Excel:生成数据、设置单元格样式、设置数据有效性(hutool)

必读信息 该篇文章&#xff0c;主要通过 Java 代码对 Excel 文件的常用操作&#xff0c;包括&#xff1a;生成表格、修改单元格样式、设置数据有效性。 该篇文章&#xff0c;在官网文献下增加个人的看法和理解&#xff0c;如文中有出现不符、错误或需要补充的地方&#xff0c…...

YOLOv5算法改进(11)— 主干网络介绍(MobileNetV3、ShuffleNetV2和GhostNet)

前言:Hello大家好,我是小哥谈。主干网络通常指的是深度学习中的主干模型,通常由多个卷积层和池化层组成,用于提取输入数据的特征。在训练过程中,主干网络的参数会被不断优化以提高模型的准确性。YOLOv5算法中的主干网络可以有多种替换方案,为了后面讲解的方便,本篇文章就…...

ideal远程Debug部署在服务器上的服务详解

ideal远程Debug部署在服务器上的服务详解 一 简介二 ideal配置步骤第一步&#xff1a;点击Edit Configurations选项添加远程连接第二步&#xff1a;配置Remote JVM debug参数第三步&#xff1a;服务的启动参数中添加第二步生成的命令并重新启动服务第四步&#xff1a;ideal启动…...

基于SSM的校园音乐平台系统

基于SSM的校园音乐平台系统~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 登录界面 管理员界面 歌手管理 歌曲管理 摘要 校园音乐平台系统&#xff08;Campus Mu…...

07_03文件系统怎么玩的

文件系统 Linux将文件系统分为了两层&#xff1a;VFS&#xff08;虚拟文件系统&#xff09;、具体文件系统&#xff0c;如下图所示&#xff1a; VFS&#xff08;Virtual Filesystem Switch&#xff09;称为虚拟文件系统或虚拟文件系统转换&#xff0c;是一个内核软件层&#…...

php实战案例记录(24)不要键名只保留值的算法

php中对数组 $originalArray array( “name” > “John”, “age” > 25, “city” > “New York” )仅去除键名保留值的算法是什么 array_values() 函数 在 PHP 中&#xff0c;你可以使用 array_values() 函数来去掉数组的键名。该函数会返回一个新数组&#xff0c…...

【交付高质量,用户高增长】-用户增长质量保证方法论 | 京东云技术团队

前言 俗话说&#xff0c;“测试是质量的守护者”&#xff0c;但单凭测试本身却远远不够。大多数情况下&#xff0c;测试像“一面镜子”&#xff0c;照出系统的面貌&#xff0c;给开发者提供修改代码的依据&#xff0c;这个“照镜子”的过程&#xff0c;就是质量评估的过程&…...

LMI FocalSpec 3D线共焦传感器 使用笔记1

一.硬件介绍 以上特别注意: 屏蔽线必须接地,因为在现场实际调试中,使用软件调试发现经常 弹窗 传感器丢失警告!! 以上 Position LED 的灯被钣金挡住,无法查看异常现象,能否将指示灯设置在软件界面上? 需要确认是软触发还是硬触发,理论上 硬触发比软触发速度要快.(我们目前使用…...

四、RocketMQ发送普通消息、批量消息和延迟消息

Producer发送普通消息的方式 1.同步发送消息 同步消息代表发送端发送消息到broker之后&#xff0c;等待消息发送结果后&#xff0c;再次发送消息 实现步骤 创建生产端&#xff0c;声明在哪个生产组注册NameServer地址构建Message实体&#xff0c;指定topic、tag、body启动…...

idea自定义 postfix completion提高编码效率

postfix completion的使用 详情见&#xff1a; https://www.cnblogs.com/expiator/p/17380495.html 自定义 postfix completion List、 String 初始化list&#xff1a; key: list表达式&#xff1a; List<$EXPR$> $END$List new ArrayList<>();字符串判空&…...

解锁学习电路设计的正确姿势!

...

【Linux】 ps命令使用

作为一个后端的程序员&#xff0c;我们经常用到ps -ef | grep XXX 到底什么事ps呢。 下面我们一起学习一下吧、 ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器。 ps命令 -Linux手册页 …...

打造高效的分布式爬虫系统:利用Scrapy框架实现

在大数据时代的今天&#xff0c;爬虫系统成为了获取和分析海量数据的重要工具。本文将介绍如何使用Scrapy框架来构建一个高效的分布式爬虫系统&#xff0c;以加速数据采集过程和提高系统的可扩展性。 Scrapy框架简介 Scrapy是一个基于Python的强大的开源网络爬虫框架&#xff…...

SpringCloud组件Ribbon的IRule的问题排查

最近很久没有写文章啦&#xff0c;刚好遇到了一个问题&#xff0c;其实问题也挺简单&#xff0c;但是还是得对源码有一定了解才能够发现。 最近在实现一个根据请求流量的标签&#xff0c;将请求转发到对应的节点&#xff0c;其实和俗称的灰度请求有点相似&#xff0c; 实现思…...

比较完整一些chatGPT项目代码(权威)

https://gitee.com/zccbbg/chatgpt-springboot-service yml中的配置文件无法读取&#xff0c;前端访问比较困难。...

Python - 生成二维码、条形码

二维码 import qrcode# 要生成的文本或链接 data "要生成的文本或链接"# 创建QR码对象 qr qrcode.QRCode(version1, # 版本号&#xff0c;通常设置为1error_correctionqrcode.constants.ERROR_CORRECT_L, # 错误修正级别box_size10, # 每个小方块的像素大小bor…...

8+纯生信,多组机器学习+分型探讨黑色素瘤发文思路。

今天给同学们分享一篇泛癌多组机器学习分型的生信文章“Comprehensive characterisation of immunogenic cell death in melanoma revealing the association with prognosis and tumor immune microenvironment”&#xff0c;这篇文章于2022年9月23日发表在Front Immunol 期刊…...

GPU高性能面试-写一个ReduceKernel

要求写一个reduceKernel 要求给出Kerne的完整调用: 1. 进行一维reduce 可以写一个最基础的&#xff0c;仅仅实现基础功能就行 使用share mem进行功能优化 使用shuffles指令完成block reduce操作 2.实现二维reduce...

深入探索STARK的安全性和可靠性——STARKs全面安全分析

1. 引言 non-interactive STARKs&#xff0c;起源于Interactive Oracle Proofs (IOPs)&#xff0c;然后通过random oracle模式转换为非交互式。StarkWare团队 ethSTARK Documentation – Version 1.2&#xff08;2023年7月&#xff09;论文做了更新&#xff0c;给出了完整具体…...

WPF 控件分辨率自适应问题

WPF 控件分辨率自适应时&#xff0c;我首先想到的是使用ViewBox控件来做分辨率自适应。 ViewBox这个控件通常和其他控件结合起来使用&#xff0c;是WPF中非常有用的控件。定义一个内容容器。ViewBox组件的作用是拉伸或延展位于其中的组件&#xff0c;以填满可用空间&#xff0…...