0%

张量

张量

张量(Tensor)是深度学习中最基本的数据结构,你可以把它理解为一个多维数组。在 Python 中,我们通常使用 PyTorch 或 TensorFlow 等库来操作张量。

下面将以 PyTorch 为例,介绍张量的核心概念和常用操作。

什么是张量?

张量是标量、向量、矩阵的泛化,是 AI 中统一的数据格式。它的“阶”(Rank)或“维度”(Dimensions)决定了它的结构。

阶 (Rank) 名称 示例 形状 (Shape)
0 标量 (Scalar) 一个数字,如 5 ()
1 向量 (Vector) 一维数组,如 [1, 2, 3] (3,)
2 矩阵 (Matrix) 二维表格,如 [[1, 2], [3, 4]] (2, 2)
3 3阶张量 三维数组,如一张彩色图片 (高, 宽, 通道) (224, 224, 3)
n n阶张量 n维数组,如一批图片 (批次, 高, 宽, 通道) (32, 224, 224, 3)

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

  • 形状 (shape): 描述张量在每个维度上的大小。
  • 数据类型 (dtype): 张量中元素的类型,如 torch.float32
  • 设备 (device): 张量存储的位置,如 CPU 或 GPU。

Python中的张量操作 (基于PyTorch)

1. 创建张量

有多种方式可以创建张量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import torch
import numpy as np

# 1. 从Python列表创建
tensor_from_list = torch.tensor([1, 2, 3, 4])

# 2. 从NumPy数组创建 (注意:两者共享内存)
np_array = np.array([1, 2, 3])
tensor_from_numpy = torch.from_numpy(np_array)

# 3. 创建特殊值的张量
zeros_tensor = torch.zeros(2, 3) # 创建一个2x3的全0张量
ones_tensor = torch.ones(2, 3) # 创建一个2x3的全1张量
rand_tensor = torch.rand(2, 3) # 创建一个2x3的[0,1)均匀分布随机张量
randn_tensor = torch.randn(2, 3) # 创建一个2x3的标准正态分布随机张量

# 4. 创建序列张量
arange_tensor = torch.arange(0, 10, 2) # 创建 [0, 2, 4, 6, 8]

2. 查看和修改属性

1
2
3
4
5
tensor = torch.rand(3, 4)

print(f"形状: {tensor.shape}") # 输出: torch.Size([3, 4])
print(f"数据类型: {tensor.dtype}") # 输出: torch.float32
print(f"设备: {tensor.device}") # 输出: cpu

3. 索引与切片

与 NumPy 的语法非常相似。

1
2
3
4
5
6
7
8
9
10
11
tensor = torch.arange(24).reshape(4, 6) # 创建一个4x6的张量

# 获取第一行
first_row = tensor[0]
# 获取第一列
first_col = tensor[:, 0]
# 获取子矩阵
sub_matrix = tensor[1:3, 2:4]
# 使用布尔掩码
mask = tensor > 10
selected_elements = tensor[mask]

4. 维度变换

这是深度学习数据预处理中非常关键的一步。

  • reshape() / view(): 改变张量的形状,但元素总数不变。view() 要求张量在内存中是连续的,而 reshape()更灵活。

    1
    2
    3
    4
    5
    6
    7
    # 创建序列张量
    tensor_seq = torch.arange(0, 10, 2) # 创建从0到10,步长为2的序列张量 也就是[0, 2, 4, 6, 8]
    # torch.Size([5])
    print(f"形状: {tensor_seq.shape}")
    re_tensor = tensor_seq.reshape(5,1) # 将张量重新形状为1*5
    # torch.Size([5, 1]) 注意总数量是不变的
    print(f"形状: {re_tensor.shape}")
  • squeeze() / unsqueeze(): 移除或增加大小为1的维度。

    1
    2
    3
    a = torch.tensor() # 形状: (1, 2)
    b = torch.squeeze(a) # 形状: (2,)
    c = torch.unsqueeze(b, 0) # 形状: (1, 2) 第二个参数dim为0,表示在0维度上添加一个维度
  • transpose() / permute(): 交换或重排维度。

    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
    # 矩阵转置
    matrix = torch.tensor([[1, 2], [3, 4]])
    # tensor([1, 2])
    print(f"第一行: {matrix[0]}")
    transposed = matrix.t() # 或 torch.transpose(matrix, 0, 1)
    # tensor([1, 3])
    print(f"第一行: {transposed[0]}")

    # 多维张量维度重排,例如从 (Batch, Height, Width, Channel) 变为 (Batch, Channel, Height, Width)
    data = torch.randn(2, 3, 4)
    # torch.Size([2, 3, 4])
    print(f"形状: {data.shape}")
    data_permuted = data.permute(2, 0, 1)
    # torch.Size([4, 2, 3])
    # 新张量的第 1 个维度(最左边),请放入原张量的 第 2 维。
    # 原第 2 维的大小是 4
    # →
    # → 所以新形状的第 1 位是 4。
    # 新张量的第 2 个维度(中间),请放入原张量的 第 0 维。
    # 原第 0 维的大小是 2
    # →
    # → 所以新形状的第 2 位是 2。
    # 新张量的第 3 个维度(最右边),请放入原张量的 第 1 维。
    # 原第 1 维的大小是 3
    # →
    # → 所以新形状的第 3 位是 3
    print(f"形状: {data_permuted.shape}")

5. 张量运算

  • 基本运算: 加减乘除等是逐元素(element-wise)进行的。

    1
    2
    3
    4
    a = torch.tensor([1, 2, 3])
    b = torch.tensor([4, 5, 6])
    c = a + b # 结果: [5, 7, 9]
    d = a * b # 点乘运算,逐元素乘法(同位置进行相乘), 结果: [4, 10, 18]
  • 矩阵乘法: 使用 @ 运算符或 torch.matmul() 函数。

    A矩阵的每一行与B矩阵的每一列进行相乘然后进行累加

    1
      
1
2
3
4
5
6
7
matrix_a = torch.rand(2, 3)
matrix_b = torch.rand(3, 2)
# 内积消除法
# 中间必须相等:A 的列数(n)必须等于 B 的行数(n)。这是乘法能够进行的前提条件
# 公式:(m, n) × (n, p) → (m, p) 中间相同被消去,留下两头做结果
result = matrix_a @ matrix_b # 结果形状: (2, 2)
print(result.shape)
  • 聚合操作: 对张量进行求和、求均值等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    tensor = torch.tensor([1.0, 2.0, 3.0])
    # 求和
    sum_val = tensor.sum() # 结果: 6.0
    # 平均值
    mean_val = tensor.mean() # 结果: 2.0
    # n次方
    torch.pow(tensor,n)
    # 平方根
    tensor.sqrt()
    # 指数
    tensor.exp()
    # 对数
    tensor.log()

6. 设备间移动 (CPU/GPU)

为了利用 GPU 加速计算,可以将张量移动到 GPU 上。

1
2
3
4
5
6
7
# 检查CUDA是否可用
if torch.cuda.is_available():
device = torch.device("cuda")
# 将张量移动到GPU
gpu_tensor = tensor.to(device)
# 移回CPU
cpu_tensor = gpu_tensor.cpu()

欢迎关注我的其它发布渠道