PyTorch (torch)
1. 定义
PyTorch 是一个开源的深度学习框架(Meta 主导),用 Python 写神经网络、训练模型、跑推理。核心是张量 (Tensor) 计算 + 自动求导 (autograd) + GPU 加速。
包名就叫 torch,import torch。
类比:NumPy 是”能在 CPU 上算多维数组”,PyTorch 是”能在 GPU 上算、还能自动求梯度的 NumPy”——所以深度学习几乎都用它。
2. PyTorch 解决了什么问题
手写神经网络要自己算梯度、管 GPU 内存、写训练循环,工作量巨大且易错。PyTorch 把这些做成框架:
| 你要的 | 自己写 | PyTorch |
|---|---|---|
| 多维数组运算 | NumPy(只 CPU) | torch.Tensor(CPU/GPU 通用) |
| 求梯度(反向传播) | 手推链式法则 | autograd 自动算 |
| GPU 加速 | 手写 CUDA | .to("cuda") 一句话 |
| 搭网络 | 手撸矩阵 | torch.nn 现成层 |
| 优化器 | 手写 SGD/Adam | torch.optim 现成 |
3. 核心概念
| 概念 | 是什么 |
|---|---|
| Tensor(张量) | 多维数组,PyTorch 的基本数据结构,可放 CPU 或 GPU |
| autograd(自动求导) | 记录张量运算图,反向传播时自动算梯度 |
requires_grad | 张量属性,为 True 才会被追踪求梯度 |
nn.Module | 所有神经网络/层的基类,自定义模型继承它 |
| optimizer(优化器) | 根据梯度更新参数,如 SGD、Adam |
| loss(损失函数) | 衡量预测和真实值的差距,反向传播的起点 |
| device | 张量/模型所在的设备:"cpu" / "cuda"(GPU)/ "mps"(Apple 芯片) |
4. Tensor 基础(像 NumPy 但能上 GPU)
import torch
# 创建
x = torch.tensor([1.0, 2.0, 3.0])
z = torch.zeros(2, 3) # 2x3 全 0
r = torch.randn(2, 3) # 正态分布随机
# 运算(和 NumPy 几乎一样)
y = x * 2 + 1
m = r @ r.T # 矩阵乘
# 和 NumPy 互转
import numpy as np
arr = x.numpy() # tensor -> ndarray
t = torch.from_numpy(np.array([1, 2, 3])) # ndarray -> tensor
# 形状操作
r.shape # torch.Size([2, 3])
r.view(3, 2) # 改形状(reshape)
r.unsqueeze(0) # 加一维 -> (1, 2, 3)5. 设备管理(CPU / GPU / Apple MPS)
# 自动选设备(写代码的标准姿势)
device = (
"cuda" if torch.cuda.is_available() # NVIDIA GPU
else "mps" if torch.backends.mps.is_available() # Apple 芯片 GPU
else "cpu"
)
x = torch.randn(3, 3).to(device) # 把张量搬到设备
model = MyModel().to(device) # 模型也要搬
# 检查 GPU
torch.cuda.is_available() # 有没有可用的 CUDA GPU
torch.cuda.get_device_name(0) # GPU 型号关键铁律:参与运算的张量必须在同一设备。模型在 GPU、数据在 CPU 会直接报错
Expected all tensors to be on the same device。见cuda.md。
6. autograd 自动求导(PyTorch 的灵魂)
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x # y = x² + 3x
y.backward() # 反向传播,自动算 dy/dx
print(x.grad) # dy/dx = 2x + 3 = 7.0- 有
requires_grad=True的张量,运算会被记录成计算图 .backward()从结果反推,自动填好每个参数的.grad- 推理时用
with torch.no_grad():关掉追踪,省内存、加速
7. 一个最小训练循环(记住这个模板)
import torch
import torch.nn as nn
model = nn.Linear(10, 1).to(device) # 简单线性层
loss_fn = nn.MSELoss() # 损失函数
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) # 优化器
for epoch in range(100):
X, y = get_batch() # 取一批数据
X, y = X.to(device), y.to(device) # 搬到设备
pred = model(X) # 1. 前向:算预测
loss = loss_fn(pred, y) # 2. 算损失
optimizer.zero_grad() # 3. 清空上一轮梯度(必做!)
loss.backward() # 4. 反向:算梯度
optimizer.step() # 5. 更新参数五步口诀:前向 → 算损失 → 清梯度 → 反向 → 更新。
zero_grad()忘了会导致梯度累加,训练直接跑飞——这是新手头号坑。
8. 自定义模型(继承 nn.Module)
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x): # 定义数据怎么流过网络
x = F.relu(self.fc1(x))
return self.fc2(x)
model = Net().to(device)9. 保存 / 加载模型
torch.save(model.state_dict(), "model.pth") # 只存参数(推荐)
model.load_state_dict(torch.load("model.pth"))
model.eval() # 推理前切到 eval 模式存
state_dict()(只有权重)而非整个模型对象,更稳、跨代码更通用。
10. 常见坑
- 忘了
optimizer.zero_grad():梯度累加,训练发散(头号坑) - 张量不在同一设备:
Expected all tensors to be on the same device——数据和模型都要.to(device) - 推理没用
torch.no_grad():白白建计算图、爆显存、变慢 - 忘了
model.eval()/model.train():Dropout、BatchNorm 在训练/推理行为不同,切错结果异常 - CUDA out of memory (OOM):batch 太大、没释放中间变量;减小 batch、用
torch.no_grad()、del+torch.cuda.empty_cache() - CPU-only 的 torch 却调
.cuda():装错版本(见cuda.md),torch.cuda.is_available()返回 False .item()vs 张量:在训练循环里累加 loss 要用loss.item()取标量,否则会把整个计算图留在内存里
11. 延伸阅读 / 关联概念
- CUDA — GPU 加速的底层,torch 靠它跑在 NVIDIA 显卡上;装 torch 前要搞清 CUDA 版本,见
cuda.md - NumPy — torch 张量的 CPU 表亲,API 高度相似,可互转;见
numpy-basics.md - torchvision / torchaudio — 官方配套库,管图像/音频数据集和预训练模型
- CUDA / mps / cpu 设备 — 三种运行后端,代码里统一用
device变量切换 - Hugging Face Transformers — 建在 PyTorch 上的大模型库,实际用得最多
- 官方文档:https://pytorch.org/docs/ | 安装选择器:https://pytorch.org/get-started/locally/