前言
张量(Tensor)是PyTorch的核心数据结构,掌握其高频操作是入门PyTorch的关键。本文精选10个最常用的张量操作,按「运算、索引切片、设备迁移」三大类整理,所有代码均可直接运行,结果直观易懂。
一、张量运算(3 个核心操作)
1. 算术运算(加减乘除)
PyTorch张量支持直观的算术运算,可直接用运算符(+、-、*、/)或对应函数,运算规则与NumPy类似。
import torch # 初始化两个张量 a = torch.tensor([1, 2, 3]) b = torch.tensor([4, 5, 6]) # 算术运算 add = a + b # 加法 sub = a - b # 减法 mul = a * b # 乘法(元素级) div = a / b # 除法(元素级) print("加法结果:", add) print("减法结果:", sub) print("乘法结果:", mul) print("除法结果:", div)运行结果:
加法结果: tensor([5, 7, 9]) 减法结果: tensor([-3, -3, -3]) 乘法结果: tensor([ 4, 10, 18]) 除法结果: tensor([0.2500, 0.4000, 0.5000])2. 矩阵乘法(torch.matmul)
矩阵乘法是深度学习核心运算(如神经网络全连接层),需注意张量维度匹配,torch.matul支持标量、向量、矩阵的乘法,兼容性优于torch.mm。
# 二维矩阵乘法(核心场景) x = torch.tensor([[1, 2], [3, 4]]) # 2×2 y = torch.tensor([[5, 6], [7, 8]]) # 2×2 matmul_2d = torch.matmul(x, y) # 向量×矩阵(广播兼容) vec = torch.tensor([1, 2]) # 1×2 matmul_vec_mat = torch.matmul(vec, x) print("二维矩阵乘法:\n", matmul_2d) print("向量×矩阵:", matmul_vec_mat)运行结果:
二维矩阵乘法: tensor([[19, 22], [43, 50]]) 向量×矩阵: tensor([ 7, 10])3. 广播机制
当两个张量维度不同时,PyTorch会自动扩展维度较小的张量(不复制数据),使其匹配维度较大的张量,这就是广播,是简化运算的核心机制。
# 示例1:一维张量(3,)与标量()广播 c = torch.tensor([1, 2, 3]) scalar = torch.tensor(5) broadcast1 = c + scalar # 示例2:二维张量(2,3)与一维张量(3,)广播 d = torch.tensor([[1, 2, 3], [4, 5, 6]]) e = torch.tensor([10, 20, 30]) broadcast2 = d + e print("标量广播结果:", broadcast1) print("维度扩展广播结果:\n", broadcast2)运行结果:
标量广播结果: tensor([6, 7, 8]) 维度扩展广播结果: tensor([[11, 22, 33], [14, 25, 36]])二、索引与切片(3 个核心操作)
1. 普通索引
与Python列表、NumPy数组索引规则一致,通过「维度下标」取值,支持单元素、连续区间索引。
# 初始化3维张量(2×3×4) tensor = torch.arange(24).reshape(2, 3, 4) print("原始张量:\n", tensor) # 普通索引:取第0个维度、第1行、第2列的元素 single_elem = tensor[0, 1, 2] # 切片:取第1个维度的所有行,第0-2列(左闭右开) slice_part = tensor[1, :, 0:2] print("单元素索引结果:", single_elem) print("切片结果:\n", slice_part)运行结果:
原始张量: tensor([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]) 单元素索引结果: tensor(6) 切片结果: tensor([[12, 13], [16, 17], [20, 21]])2. 高级索引
通过「索引张量」取不连续的元素,索引张量需为torch.long类型,适用于随机取值场景。
# 初始化2维张量 t = torch.tensor([[1, 2], [3, 4], [5, 6]]) print("原始张量:\n", t) # 高级索引:取第0行第1列、第2行第0列的元素 row_idx = torch.tensor([0, 2]) # 行索引 col_idx = torch.tensor([1, 0]) # 列索引 advanced_idx = t[row_idx, col_idx] print("高级索引结果:", advanced_idx)运行结果:
原始张量: tensor([[1, 2], [3, 4], [5, 6]]) 高级索引结果: tensor([2, 5])3. 掩码索引
通过布尔张量(掩码)筛选满足条件的元素,是深度学习中筛选数据的常用方式(如过滤无效值)。
# 初始化张量 mask_tensor = torch.tensor([10, 2, 15, 3, 20]) print("原始张量:", mask_tensor) # 生成掩码:筛选大于5的元素 mask = mask_tensor > 5 # 掩码索引取值 masked_result = mask_tensor[mask] print("掩码(布尔张量):", mask) print("掩码索引结果:", masked_result)运行结果:
原始张量: tensor([10, 2, 15, 3, 20]) 掩码(布尔张量): tensor([ True, False, True, False, True]) 掩码索引结果: tensor([10, 15, 20])三、张量设备迁移(4 个核心操作)
PyTorch张量可在CPU和GPU之间迁移,核心用to()方法,需先确认GPU可用(无GPU则自动用CPU)。
# 1. 初始化CPU张量 cpu_tensor = torch.tensor([1, 2, 3]) print("初始设备:", cpu_tensor.device) # 2. CPU → GPU(若有GPU) if torch.cuda.is_available(): gpu_tensor = cpu_tensor.to("cuda") # 等价于 to(torch.device("cuda")) print("GPU设备:", gpu_tensor.device) # 3. GPU → CPU back_to_cpu = gpu_tensor.to("cpu") print("迁回CPU设备:", back_to_cpu.device) # 4. 直接指定设备编号(多GPU场景) gpu1_tensor = cpu_tensor.to("cuda:0") print("指定GPU编号设备:", gpu1_tensor.device) else: print("无可用GPU,仅演示CPU张量")运行结果(有GPU):
初始设备: cpu GPU设备: cuda:0 迁回CPU设备: cpu 指定GPU编号设备: cuda:0运行结果(无GPU):
初始设备: cpu 无可用GPU,仅演示CPU张量总结
张量运算:算术运算为元素级,torch.matmul是矩阵乘法核心,广播机制可自动扩展维度匹配运算;
索引切片:普通索引对标列表操作,高级索引取不连续元素,掩码索引通过布尔张量筛选数据;
设备迁移:to()方法是核心,通过指定"CPU"/"cuda"实现张量在CPU/GPU间迁移,需先判断GPU可用性。