@0xkozue: https://x.com/0xkozue/status/2072607035624247732
摘要
一份简洁的一页速查表,涵盖PyTorch张量、模型、矩阵乘法以及用于深度学习训练流程的自动求导。
查看缓存全文
缓存时间: 2026/07/02 14:23
你的单页 PyTorch 训练管道速查表。
深度学习整个引擎的工作方式是对模型权重进行微小的、连续的调整。这是我整理的 PyTorch 训练管道速查表。如果你发现任何错误或有改进建议,欢迎留言。希望对你有帮助!
1. 张量 (Tensor)
在 PyTorch 中,张量 是用于存储和操作数值数据的基本数据结构,是神经网络的构建基石。
输入:
data = [[1,2,3],[4,5,6]]
x = torch.tensor(data)
输出:
tensor([[1, 2, 3],
[4, 5, 6]])
问:张量内部包含什么?
三个东西:形状 (Shape)、数据类型 (DType) 和 设备 (Device)。
- 形状 (Shape): 描述维度的元组(PyTorch 中 90% 的错误都是形状不匹配)
- 数据类型 (Dtype): 数字的数据类型
- 设备 (Device): 张量所在的位置:CPU 或 CUDA(GPU)
如果你的代码出错,通常是因为这三个中的某一个不匹配。
输入:
# 张量的属性
tensor = torch.randn(2,3)
print("shape:", tensor.shape)
print("datatype:", tensor.dtype)
print("device:", tensor.device)
输出:
shape: torch.Size([2, 3])
datatype: torch.float32
device: cpu
默认情况下,张量只是数据。要让它成为可学习的参数,需要设置 requires_grad=True。一旦启用,PyTorch 就会开始构建计算图,记录对该张量执行的每一个操作,以便在反向传播时自动计算梯度。
输入:
# 数据 vs 参数
# 标准数据张量
x_data = torch.tensor([[1.,2.],[3.,4.]])
# 参数张量
w = torch.tensor([[1.0],[2.0]], requires_grad=True)
print("Data tensor requires_grad:", x_data.requires_grad)
print("Parameter tensor requires_grad:", w.requires_grad)
输出:
Data tensor requires_grad: False
Parameter tensor requires_grad: True
问:什么是参数?
一种特殊的张量,默认requires_grad = True,会自动注册到模型中,并处理所有记账工作。
2. 模型
模型是一个神经网络架构,定义为继承自 torch.nn.Module 基类的 Python 对象。
- 模型就是一个包含多个层的
nn.Module - 层就是包含参数并执行数学运算的容器
- 学习就是通过
zero_grad、backward、step更新参数 - 模型参数(权重、偏置)必须是浮点类型(float32)
问:为什么用 float32?
权重需要以极小的量变化。整数无法做到这一点。浮点数允许模型在每次迭代中做出微小的改进。
最简单的神经网络是 y = X @ W + b,其中:
- y → 预测值
- X → 输入
- W → 权重
- b → 偏置
预测 = 输入 × 知识 + 调整
3. 矩阵乘法
X @ W
这是深度学习的核心。几乎所有现代神经网络都是由重复的矩阵乘法构建而成。在构建线性层时使用 @ 运算符。在 PyTorch 中,@ 执行矩阵乘法,这是每一个 nn.Linear 层背后的核心操作。
规则:M1 的列数 = M2 的行数
输入:
# 矩阵乘法
# 形状 (2,3)
m1 = torch.tensor([[1,2,3],
[4,5,6]])
# 形状 (3,2)
m2 = torch.tensor([[7,8],
[9,10],
[11,12]])
# 形状 (2,2)
matrix_product = m1 @ m2
print(matrix_product)
输出:
tensor([[ 58, 64],
[139, 154]])
不要混淆 ‘@’ 和 ‘*’ …
@执行矩阵乘法,而*将对应元素逐一相乘。
4. 自动微分 (Autograd)
torch.autograd 是 PyTorch 的自动微分引擎,为神经网络训练提供动力。它在前向传播过程中动态构建一个有向无环图(DAG)来跟踪张量操作,让你能够通过反向传播自动计算梯度。
自动梯度告诉:“从损失出发回溯,并为所有 requires_grad=True 的参数计算梯度。”
输入:
# y = 2x + 1
# 一批数据有10个点
N = 10
# 每个数据点有1个输入特征和1个输出值
D_in = 1
D_out = 1
# 创建输入数据 X
X = torch.randn(N, D_in)
# 使用“真实”的 W, b 创建真实的目标标签 y
# “真实” W = 2.0,“真实” b = 1.0
true_w = torch.tensor([[2.0]])
true_b = torch.tensor([[1.0]])
y_true = X @ true_w + true_b + torch.randn(N, D_out) * 1.0 # 加入一点噪声
W = torch.randn(D_in, D_out, requires_grad=True)
b = torch.randn(1, requires_grad=True)
print("初始权重 W:\n", W)
print("初始偏置 b:\n", b)
y_hat = X @ W + b
print(y_hat)
# 误差
error = y_hat - y_true
squared_error = error ** 2
loss = squared_error.mean()
print("Loss:", loss, "\n")
loss.backward()
print("w 的梯度:\n", W.grad)
print("b 的梯度:\n", b.grad)
输出:
初始权重 W:
tensor([[-0.5669]], requires_grad=True)
初始偏置 b:
tensor([0.0011], requires_grad=True)
tensor([[ 0.0604],
[ 0.5645],
[ 0.6193],
[-0.2863],
[ 1.2082],
[ 0.6468],
[ 0.5936],
[-0.2940],
[ 0.6108],
[ 0.8328]], grad_fn=<AddBackward0>)
Loss: tensor(6.5599, grad_fn=<MeanBackward0>)
w 的梯度:
tensor([[-5.0230]])
b 的梯度:
tensor([1.8041])
5. 反向传播 (反向传递)
loss.backward()
- ∂L/∂w = 损失相对于权重 w 的梯度
- ∂L/∂b = 损失相对于偏置 b 的梯度
通过 loss.backward() 自动计算。
6. 梯度下降 (优化)
计算梯度后,我们更新模型参数以减少损失。更新规则为:
θt+1 = θt - η ∇θL
其中:
- θ (theta) = 模型参数(权重和偏置)
- η (eta) = 学习率
- ∇θL = 损失相对于参数的梯度(w.grad, b.grad)
新权重 = 旧权重 - 学习率 × 梯度
输入:
# 训练(梯度下降)
# 超参数
learning_rate, epochs = 0.01, 100
# 重新初始化参数
W, b = torch.randn(1,1, requires_grad=True), torch.randn(1, requires_grad=True)
# 训练循环
for epoch in range(epochs):
# 前向传播和损失
y_hat = X @ W + b
loss = torch.mean((y_hat - y_true)**2)
# 反向传播
loss.backward()
# 更新参数
with torch.no_grad():
W -= learning_rate * W.grad
b -= learning_rate * b.grad
# 梯度清零(为新的学习周期重置)
W.grad.zero_()
b.grad.zero_()
print(W.grad, "\n", b.grad)
7. nn.Module
不必手动编写所有内容,PyTorch 提供了:
nn.Linearnn.ReLUnn.GELUnn.Softmaxnn.Embeddingnn.LayerNormnn.Dropout
这些都是可复用的构建块。
输入:
# NN.LINEAR
# 输入有1个特征,输出有1个值
D_in = 1
D_out = 1
linear_layer = torch.nn.Linear(in_features=D_in, out_features=D_out)
print("层的权重 (W):", linear_layer.weight)
print("层的偏置 (b):", linear_layer.bias)
# 前向传播
y_hat_nn = linear_layer(X)
print("nn.Linear 的输出(前3个):\n", y_hat_nn[:3])
输出:
层的权重 (W): Parameter containing:
tensor([[0.5193]], requires_grad=True)
层的偏置 (b): Parameter containing:
tensor([-0.2911], requires_grad=True)
nn.Linear 的输出(前3个):
tensor([[-0.3454],
[-0.8072],
[-0.8574]], grad_fn=<SliceBackward0>)
输入:
# NN.RELU (修正线性单元)
# 规则:如果输入为负,将其置为0。ReLU(x) = max(0, x)
relu = torch.nn.ReLU()
sample_data = torch.tensor([-2.0, -5.0, 0.0, 0.5, 2.0])
activated_data = relu(sample_data)
print("原始数据:", sample_data)
print("ReLU 后的数据:", activated_data)
输出:
原始数据: tensor([-2.0000, -5.0000, 0.0000, 0.5000, 2.0000])
ReLU 后的数据: tensor([0.0000, 0.0000, 0.0000, 0.5000, 2.0000])
输入:
# NN.GELU (高斯误差线性单元)
# 现代 Transformer 的标准 (GPT, Llama)。比 ReLU 更平滑、温和弯曲的版本
gelu = torch.nn.GELU()
sample_data = torch.tensor([-2.0, -0.5, 0.0, 0.5, 2.0])
activated_data = gelu(sample_data)
print("原始数据:", sample_data)
print("GELU 后的数据:", activated_data)
输出:
原始数据: tensor([-2.0000, -0.5000, 0.0000, 0.5000, 2.0000])
GELU 后的数据: tensor([-0.0455, -0.1543, 0.0000, 0.3457, 1.9545])
输入:
# NN.SOFTMAX
# 用于分类任务的最终输出层
# 将 logits 转换为概率分布
softmax = torch.nn.Softmax(dim=-1)
logits = torch.tensor([[1.0, 3.0, 0.5, 1.5],
[-1.0, 2.0, 1.0, 0.0]])
prob = softmax(logits)
print("输出概率:", prob)
print("概率之和:", prob[0].sum())
输出:
输出概率: tensor([[0.0939, 0.6942, 0.0570, 0.1549],
[0.0321, 0.6439, 0.2369, 0.0871]])
概率之和: tensor(1.)
输入:
# NN.EMBEDDING
# 将单词转换为数字
vocab_size = 10
embedding_dim = 3
embedding_layer = torch.nn.Embedding(vocab_size, embedding_dim)
input_ids = torch.tensor([[1, 5, 0, 8]])
word_vector = embedding_layer(input_ids)
word_vector
输出:
tensor([[[-0.3875, -1.7026, -0.8399],
[-0.3027, -0.0060, 0.7160],
[-2.0736, 0.3490, -0.0605],
[ 1.3206, 0.8779, 0.4340]]], grad_fn=<EmbeddingBackward0>)
输入:
# nn.LayerNorm
# 防止值爆炸/消失,将其重新缩放到稳定范围
norm_layer = torch.nn.LayerNorm(normalized_shape=3)
input_features = torch.tensor([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]])
normalized_features = norm_layer(input_features)
print("均值(应约为0):", normalized_features.mean(dim=-1))
print("标准差(应约为1):", normalized_features.std(dim=-1))
输出:
均值(应约为0): tensor([0., 0.], grad_fn=<MeanBackward1>)
标准差(应约为1): tensor([1.2247, 1.2247], grad_fn=<StdBackward0>)
输入:
# NN.DROPOUT
# 防止过拟合,训练时随机将神经元置零,强制网络具备鲁棒性
dropout_layer = torch.nn.Dropout(p=0.5)
input_tensor = torch.ones(1, 10)
dropout_layer.train()
output_during_train = dropout_layer(input_tensor)
dropout_layer.eval()
output_during_eval = dropout_layer(input_tensor)
8. 黄金三步
optimizer.zero_grad()loss.backward()optimizer.step()
9. 演示:玩具模型
import torch
import torch.nn as nn
print(torch.cuda.is_available())
class LinearRegressionModel(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
# 在构造函数中定义层
self.linear_layer = nn.Linear(in_features, out_features)
def forward(self, x):
# 在前向传播中连接层
return self.linear_layer(x)
model = LinearRegressionModel(in_features=1, out_features=1)
print("模型架构:")
print(model)
# 导入优化器
import torch.optim as optim
# 超参数
learning_rate = 0.01
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
loss_fn = nn.MSELoss()
epochs = 100
for epoch in range(epochs):
# 前向传播
y_hat = model(X)
loss = loss_fn(y_hat, y_true)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 10 == 0:
print("Epoch:", epoch, "Loss:", loss.item())
输出:
True
模型架构:
LinearRegressionModel(
(linear_layer): Linear(in_features=1, out_features=1, bias=True)
)
Epoch: 0 Loss: 11.082582473754883
Epoch: 10 Loss: 9.987239837646484
Epoch: 20 Loss: 8.982141494750977
Epoch: 30 Loss: 8.073999404907227
Epoch: 40 Loss: 7.263952732086182
Epoch: 50 Loss: 6.5487494468688965
Epoch: 60 Loss: 5.9224066734313965
Epoch: 70 Loss: 5.377523899078369
Epoch: 80 Loss: 4.90612268447876
Epoch: 90 Loss: 4.500123500823975
希望这能帮助你更好地理解 PyTorch。祝你构建愉快!
相似文章
@ManningBooks: PyTorch 能带你走得很远,但当性能成为问题时,了解 GPU 层面的情况就至关重要…
为 Elliot Arledge 所著的《CUDA for Deep Learning》一书做的推广帖子,提供第一章总结视频,讲解 GPU 性能、CUDA 编程模型,以及何时需要编写自定义 CUDA 内核。
pytorch/pytorch
PyTorch 是一个开源深度学习框架,提供 GPU 加速的张量计算和基于 tape-based autograd 的动态神经网络。GitHub README 提供了安装说明、组件概览以及文档链接。
@_rohit_tiwari_: PyTorch 基础:动手深度学习的第一步。Github (900+ 星): https://github.com/analyticalr…
一个适合初学者的GitHub仓库,涵盖PyTorch基础,包括张量初始化、运算、索引和重塑,拥有超过900颗星。
@jino_rohit: https://x.com/jino_rohit/status/2071247775837356399
一篇博文,解释 PyTorch FX 图,这是 PyTorch 2.0 编译生态系统中使用的一种中间表示。它涵盖了核心对象 Graph、Node 和 GraphModule,以及如何理解和使用它们。
@loganthorneloe: 这是研读《Attention Is All You Need》的最佳方式。它通过……帮助你理解基础概念。
一条推文推荐《The Annotated Transformer》作为软件工程师的资源,通过用PyTorch构建来理解《Attention Is All You Need》论文的基础概念。