0_Pytorch中的张量操作

[引言]张量的概念

1.基本概念
  • 张量是一个通用的多维数组,可以表示标量(0 维)、向量(1 维)、矩阵(2 维)以及更高维度的数据。
  • 张量是 PyTorch 中的核心数据结构,用于表示和操作数据。

0维张量:标量(scalar)
1维张量:向量(vector)
2维张量:矩阵(matrix)
多维张量: 例如三维张量==>类比魔方

1.张量的创建

张量的基本创建

  • torch.tensor() 根据指定数据创建张量

    # 1.根据指定数据创建张量 - torch.tensor
    print('tensor 方式创建张量')# 1.1 创建张量标量
    data = torch.tensor(10)
    print(f'张量标量:{data}')# 1.2 根据 numpy数组 创建张量
    data = np.random.randn(3, 2)
    data = torch.tensor(data)
    print(f'根据numpy数组创建张量:\r\n{data}')# 1.3 根据 列表 创建张量
    data = [[1, 0, 0], [0, 1, 0]]
    data = torch.tensor(data)
    print(f'根据列表创建张量:\r\n{data}')
    
  • torch.Tensor() 根据形状创建张量, 其也可用来创建指定数据的张量

    # 2. 根据形状创建张量 - torch.Tensor
    print('Tensor 方式创建张量')
    #   2.1 创建 2 行 3 列的张量 默认的dtype为 float32
    data = torch.Tensor(2, 3)
    print(data)#   2.2 注意!! 如果 传递列表, 则创建包含指定元素的张量
    data = torch.Tensor([10])
    print(data)
    
  • torch.IntTensor()、torch.FloatTensor()、torch.DoubleTensor() 创建指定类型的张量

    # 3.创建指定类型的张量 - torch.IntTensor、torch.FloatTensor、torch.DoubleTensor
    print('创建指定类型的张量-> torch.IntTensor、torch.FloatTensor、torch.DoubleTensor')
    #   3.1 创建 2 行 3 列,dtype为 int32 的张量
    data = torch.IntTensor(2, 3)
    print(data)#   3.2 注意!! 如果传递的类型不正确,则会进行类型转换
    data = torch.IntTensor([2.5, 3.3])
    print(data)
    """
    其他的一些类型
    class DoubleTensor(Tensor): ...
    class FloatTensor(Tensor): ...
    class BFloat16Tensor(Tensor): ...
    class LongTensor(Tensor): ...
    class IntTensor(Tensor): ...
    class ShortTensor(Tensor): ...
    class HalfTensor(Tensor): ...
    class CharTensor(Tensor): ...
    class ByteTensor(Tensor): ...
    class BoolTensor(Tensor): ...
    """
    
1-总结

小写 t: 根据指定数据创建
大写 T: 既可以根据指定数据创建,也可以根据形状创建

Tensor: 不指定类型

(Type)Tensor: 指定类型

创建线性张量和随机张量

  • torch.arange() 和 torch.linspace() 创建线性张量

    # 1. 创建线性张量
    print('=' * 50 + '创建线性张量' + '=' * 50)
    #   1.1 在指定区间内按照步长生成元素
    data = torch.arange(0, 10, 2)
    print(data)#   1.2 在指定区间按照元素个数生成
    data = torch.linspace(0, 10, 9)
    print(data)
    
  • torch.random.init_seed() 和 torch.random.manual_seed() 随机种子设置

  • torch.randn() 创建随机张量

# 2.创建随机张量
print('=' * 50 + '创建随机张量' + '=' * 50)
#   2.1 创建一个 2 行 3列的随机张量
data = torch.randn(2, 3)
print(data)#   2.2 设置随机数种子
#   - torch.random.init_seed
print(f'随机数种子: {torch.random.initial_seed()}')  # 25338627685600
#   - torch.random.manual_seed
torch.random.manual_seed(200)
data = torch.randn(2, 3)
print(data)
print(f'随机数种子: {torch.random.initial_seed()}')  # 100

创建0-1张量

  • torch.ones 和 torch.ones_like 创建全1张量
  • torch.zeros 和 torch.zeros_like 创建全0张量
  • torch.full 和 torch.full_like 创建全为指定值张量
import torch# - torch.ones 和 torch.ones_like 创建全1张量
data = torch.ones(2, 3)
print(f'data:\r\n{data}')
data1 = torch.ones_like(data)
print(f'data1:\r\n{data1}')# - torch.zeros 和 torch.zeros_like 创建全0张量
data = torch.zeros(2, 3)
print(f'data:\r\n{data}')
data1 = torch.zeros_like(data)
print(f'data1:\r\n{data1}')# - torch.full 和 torch.full_like 创建全为指定值张量
data = torch.full([2, 3], 10, dtype=torch.float32)
print(f'data:\r\n{data}')
data1 = torch.full_like(data, 20)
print(f'data1:\r\n{data1}')
print(f'data1.dtype:{data1.dtype}')  # float32

2.张量的类型转换

张量的元素类型转换
  • data.type(torch.DoubleTensor)
  • data.double()
import torch
# 1. data.type(torch.类型)
print('===============data.type(torch.类型)================')
data = torch.full([2, 3], 10)
print(data.dtype)data = data.type(torch.DoubleTensor)
print(data.dtype)# data = data.type(torch.IntTensor)
# print(data.dtype)
# data = data.type(torch.LongTensor)
# print(data.dtype)# 2. data.double()
print('===============data.double()=================')
data = torch.full([2, 3], 20)
print(data.dtype)data = data.double()
print(data.dtype)# data = data.int()
# print(data.dtype)

张量的类型转换

  1. 张量转换为Numpy数组的方法
  • 使用 Tensor.numpy 函数可以将张量转换为 ndarray 数组,但是共享内存,可以使用 copy 函数避免共享。

    # 1. 张量转换为Numpy数组的方法
    # - 使用 Tensor.numpy 函数可以将张量转换为 ndarray 数组,但是共享内存,可以使用 copy 函数避免共享.
    print('=' * 30 + '使用 Tensor.numpy但不进行copy' + '=' * 30)
    data_tensor = torch.tensor([2, 3, 4])
    data_numpy = data_tensor.numpy()
    print(type(data_tensor))
    print(type(data_numpy))data_numpy[0] = 100
    print(data_tensor)
    print(f'ndarray:{data_numpy}')print('=' * 30 + '使用 Tensor.numpy并进行copy' + '=' * 30)
    data_tensor = torch.tensor([2, 3, 4])
    data_numpy = data_tensor.numpy().copy()
    print(type(data_tensor))
    print(type(data_numpy))data_numpy[0] = 100
    print(data_tensor)
    print(f'ndarray:{data_numpy}')
    
    1. Numpy数组转换为张量的方法
    • 使用 from_numpy 可以将 ndarray 数组转换为 Tensor,默认共享内存,使用 copy 函数避免共享。

    • 使用 torch.tensor 可以将 ndarray 数组转换为 Tensor,默认不共享内存。

      # 2. Numpy数组转换为张量的方法
      """
      将numpy数组转换为张量2.1 from_numpy 默认共享内存,使用 copy 函数避免共享。2.2 torch.tensor(ndarray) 默认不共享内存。
      """
      # - 2.1 使用 from_numpy:会共享内存,可以使用 copy 函数避免共享。
      print('=' * 30 + '使用from_numpy但不进行copy' + '=' * 30)
      data_numpy = np.array([2, 3, 4])
      data_tensor = torch.from_numpy(data_numpy)
      data_tensor[0] = 100
      print(data_tensor)
      print(f'ndarray:{data_numpy}')print('=' * 30 + '使用from_numpy且进行copy' + '=' * 30)
      data_numpy = np.array([2, 3, 4])
      data_tensor = torch.from_numpy(data_numpy.copy())
      data_tensor[0] = 100
      print(data_tensor)
      print(f'ndarray:{data_numpy}')# - 2.2 使用 torch.tensor(ndarray) 默认不共享内存。
      data_numpy = np.array([2, 3, 4])
      data_tensor = torch.tensor(data_numpy)data_tensor[0] = 100
      print(data_tensor)
      print(f'ndarray:{data_numpy}')
      
      1. 标量张量和数字转换方法
      • 对于只有一个元素的张量,使用item()函数将该值从张量中提取出来

        官方文档解释: Returns the value of this tensor as a standard Python number.
        This only works for tensors with one element.

# 3. 标量张量和数字转换方法
# - 对于只有一个元素的张量,使用item()函数将该值从张量中提取出来
data_tensor = torch.tensor([30, ])
print(data_tensor.item())data_tensor = torch.tensor(30)
print(data_tensor.item())

3.张量数值计算

  1. 张量基本运算
  • 不修改原数据

    • add、sub、mul、div、neg
  • 修改源数据

    • add_、sub_、mul_、div_、neg_(带下划线的版本会修改原数据)
    # 1.张量基本运算
    print('=' * 30 + '基本运算' + '=' * 30)
    data = torch.randint(0, 10, [2, 3])
    print(f'原数据data:\r\n{data}')#   1.1 不修改原数据
    print('=' * 10 + 'add' + '=' * 10)
    new_data = data.add(10)
    print(f'new_data:\r\n{new_data}')
    print(f'data:\r\n{data}')#   1.2 直接修改原数据
    print('=' * 10 + 'add_' + '=' * 10)
    data.add_(10)
    print(f'data:\r\n{data}')# print(data.sub(10))
    # print(data.mul(10))
    # print(data.div(10))
    # print(data.neg())
    
  1. 张量点乘运算

    • 点乘指(Hadamard积)的是两个 同维[同型]矩阵 对应位置的元素相乘,使用mul 和运算符 * 实现。

      # 2. 张量点乘运算
      print('=' * 30 + '张量点乘运算' + '=' * 30)
      A = torch.tensor([[1, 2], [3, 4]])
      B = torch.tensor([[5, 6], [7, 8]])# - 2.1 使用 mul(A,B)
      print('=' * 10 + 'mul 点乘' + '=' * 10)
      res = torch.mul(A, B)
      print(f'点乘后的结果:{res}')# - 2.2 使用 * 运算符
      print('=' * 10 + '* 点乘' + '=' * 10)
      res = A * B
      print(f'点乘后的结果:{res}')
      
  2. 张量矩阵乘法运算

    矩阵乘法运算要求第一个矩阵 shape: (n, m),第二个矩阵 shape: (m, p), 两个矩阵点积运算 shape 为: (n, p)。

    • 1.运算符 @ 用于进行两个矩阵的乘积运算
    • 2.torch.matmul 对进行乘积运算的两矩阵形状没有限定.对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
# 3. 张量矩阵乘法运算
print('=' * 30 + '张量矩阵乘法运算' + '=' * 30)
A = torch.tensor([[1, 2], [3, 4], [5, 6]])
B = torch.tensor([[5, 6], [7, 8]])#   3.1 使用 matmul(A,B)
# - torch.matmul 对进行乘积运算的两矩阵形状没有限定.对数输入的 shape 不同的张量, 对应的最后几个维度必须符合矩阵运算规则
print(f'matmul(A,B) ={torch.matmul(A, B)}')#   3.2 使用@ 运算符
print(f'A @ B = {A @ B}')

4.张量运算函数

"""
- 均值
- 平方根
- 求和
- 指数计算
- 对数计算
.......
"""
import torchdata = torch.randint(0, 10, [2, 3], dtype=torch.float64)
print(data)# 1.均值
# 注意!! tensor必须为 float 或者 Double类型
print('=' * 10 + 'mean' + '=' * 10)
print(data.mean())
print(data.mean(dim=0))  # 按列求均值
print(data.mean(dim=1))  # 按行求均值# 2.求和
print('=' * 10 + 'sum' + '=' * 10)
print(data.sum())
print(data.sum(dim=0))
print(data.sum(dim=1))# 3.计算平方
print('=' * 10 + 'pow' + '=' * 10)
print(torch.pow(data, 2))
print(data.pow(2))# 4.计算平方根
print('=' * 10 + 'sqrt' + '=' * 10)
print(data.sqrt())
print(torch.sqrt(data))# 5.指数计算 e^n 次方
print('=' * 10 + 'exp' + '=' * 10)
print(data.exp())
print(torch.exp(data))# 6.对数计算 :以 e 为底数
print('=' * 10 + 'log' + '=' * 10)
print(data.log())
print(torch.log(data))
print(data.log2())
print(data.log10())

5.张量索引操作

  1. 简单行列索引的使用

    格式:data[row,col]
    

    代码

    data = torch.randint(0, 10, [4, 5])
    print('data->\r\n', data)# 1. 简单行列索引的使用
    print('=' * 20, '简单行列索引', '=' * 20)
    print(f'data[0, 0] -> {data[0, 0]}')
    print(f'data[:,0] -> {data[:, 0]}')
    
  2. 列表索引的使用

    格式:rows = [a,b,...]cols = [c,d...]访问:data[rows,cols]
    含义:访问 [a,c] | [b,d]....的值
    

    代码:

    data = torch.randint(0, 10, [4, 5])
    print('data->\r\n', data)# 2. 列表索引的使用
    print('=' * 20, '列表索引', '=' * 20)
    #   2.1 返回 (0, 2)、(1, 3) 两个位置的元素
    rows = [0, 1]
    cols = [2, 3]
    print(f'data[rows,cols] ->', data[rows, cols])
    #   2.2 返回行索引为 0 的第 1、2、3 列的值
    print(f'data[[0],[1,2]] ->', data[[0], [1, 2]])#   2.3 range()方式访问元素:返回 (0, 1) 和 (1, 2) 两个位置的元素
    print(f'data[rows,cols] ->', data[range(2), range(1, 3)])#   2.4 返回行索引为 0 和 1 的第 1、2、3 列的值
    print(f'data[[[0], [1]], [1, 2, 3]] ->', data[[[0], [1]], [1, 2, 3]])#   2.5 返回行索引为 0、1、2 的第 0、1、2 列的值 和 行索引为 1、2、3 的第 1、2、3 列的值
    print(f'data[[[0, 1, 2], [1, 2, 3]], [[0, 1, 2], [1, 2, 3]]] ->', data[[[0, 1, 2], [1, 2, 3]], [[0, 1, 2], [1, 2, 3]]])# print('data[[[0],[1,2,3]], [0,1,2]] ->',{data[0, 0]}) # 报错, 因为索引的维度不匹配
    
  3. 范围索引的使用

    • Numpy大致相同,但不 支持反向索引
    data = torch.randint(0, 10, [4, 5])
    print('data->\r\n', data)# 3. 范围索引的使用
    print('=' * 20, '范围索引', '=' * 20)
    # 3.1   获取前三行前两列元素的值
    print('data[:3,:2]->', data[:3, :2])# 3.2   获取后两行后两列元素的值
    print('data[-2:,-2:]->', data[-2:, -2:])# print('data[3:1:-1,-2:]->', data[3:1:-1, -2:]) # 报错,tensor不支持反向切片
    
  4. 布尔索引的使用

     - 和`Numpy`,`Pandas`大致相同
    
    # 4. 布尔索引的使用
    print('=' * 20, '布尔索引', '=' * 20)
    #   4.0 理解布尔索引的原理
    bool_index = [True, False, False, True, False]
    """
    注意它取元素时的方式!!!!第一行中满足布尔索引的拿出来,当作一行第二行中满足布尔索引的拿出来,当作一行以此类推
    """
    print('data[:,bool_index] ->\r\n', data[:, bool_index])#   4.1 获取第三行大于 5的元素
    print(data[data[:, 2] > 5])#   4.2 获取第二行大于 5的 列
    print('data[:,data[1]>5] ->\r\n', data[:, data[1] > 5])
    
  5. 多维索引的使用

    • Numpy,Pandas大致相同
data = torch.randint(0, 10, [4, 5])
print('data->\r\n', data)# 5. 多维索引的使用
print('=' * 20, '多维索引', '=' * 20)
data = torch.randint(0, 10, [3, 4, 5])
print('data->\r\n', data)
#   5.1 获取第一维元素
print(data[0, :, :])
#   5.2 获取第二维元素
print(data[:, 0, :])
#   5.3 获取第三维元素 # 注意它取元素的方式!!!
print(data[:, :, 0])

6.张量形状操作

0.形状信息获取
使用 shape 属性或者 size 方法都可以获得张量的形状

data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 1. 使用 shape 属性或者 size 方法都可以获得张量的形状
print('使用 shape 属性或者 size 方法都可以获得张量的形状')
print(data.shape, data.shape[0], data.shape[1])
print(data.size(), data.size(0), data.size(1))
print()

1.reshape方式修改形状

​ - reshape()

reshape 函数可以在保证张量数据不变的前提下改变数据的维度,将其转换成指定的形状
转换顺序:左右上下

data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 2. 使用 reshape() 修改张量的形状
print('使用 reshape() 修改张量的形状')
reshape_data = data.reshape(1, data.shape[0] * data.shape[1])
print(f'reshape_data:{reshape_data}')
print(f'reshape_data:{data.reshape(1, -1)}')
print()
  1. 升维与降维

    • squeeze()

    • unsqueeze()

      - squeeze函数 删除形状为 1 的维度(降维)
      - unsqueeze函数 添加形状为1的维度(升维)
      

      unsqueeze(dim=i):在索引为i的位置添加一个形状为1的维度

      data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 3. squeeze()和unsqueeze()函数
      print('squeeze()和unsqueeze()函数')
      mydata1 = torch.tensor([1, 2, 3, 4, 5, 6])
      print('mydata1->', mydata1.shape, mydata1)  # torch.Size([6])mydata2 = mydata1.unsqueeze(dim=0)
      print('在0维度上 扩展维度:', mydata2, mydata2.shape)  # torch.Size([1, 6])mydata3 = mydata1.unsqueeze(dim=1)
      print('在1维度上 扩展维度:\r\n', mydata3, mydata3.shape)  # torch.Size([6, 1])mydata4 = mydata1.unsqueeze(dim=-1)
      print('在-1维度上 扩展维度:\r\n', mydata3, mydata3.shape)  # torch.Size([6, 1])mydata5 = mydata4.squeeze()
      print('压缩维度:', mydata5, mydata5.shape)  # torch.Size([6])
      print()
      
  2. 修改形状

    • transpose()

    • permute()

      transpose 函数可以实现交换张量形状的指定维度, 例如: 一个张量的形状为 (2, 3, 4) 可以通过 transpose 函数把 3 和 4进行交换, 将张量的形状变为 (2, 4, 3) 。
      permute 函数可以一次交换更多的维度。

      data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 4.transpose() 和 permute()
      print('transpose() 和 permute()')
      data = torch.tensor(np.random.randint(0, 10, [2, 3, 3]))
      print(f'data shape:{data.size()}')
      print(data)
      #   4.1 交换1 和 2维度
      data_transpose = torch.transpose(data, 1, 2)
      print(f'data_transpose shape:{data_transpose.size()}')#   4.2 将data 的形状修改为 (4, 5, 3), 需要变换多次
      data_transpose1 = torch.transpose(data, 0, 1)
      print(data_transpose1)
      data_transpose1 = torch.transpose(data_transpose1, 1, 2)
      print(f'data_transpose1 shape:{data_transpose1.size()}')#   4.3 使用 permute 函数将形状修改为 (4, 5, 3)
      data_transpose2 = torch.permute(data, (1, 2, 0))
      print(f'data_transpose1 shape:{data_transpose2.size()}')
      
    • view()

      view 函数也可以用于修改张量的形状,只能用于存储在整块内存中的张量。
      在 PyTorch 中,有些张量是由不同的数据块组成的,它们并没有存储在整块的内存中,view 函数无法对这样的张量进行变形处理.
      例如: 一个张量经过了transpose 或者 permute 函数的处理之后,就无法使用 view 函数进行形状操作。

    • contiguous()

      若要使用view函数, 需要使用contiguous() 变成连续以后再使用view函数
      is_contiguous() 判断是否 连续存储

data = torch.tensor([[10, 20, 30], [40, 50, 60]])# 5.view()和contiguous()函数"""
1. 一个张量经过了 transpose 或者 permute 函数的处理之后,就无法使用view 函数进行形状操作若要使用view函数, 需要使用contiguous() 变成连续以后再使用view函数
2. 判断张量是否使用整块内存 is_contiguous
"""
print('view()和is_contiguous()函数')
data = torch.tensor([[10, 20, 30], [40, 50, 60]])
print('data--->', data, data.shape)# 5.1 判断是否使用整块内存
print(data.is_contiguous())  # True# 5.2 view
data_view = data.view(3, 2)
print('data_view ->', data_view, data_view.shape)# 5.3 判断是否使用整块内存
print('data_view.is_contiguous->', data_view.is_contiguous())
print()# 5.4 使用 transpose 函数修改形状
print('view()和contiguous()函数')
data_transpose = data.transpose(0, 1)
print('data_transpose->', data_transpose, data_transpose.shape)
print('data_transpose.is_contiguous->', data_transpose.is_contiguous())
print(data_transpose.contiguous().is_contiguous())
data_view = data_transpose.contiguous().view(2, 3)
print('data_view->', data_view.shape, data_view)
print('')

7.张量拼接操作

张量拼接(Concatenation)是将多个张量按指定的维度连接起来的操作。

  • torch.cat()

    • torch.cat 是按指定维度将多个张量连接起来,拼接后的维度大小会变化,但总维数保持不变。

    • 使用时,所有张量在指定的拼接维度上必须形状一致。

      # 1. torch.cat()
      print('================cat 方式拼接=====================')
      data1 = torch.randint(0, 10, [1, 2, 3])
      data2 = torch.randint(0, 10, [1, 2, 3])
      print(f'data1:{data1}')
      print(f'data2:{data2}')
      print()
      #   1.1 按 0维拼接
      new_data = torch.cat([data1, data2], dim=0)
      print('按 0维 拼接->', new_data, new_data.size())#   1.2 按 1维拼接
      new_data = torch.cat([data1, data2], dim=1)
      print('按 1维 拼接->', new_data, new_data.size())#   1.3 按 2维拼接
      new_data = torch.cat([data1, data2], dim=2)
      print('按 2维 拼接->', new_data, new_data.size())
      print()
      
  • torch.stack() [了解]

    • torch.stack 是在新维度上将多个张量连接起来,拼接后的总维数会增加 1。

    • 使用时,所有张量的形状必须完全一致。

      # 2.stack
      print('================stack 方式拼接=====================')
      data1 = torch.randint(0, 10, [1, 2, 3])
      data2 = torch.randint(0, 10, [1, 2, 3])
      print(f'data1:{data1}')
      print(f'data2:{data2}')#   2.1 按 0维连接
      new_data = torch.stack([data1, data2], dim=0)
      print('按 0维 连接->', new_data, new_data.size())#   2.2 按 1维连接
      new_data = torch.stack([data1, data2], dim=1)
      print('按 1维 连接->', new_data, new_data.size())#   2.3 按 2维连接
      new_data = torch.stack([data1, data2], dim=2)
      print('按 2维 连接->', new_data, new_data.size())
      print()
      
torch.cattorch.stack 的区别
q特性torch.cattorch.stack
总维数变化不增加维数增加 1 个维数
形状要求指定维度一致所有维度必须完全一致
典型应用沿某个轴扩展数据创建新的批量或时间步维度

8.自动微分模块

- 反向传播算法```properties在该算法中,参数(模型权重)会根据损失函数关于对应参数的梯度进行调整。为了计算这些梯度,PyTorch内置了名为 torch.autograd 的微分引擎。它支持任意计算图的自动梯度计算, 使用 backward 方法、grad 属性来实现梯度的计算和访问.```

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

示例:

# 1. 当X为标量时梯度的计算
def scaler_grad_compute():x = torch.tensor(5)# 目标值: labely = torch.tensor(0.)# 设置要更新的权重和偏置的初始值w = torch.tensor(1, requires_grad=True, dtype=torch.float32)b = torch.tensor(3, requires_grad=True, dtype=torch.float32)# 设置网络的输出值z = w * x + b  # 矩阵乘法?# 设置损失函数,并进行损失的计算loss = torch.nn.MSELoss()loss = loss(z, y)# 自动微分loss.backward()# 打印 w,b 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print(f'w->{w.grad}')print(f'b->{b.grad}')
# 2.非标量下时梯度的计算
def grad_compute():# 输入张量(2,5)x = torch.ones(2, 5)# 输出张量(2,3)y = torch.zeros(2, 3)# 设置要更新的权重和偏置的初始值w = torch.randn(5, 3, requires_grad=True)b = torch.randn(3, requires_grad=True)# 设置神经网络的输出值z = torch.matmul(x, w) + b# 设置损失函数,并进行损失的计算loss = torch.nn.MSELoss()loss = loss(z, y)  # 底层实现了__call__()方法print(y)# 自动微分loss.backward()# 打印 w,b 变量的梯度# backward 函数计算的梯度值会存储在张量的 grad 变量中print("W的梯度:", w.grad)print("b的梯度", b.grad)

矩阵乘法?

# 设置损失函数,并进行损失的计算
loss = torch.nn.MSELoss()
loss = loss(z, y)# 自动微分
loss.backward()
# 打印 w,b 变量的梯度
# backward 函数计算的梯度值会存储在张量的 grad 变量中
print(f'w->{w.grad}')
print(f'b->{b.grad}')

2.非标量下时梯度的计算

def grad_compute():
# 输入张量(2,5)
x = torch.ones(2, 5)
# 输出张量(2,3)
y = torch.zeros(2, 3)
# 设置要更新的权重和偏置的初始值
w = torch.randn(5, 3, requires_grad=True)
b = torch.randn(3, requires_grad=True)

# 设置神经网络的输出值
z = torch.matmul(x, w) + b
# 设置损失函数,并进行损失的计算
loss = torch.nn.MSELoss()
loss = loss(z, y)  # 底层实现了__call__()方法
print(y)
# 自动微分
loss.backward()
# 打印 w,b 变量的梯度
# backward 函数计算的梯度值会存储在张量的 grad 变量中
print("W的梯度:", w.grad)
print("b的梯度", b.grad)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LS-LINUX-002 简易创建SSH

LS-LINUX-002 简易创建SSH 1. CentOS 8 创建和配置SSH服务 1.1 安装SSH服务 CentOS 8 默认已经安装了OpenSSH服务。如果没有安装,可以使用以下命令安装: sudo dnf install -y openssh-server1.2 启动SSH服务 安装完成后,需要启动SSH服务…

计算机专业求职面试的常见题目分类整理

以下是计算机专业求职面试的常见题目分类整理,每个大类精选20道高频问题,结合参考内容进行解析与扩展,帮助系统化备考: 一、数据结构与算法 解释时间复杂度和空间复杂度 时间复杂度衡量算法执行时间随输入规模的增长趋势&#xf…

脚本启动 Java 程序

如果你想在后台启动一个 Java 程序,并在终端窗口中显示一个自定义的名字,可以通过编写一个简单的脚本来实现。以下是一个基于 Linux/macOS 的解决方案,使用 Bash 脚本启动 Java 程序,并在终端窗口中显示自定义标题。 示例脚本 创建…

CentOS禁用nouveau驱动

1、验证 nouveau 是否在运行 lsmod | grep nouveau如果命令返回结果,说明 nouveau 驱动正在运行。 2、编辑黑名单文件 通过编辑黑名单配置文件来禁用 nouveau 驱动,这样在系统启动时不会加载它。 vi /etc/modprobe.d/blacklist-nouveau.conf修改以下…

Linux: network: tcpdump: packets dropped by kernel

文章目录 最近遇到一个问题原因libpcap/tcpdump 接口linux/libpcap 接口内核的处理原因可能有以下几种:解决方法:man pcap_stats最近遇到一个问题 tcpdump命令显示有dropped的包,而且是被内核drop的。 [root@-one-01 ~]# tcpdump -i any udp and port 8080 -v -w /root/udp…

WEB安全--提权思路

一、情形 在我们成功上传webshell到服务器中并拿到权限时,发现我们的权限很低无法执行特定的命令,这时为了能做更多的操作,我们就需要提升权限。 二、方式 2.1、Windows提权 1、普通用户执行systeminfo命令获取服务器的基本信息&#xff0…

001 vue

https://cn.vuejs.org/ 文章目录 v-bindv-modelv-on修饰符条件渲染/控制:v-if v-show列表渲染 M:即Model,模型,包括数据和一些基本操作 V:即View,视图,页面渲染结果 VM:即View-Mode…

Tomcat 负载均衡

目录 二、Tomcat Web Server 2.1 Tomcat 部署 2.1.1 Tomcat 介绍 2.1.2 Tomcat 安装 2.2 Tomcat 服务管理 2.2.1 Tomcat 启停 2.2.2 目录说明 2.2.3编辑主页 2.3 Tomcat管理控制台 2.3.1开启远程管理 2.3.2 配置远程管理密码 三、负载均衡 3.1 重新编译Nginx 3.1.1 确…

使用SpringSecurity下,发生重定向异常

使用SpringSecurity下,发生空转异常 环境信息: Spring Boot 3.4.4 , jdk 17 , springSecurity 6.4.4 问题背景: 没有自定义controller ,改写了login 页面,并且进行了成功后的跳转处理&#xf…

S130N-ISI 全栈方案与云平台深度协同:重构 PLC 开发新范式

一、什么是 PLC? 1.技术定义 PLC(Power Line Communication)是一种创新的通信技术,它以电力线作为天然的传输介质,通过先进的信号调制技术将高频数据信号叠加于工频电流之上,实现电力输送与数据通信的双频共…

SU-YOLO:基于脉冲神经网络的高效水下目标检测模型解析

论文地址:https://arxiv.org/pdf/2503.24389 目录 一、论文概述 二、创新点解析 1. 基于脉冲的水下图像去噪(SpikeDenoiser) 原理与结构 2. 分离批归一化(SeBN) 原理与结构 3. 优化的残差块(SU-Block) 原理与结构 三、代码复现指南 环境配置 模型训练 四、…

实现阿里云服务器上的文字聊天程序以及C语言写的进程间通信(IPC)程序

实现阿里云服务器上的文字聊天程序以及C语言写的进程间通信(IPC)程序 1. 基于 Linux 中的管道进行进程间通信 我们首先使用管道进行进程间通信,这对于简单的聊天程序来说是一个比较简单且实用的方法。 步骤: 创建管道&#xf…

COMSOL 与人工智能融合的多物理场应用:28个案例的思路、方法与工具概述

应用案例概述 基于 COMSOL 与人工智能(AI)结合的应用案例涵盖了 28 个多领域场景,包括工程(如热传导优化、结构力学预测)、能源(如电池热管理、燃料电池性能)、生物医学(如药物传递…

SAN及其ZONE

目录 一、什么是SAN? 二、什么是ZONE? 三、配置ZONE 2.1 核心概念 2.2 划分原则 2.3 Zone划分最佳实践 2.4 配置语法 1). 基于端口(Domain,Port)的zone语法 2). 基于WWN(World Wide Name)的Zone语法 3). 使用Alias简化配置 4).…

Springboot框架—单元测试操作

Springboot单元测试的操作步骤: 1.添加依赖spring-boot-starter-test 在pom.xml中添加依赖spring-boot-starter-test 2.在src/test/java下新建java class 3.单元测试入口代码结构 import org.junit.Test; import org.junit.runner.RunWith; import org.springfra…

用AbortController取消事件绑定

视频教程 React - 🤔 Abort Controller 到底是什么神仙玩意?看完这个视频你就明白了!💡_哔哩哔哩_bilibili AbortController的好处之一是事件绑定的函数已无需具名函数,匿名函数也可以被取消事件绑定了 //该代码2秒后点击失效…

JavaScript性能优化(上)

1. 减少 DOM 操作 减少 DOM 操作是优化 JavaScript 性能的重要方法,因为频繁的 DOM 操作会导致浏览器重绘和重排,从而影响性能。以下是一些具体的策略和技术,可以帮助有效减少 DOM 操作: 1.1. 批量更新 DOM 亲切与母体&#xff…

OpenCV 图形API(14)用于执行矩阵(或图像)与一个标量值的逐元素乘法操作函数mulC()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 描述 将矩阵与标量相乘。 mulC 函数将给定矩阵 src 的每个元素乘以一个给定的标量值: dst ( I ) saturate ( src1 ( I ) ⋅ multiplier ) \…

持续集成与Jenkins安装使用教程

一、持续集成与Jenkins 持续集成(Continuous integration,简称CI)指的是,频繁地(一天多次)将代码集成到主干。 持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。 它的…

TIM定时器

一、TIM定时器 STM32高级定时器实战:PWM、捕获与死区控制详解-CSDN博客 玩转STM32_rivencode的博客-CSDN博客 二、相关函数 1.TIM_TimeBaseInitTypeDef结构体讲解 typedef struct {uint16_t TIM_Prescaler; // 预分频器,用于设置定时器计数频…