什么是 PyTorch 张量(Tensor)
在深度学习的世界里,数据的表示方式至关重要。你可能已经听说过“张量”这个词,听起来像是一个高深的数学概念,但其实它就是一种多维数组,是 PyTorch 中所有数据处理的基础单位。可以把它想象成一个“智能容器”,不仅能存放数字,还能记录这些数字之间的关系、计算历史,甚至支持自动求导。
在 PyTorch 中,张量(Tensor)是所有神经网络操作的核心。无论是图像、文本还是音频,最终都会被转换成张量的形式输入模型。理解张量,就是理解 PyTorch 的第一步。
比如,一个标量(单个数字)可以看作是 0 维张量,一个向量是 1 维张量,一个矩阵是 2 维张量,而更高维的数据(如彩色图像、视频序列)则对应 3 维、4 维甚至更高维的张量。
记住:PyTorch 张量(Tensor)不是简单的数组,它是带智能属性的数据容器。
创建数组与初始化
要使用 PyTorch 张量,第一步就是创建它。PyTorch 提供了多种方式来创建张量,从简单的数值到复杂的随机初始化都有支持。
import torch
tensor_1d = torch.tensor([1, 2, 3, 4, 5])
print(tensor_1d)
这段代码中,torch.tensor() 是最基础的创建方式。它接收一个 Python 列表,并将其转换为 PyTorch 张量。你也可以直接指定数据类型,比如 float32 或 int64:
float_tensor = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32)
print(float_tensor)
对于需要初始化大量随机数据的场景,PyTorch 提供了更高效的方式:
random_tensor = torch.rand(3, 4)
print(random_tensor)
如果你想要的是正态分布的随机数,可以用 torch.randn():
normal_tensor = torch.randn(2, 3)
print(normal_tensor)
| 函数 | 作用 | 示例 |
|---|---|---|
torch.tensor() |
从 Python 列表或数组创建张量 | torch.tensor([1, 2, 3]) |
torch.rand() |
生成 [0, 1) 区间内的均匀随机张量 | torch.rand(2, 3) |
torch.randn() |
生成标准正态分布随机张量 | torch.randn(1, 4) |
torch.zeros() |
创建全零张量 | torch.zeros(3, 2) |
torch.ones() |
创建全一张量 | torch.ones(2, 2) |
这些初始化方式在模型训练前非常关键,比如权重初始化就常用 torch.randn(),而偏置项则常用 torch.zeros()。
张量的维度与形状
理解张量的“形状”是使用 PyTorch 的核心。形状(shape)描述了张量在每个维度上的大小。
tensor_2d = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(f"张量形状: {tensor_2d.shape}")
这里的 torch.Size([2, 3]) 表示这个张量有 2 行 3 列。你可以把它想象成一个表格,行是第一个维度,列是第二个维度。
更复杂的例子:
tensor_3d = torch.rand(2, 3, 4)
print(f"3D 张量形状: {tensor_3d.shape}")
这就像两个 3 行 4 列的表格堆叠在一起,构成了一个三维结构。
你还可以通过 .view() 或 .reshape() 来改变张量的形状,但必须保证总元素数量不变:
original = torch.rand(2, 3, 4)
reshaped = original.view(6, 4)
print(f"重塑后形状: {reshaped.shape}")
注意:view() 要求张量在内存中是连续的,如果需要,可以用 .contiguous() 确保连续性。
张量的运算与广播机制
PyTorch 张量支持丰富的数学运算,包括加法、乘法、矩阵乘法等。这些操作可以像普通数组一样进行,但更智能。
a = torch.tensor([[1, 2], [3, 4]])
b = torch.tensor([[5, 6], [7, 8]])
add_result = a + b
print(add_result)
matmul_result = torch.mm(a, b)
print(matmul_result)
torch.mm() 是矩阵乘法,要求第一个张量的列数等于第二个张量的行数。
更高级的功能是广播机制(Broadcasting),它允许不同形状的张量进行运算。比如你可以把一个标量加到一个 2D 张量上:
scalar = torch.tensor(3.0)
matrix = torch.tensor([[1, 2], [3, 4]])
result = matrix + scalar
print(result)
这里 PyTorch 自动把标量扩展成和矩阵相同形状,再进行加法,这就是广播。
广播规则很简单:从右往左对齐维度,若某维度相同或其中一个为 1,则可以广播。这大大简化了代码,也提高了效率。
张量的设备与自动求导
在现代深度学习中,计算通常在 GPU 上进行,以加快速度。PyTorch 张量支持在 CPU 和 GPU 之间切换。
print(f"设备: {torch.device('cuda' if torch.cuda.is_available() else 'cpu')}")
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
tensor_gpu = torch.tensor([1.0, 2.0, 3.0], device=device)
print(tensor_gpu)
如果你没有 GPU,会自动使用 CPU。这让你的代码在不同硬件上都能运行。
另一个关键特性是自动求导(Autograd)。当你需要训练模型时,必须计算梯度。PyTorch 通过设置 requires_grad=True 来开启这一功能:
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2
y.backward()
print(f"x 的梯度: {x.grad}")
这个机制是训练神经网络的基础。每次前向传播后调用 .backward(),PyTorch 就会自动记录计算图,并计算出所有参数的梯度。
实际案例:从图像到张量
我们来看一个真实场景:处理一张图像。图像通常以 RGB 格式存储,即 3 个通道(红、绿、蓝),每个通道是一个二维矩阵。
image_tensor = torch.rand(3, 224, 224)
print(f"图像张量形状: {image_tensor.shape}")
normalized = (image_tensor - 0.5) * 2
print(f"归一化后范围: [{normalized.min():.2f}, {normalized.max():.2f}]")
在实际模型中,图像数据都会被转换为这样的张量格式,然后输入神经网络进行处理。
总结
PyTorch 张量(Tensor)是深度学习的基石。它不仅是数据的容器,更是计算的载体。从创建、初始化,到维度操作、数学运算,再到设备管理和自动求导,每一个环节都体现了它的强大与灵活。
对于初学者来说,理解张量的“形状”和“数据类型”是第一步;对于中级开发者,掌握广播机制、设备切换和自动求导则是进阶的关键。
记住:你写的每一个模型,本质上都是在操作张量。当你能熟练驾驭张量,你就真正掌握了 PyTorch 的核心。