Python PyTorch张量(Tensor)详解与实践

目录

  • 前言
  • 张量 Tensor
  • 1. 张量的基本概念
  • 2. 创建张量
  • 从 Python 列表或 NumPy 数组
  • 生成特定形状的张量
  • 指定设备(CPU/GPU)
  • 指定数据类型(dtype)
  • 3. 张量的属性
  • 4. 张量的操作
  • 数学运算
  • 形状操作
  • 索引与切片
  • 广播机制(Broadcasting)
  • 5. 自动微分(Autograd)
  • 6. 与 NumPy 的互操作
  • 7. 张量的存储
  • 8. 其他方法
  • 1. `.item()` 方法
  • 2. `.tolist()` 方法
  • `.numpy()` 方法
  • `.data` 属性

  • 前言

    书接上回

    张量 Tensor

    PyTorch 中的 张量(Tensor) 是多维数组的核心数据结构,类似于 NumPy 的 ndarray,但具备 GPU 加速计算和自动微分(Autograd)的能力。


    1. 张量的基本概念

  • 定义:张量是 PyTorch 中表示多维数据的容器,可以看作是多维数组。
  • 0维张量:标量(Scalar),如 tensor(3.14)
  • 1维张量:向量(Vector),如 tensor([1, 2, 3])
  • 2维张量:矩阵(Matrix),如 tensor([[1, 2], [3, 4]])
  • 3维及以上:高维张量,如 tensor([[[1, 2], [3, 4]]])

  • 2. 创建张量

    PyTorch 提供了多种创建张量的方式:

    从 Python 列表或 NumPy 数组
    import torch
    import numpy as np
    
    # 从列表创建
    a = torch.tensor([1, 2, 3])          # 1维张量
    b = torch.tensor([[1, 2], [3, 4]])   # 2维张量
    
    # 从 NumPy 数组创建
    np_array = np.array([1, 2, 3])
    c = torch.from_numpy(np_array)       # 共享内存(修改一个会影响另一个)
    
    生成特定形状的张量
    # 全零张量
    zeros = torch.zeros(2, 3)            # 2行3列的全零矩阵
    
    # 全一张量
    ones = torch.ones(2, 3)              # 2行3列的全一矩阵
    
    # 随机张量(均匀分布)
    rand = torch.rand(2, 3)              # 0~1之间的随机数
    
    # 随机张量(正态分布)
    randn = torch.randn(2, 3)            # 均值为0,标准差为1
    
    # 等差序列
    arange = torch.arange(0, 10, 2)      # tensor([0, 2, 4, 6, 8])
    
    指定设备(CPU/GPU)
    # 将张量放在 GPU 上(需有可用 GPU)
    if torch.cuda.is_available():
        gpu_tensor = torch.tensor([1, 2, 3], device="cuda:0")
    
    指定数据类型(dtype)
    # 指定数据类型为 float32
    float_tensor = torch.tensor([1, 2, 3], dtype=torch.float32)
    

    3. 张量的属性

    每个张量有三个核心属性:

    1. shape:张量的维度形状。
      x = torch.rand(2, 3)
      print(x.shape)  # 输出 torch.Size([2, 3])
      
    2. dtype:张量的数据类型(如 float32, int64 等)。
      print(x.dtype)  # 输出 torch.float32
      
    3. device:张量所在的设备(CPU 或 GPU)。
      print(x.device) # 输出 cpu 或 cuda:0
      

    4. 张量的操作

    数学运算
    a = torch.tensor([1, 2, 3])
    b = torch.tensor([4, 5, 6])
    
    # 加法
    c = a + b          # 或 torch.add(a, b)
    
    # 乘法(逐元素相乘)
    d = a * b          # tensor([4, 10, 18])
    
    # 矩阵乘法
    mat1 = torch.rand(2, 3)
    mat2 = torch.rand(3, 2)
    matmul = torch.matmul(mat1, mat2)  # 或 mat1 @ mat2
    
    形状操作
    x = torch.rand(2, 3)
    
    # 改变形状(不改变数据)
    y = x.view(3, 2)      # 变为3行2列(需保证元素总数一致)
    
    # 转置
    z = x.T               # 行变列,列变行
    
    # 增加/减少维度
    x = torch.unsqueeze(x, dim=0)  # 在第0维增加一维,形状变为 [1, 2, 3]
    x = torch.squeeze(x)           # 删除所有长度为1的维度
    
    索引与切片

    与 NumPy 类似:

    x = torch.tensor([[1, 2, 3], [4, 5, 6]])
    
    print(x[0, 1])     # 输出 2(第0行第1列)
    print(x[:, 1:3])   # 输出所有行的第1到2列
    
    广播机制(Broadcasting)

    PyTorch 支持自动广播,允许不同形状的张量进行运算:

    a = torch.tensor([[1, 2, 3]])  # 形状 [1, 3]
    b = torch.tensor([4, 5, 6])    # 形状 [3]
    c = a + b                      # 自动广播为 [1,3] + [3] → [1,3] + [1,3]
    

    5. 自动微分(Autograd)

    PyTorch 张量支持自动微分(通过 requires_grad=True):

    x = torch.tensor([2.0], requires_grad=True)
    y = x ** 2 + 3 * x + 1
    
    y.backward()        # 计算梯度
    print(x.grad)       # 输出导数 dy/dx = 2x + 3 → 7.0
    

    6. 与 NumPy 的互操作

    张量和 NumPy 数组可以互相转换:

    # 张量 → NumPy 数组
    tensor = torch.tensor([1, 2, 3])
    numpy_array = tensor.numpy()         # 共享内存
    
    # NumPy 数组 → 张量
    new_tensor = torch.from_numpy(numpy_array)
    

    7. 张量的存储

    张量的底层数据存储在连续的内存块中,可以通过 storage() 访问:

    x = torch.tensor([[1, 2], [3, 4]])
    print(x.storage())  # 输出底层存储的1D数组 [1, 2, 3, 4]
    

    你提到的 .item().tolist() 是 PyTorch 张量中常用的方法,用于将张量转换为 Python 原生的数据类型(如标量或列表)。以下是它们的详细说明和典型应用场景:


    8. 其他方法

    1. .item() 方法
  • 作用
    单元素张量(即形状为 [][1] 的张量)转换为 Python 的标量(int, float, bool 等)。

  • 适用场景
    当张量中只包含一个数值时,提取该数值(例如计算损失值后提取标量结果)。

  • 示例

    import torch
    
    # 标量张量(0维)
    x = torch.tensor(3.14)
    print(x.item())  # 输出 3.14(Python float)
    
    # 单元素张量(1维)
    y = torch.tensor([5])
    print(y.item())  # 输出 5(Python int)
    
  • 注意事项

  • 如果张量包含多个元素,调用 .item() 会报错:
    z = torch.tensor([1, 2])
    # z.item()  # 报错:ValueError: only one element tensors can be converted to Python scalars
    
  • 2. .tolist() 方法
  • 作用
    将张量转换为 Python 列表(多维张量会转换为嵌套列表)。
    所有元素会被转换为 Python 的原生数据类型(如 int, float)。

  • 适用场景
    需要将张量数据导出为 Python 原生结构(例如保存到 JSON 文件,或与其他非 PyTorch 库交互)。

  • 示例

    # 1维张量 → 列表
    a = torch.tensor([1, 2, 3])
    print(a.tolist())  # 输出 [1, 2, 3]
    
    # 2维张量 → 嵌套列表
    b = torch.tensor([[1, 2], [3, 4]])
    print(b.tolist())  # 输出 [[1, 2], [3, 4]]
    
    # 包含浮点数的张量
    c = torch.tensor([1.5, 2.7])
    print(c.tolist())  # 输出 [1.5, 2.7]
    
  • 注意事项

  • 转换后的列表与原张量 不共享内存
  • 支持任意维度的张量(会生成嵌套列表)。
  • .numpy() 方法
  • 作用:将张量转换为 NumPy 数组(与原张量共享内存)。
  • 示例
    x = torch.tensor([1, 2, 3])
    np_array = x.numpy()  # 转换为 NumPy 数组
    
  • 注意:如果张量在 GPU 上,需要先移动到 CPU:
    x = x.cpu().numpy()
    
  • .data 属性
  • 作用:获取张量的数据(返回一个无梯度的新张量)。
  • 示例
    x = torch.tensor([1.0], requires_grad=True)
    y = x.data  # y 是普通张量,无梯度信息
    
  • 作者:Python虫

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python PyTorch张量(Tensor)详解与实践

    发表回复