Appearance
PyTorch 完整实战手册
导航目录
- 一、前言:简介、价值、场景、安装、依赖、环境验证
- 二、入门基础:核心概念、开发流程、基础组件、常见误区
- 三、核心功能与基础技巧:张量、自动求导、模型、损失与优化器
- 四、进阶技巧:网络模型、训练策略、计算图、数据预处理
- 五、实战场景:基础任务、CV、NLP、保存加载、GPU优化
- 六、高级进阶:高级模型、性能优化、自定义组件、模型部署
- 七、核心工具与资源:参数手册、模板库、学习资源
- 八、常见问题与避坑指南:高频问题修复与高级避坑
- 九、实战案例汇总(3-5个完整案例)
- 十、运行环境与依赖清单
- 十一、总结
一、前言:简介、价值、场景、安装、依赖、环境验证
1.1 PyTorch 简介
核心说明
PyTorch 是目前最主流的深度学习框架之一,特点是动态计算图、开发灵活、Python 风格友好、调试体验好,并且拥有完整生态(torchvision、torchaudio、torchtext 等)。
1.2 核心价值
- 动态计算图:边运行边构图,调试直观
- 易用性高:API 设计接近 NumPy
- 灵活度高:适合研究与工程快速迭代
- 生态完善:视觉/NLP/语音工具链齐全
- CPU/GPU 加速:支持 CUDA、混合精度训练
1.3 应用场景
- 深度学习模型开发
- 计算机视觉(分类、检测、分割)
- 自然语言处理(文本分类、序列建模)
- 语音识别与生成
- 推荐系统与多任务学习
1.4 安装方法
1.4.1 pip 安装(CPU 版)
bash
pip install torch torchvision torchaudio -i https://pypi.tuna.tsinghua.edu.cn/simple1.4.2 pip 安装(CUDA 版)
bash
# 示例:CUDA 12.1(请按官方命令选择你的 CUDA 版本)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu1211.4.3 conda 安装
bash
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia1.5 核心依赖与版本建议
- Python:3.9+
- torch:2.2+
- torchvision:与 torch 主版本匹配
- numpy / matplotlib:数据处理与可视化
- CUDA 驱动:需与 PyTorch CUDA 包匹配
1.6 环境搭建与运行验证
python
import torch
print("torch version:", torch.__version__)
print("cuda available:", torch.cuda.is_available())
if torch.cuda.is_available():
print("gpu:", torch.cuda.get_device_name(0))
x = torch.tensor([1.0, 2.0, 3.0])
print("x * 2 =", x * 2)
# 效果说明:输出版本、CUDA状态和基础张量计算结果二、入门基础:核心概念、开发流程、基础组件、常见误区
2.1 PyTorch 核心概念
核心说明
- Tensor(张量):多维数组,支持 GPU 运算
- 计算图:记录运算关系用于反向传播
- 自动求导:
autograd自动计算梯度 - Module:模型与网络层封装基类
- Optimizer:优化器,负责参数更新
- Loss:损失函数,衡量预测误差
2.2 基础开发流程
- 环境搭建
- 导入依赖
- 张量创建与操作
- 自动求导实现
- 简单模型搭建
- 模型训练与测试
完整可运行基础代码示例
python
import torch
import torch.nn as nn
import torch.optim as optim
# 1) 造数据:y = 2x + 1
x = torch.randn(100, 1)
y = 2 * x + 1 + 0.1 * torch.randn(100, 1)
# 2) 定义模型
model = nn.Linear(1, 1)
# 3) 损失与优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)
# 4) 训练
for epoch in range(100):
pred = model(x)
loss = criterion(pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("weight:", model.weight.item(), "bias:", model.bias.item())
# 效果说明:参数会收敛到接近 2 和 12.3 基础组件使用
2.3.1 Tensor 创建与属性
python
import torch
a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
b = torch.zeros((2, 3))
c = torch.ones((2, 3))
d = torch.randn((2, 3))
print(a.shape, a.dtype, a.device)参数说明
dtype:数据类型(float32,int64)device:设备(CPU/GPU)
2.3.2 张量基本操作(加减乘除、索引切片、形状变换)
python
import torch
x = torch.arange(1, 7).reshape(2, 3).float()
y = torch.ones_like(x)
print("x+y:\n", x + y)
print("x-y:\n", x - y)
print("x*y:\n", x * y)
print("x/y:\n", x / y)
print("slice:", x[:, 1])
print("reshape:", x.reshape(3, 2))2.3.3 自动求导机制(torch.autograd)
python
import torch
w = torch.tensor(2.0, requires_grad=True)
x = torch.tensor(3.0)
y = w * x + 1
y.backward()
print("dy/dw =", w.grad.item()) # 3.02.3.4 简单模型定义
python
import torch.nn as nn
class SimpleMLP(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(10, 32),
nn.ReLU(),
nn.Linear(32, 2)
)
def forward(self, x):
return self.net(x)2.4 新手常见误区与避坑
- 张量类型不匹配(
floatvslong) requires_grad用错导致无法反传- 忘记
optimizer.zero_grad()导致梯度累积 - 模型和数据不在同一设备(CPU/GPU 混用报错)
- 依赖版本不匹配(torch 与 torchvision)
三、核心功能与基础技巧:张量、自动求导、模型、损失与优化器
3.1 张量操作进阶
3.1.1 拼接与拆分、广播、矩阵运算
python
import torch
a = torch.randn(2, 3)
b = torch.randn(2, 3)
cat = torch.cat([a, b], dim=0) # 拼接
chunks = torch.chunk(cat, chunks=2, dim=0) # 拆分
x = torch.randn(4, 3)
y = torch.randn(3, 2)
matmul = torch.matmul(x, y) # 矩阵乘法
v = torch.tensor([1.0, 2.0, 3.0])
print(a + v) # 广播3.1.2 索引与掩码、类型转换、CPU/GPU 切换
python
import torch
t = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32)
mask = t > 3
print("masked:", t[mask])
print("to long:", t.long())
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
t = t.to(device)
print("device:", t.device)3.2 自动求导进阶
3.2.1 梯度计算与清零
python
import torch
w = torch.tensor([2.0], requires_grad=True)
for _ in range(3):
y = w ** 2
y.backward()
print("grad:", w.grad.item())
w.grad.zero_() # 梯度清零3.2.2 梯度裁剪
python
import torch
import torch.nn as nn
model = nn.Linear(10, 1)
for p in model.parameters():
p.grad = torch.randn_like(p)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)3.2.3 高阶求导与禁用梯度
python
import torch
x = torch.tensor(2.0, requires_grad=True)
y = x ** 3
grad1 = torch.autograd.grad(y, x, create_graph=True)[0] # 3x^2
grad2 = torch.autograd.grad(grad1, x)[0] # 6x
print(grad1.item(), grad2.item())
with torch.no_grad():
z = x * 103.3 基础模型搭建(nn.Module)
python
import torch.nn as nn
class Classifier(nn.Module):
def __init__(self, in_dim=20, hidden=64, num_classes=3):
super().__init__()
self.fc1 = nn.Linear(in_dim, hidden)
self.act = nn.ReLU()
self.fc2 = nn.Linear(hidden, num_classes)
def forward(self, x):
return self.fc2(self.act(self.fc1(x)))
model = Classifier()
print(model)参数查看与初始化
python
import torch.nn.init as init
for name, param in model.named_parameters():
if "weight" in name:
init.xavier_uniform_(param)3.4 损失函数与优化器
python
import torch
import torch.nn as nn
import torch.optim as optim
logits = torch.randn(8, 4) # 8样本,4类别
targets = torch.randint(0, 4, (8,)) # 类别标签
ce_loss = nn.CrossEntropyLoss()
print("CE:", ce_loss(logits, targets).item())
pred = torch.randn(8, 1)
y = torch.randn(8, 1)
mse_loss = nn.MSELoss()
print("MSE:", mse_loss(pred, y).item())
model = nn.Linear(10, 2)
sgd = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
adam = optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-5)
rms = optim.RMSprop(model.parameters(), lr=1e-3)适用场景
MSELoss:回归任务CrossEntropyLoss:多分类任务SGD:可解释、稳定,需调学习率Adam:收敛快,工程中常用
四、进阶技巧:网络模型、训练策略、计算图、数据预处理
4.1 网络模型进阶
4.1.1 CNN(卷积网络)
python
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 16, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(16, 32, 3, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool2d((1, 1))
)
self.classifier = nn.Linear(32, num_classes)
def forward(self, x):
x = self.features(x).flatten(1)
return self.classifier(x)4.1.2 RNN/LSTM/GRU
python
import torch
import torch.nn as nn
class LSTMClassifier(nn.Module):
def __init__(self, input_dim=50, hidden_dim=64, num_classes=2):
super().__init__()
self.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, num_classes)
def forward(self, x):
out, _ = self.lstm(x)
return self.fc(out[:, -1, :])4.1.3 Transformer 基础块
python
import torch.nn as nn
encoder_layer = nn.TransformerEncoderLayer(d_model=128, nhead=8, batch_first=True)
transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers=2)4.1.4 迁移学习(以 ResNet 为例)
python
import torch.nn as nn
from torchvision.models import resnet18
model = resnet18(weights="DEFAULT")
model.fc = nn.Linear(model.fc.in_features, 5) # 改成5分类4.2 模型训练进阶
4.2.1 Dataset / DataLoader
python
import torch
from torch.utils.data import Dataset, DataLoader
class ToyDataset(Dataset):
def __init__(self, n=1000):
self.x = torch.randn(n, 10)
self.y = (self.x.sum(dim=1) > 0).long()
def __len__(self):
return len(self.x)
def __getitem__(self, idx):
return self.x[idx], self.y[idx]
loader = DataLoader(ToyDataset(), batch_size=32, shuffle=True)4.2.2 正则化、学习率调度、早停
python
import torch.optim as optim
import torch.nn as nn
model = nn.Sequential(nn.Linear(10, 64), nn.ReLU(), nn.Dropout(0.3), nn.Linear(64, 2))
optimizer = optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-5) # L2
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.5)早停策略示意
python
# 连续 patience 个 epoch 验证集不提升则停止4.3 自动求导与计算图(深入)
核心说明
- PyTorch 默认是动态计算图
- 每次 forward 都会新建图
retain_graph=True用于重复反向传播(谨慎)
python
import torch
x = torch.tensor(1.0, requires_grad=True)
y = x * 2
z = y ** 2
z.backward()
print(x.grad) # dz/dx = 84.4 数据预处理
python
from torchvision import transforms
train_tf = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])常见步骤
- 归一化
- 数据增强
- 训练/验证/测试集划分
- 自定义 Dataset 适配业务数据
五、实战场景:基础任务、CV、NLP、保存加载、GPU优化
5.1 基础深度学习任务(线性回归/逻辑回归/多分类)
python
import torch
import torch.nn as nn
import torch.optim as optim
# 多分类示例
x = torch.randn(200, 20)
y = torch.randint(0, 3, (200,))
model = nn.Sequential(nn.Linear(20, 64), nn.ReLU(), nn.Linear(64, 3))
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
for _ in range(30):
logits = model(x)
loss = criterion(logits, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()5.2 计算机视觉实战(torchvision)
python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision.datasets import FakeData
from torchvision import transforms
from torch.utils.data import DataLoader
from torchvision.models import resnet18
transform = transforms.Compose([transforms.ToTensor()])
train_ds = FakeData(size=256, image_size=(3, 64, 64), num_classes=5, transform=transform)
train_loader = DataLoader(train_ds, batch_size=32, shuffle=True)
model = resnet18(weights=None, num_classes=5)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
for imgs, labels in train_loader:
logits = model(imgs)
loss = criterion(logits, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
break
print("cv training step done")5.3 NLP 实战(文本分类简化示例)
python
import torch
import torch.nn as nn
vocab_size = 5000
embed_dim = 128
num_classes = 2
class TextClassifier(nn.Module):
def __init__(self):
super().__init__()
self.emb = nn.Embedding(vocab_size, embed_dim)
self.fc = nn.Linear(embed_dim, num_classes)
def forward(self, x):
# x: [batch, seq_len]
e = self.emb(x).mean(dim=1) # 简单平均池化
return self.fc(e)
model = TextClassifier()
tokens = torch.randint(0, vocab_size, (8, 20))
logits = model(tokens)
print(logits.shape) # [8, 2]5.4 模型保存与加载
python
import torch
import torch.nn as nn
model = nn.Linear(10, 2)
# 1) 保存参数(推荐)
torch.save(model.state_dict(), "model_state.pt")
# 2) 加载参数
new_model = nn.Linear(10, 2)
new_model.load_state_dict(torch.load("model_state.pt", map_location="cpu"))
new_model.eval()
# 3) 保存完整模型(不推荐跨版本)
torch.save(model, "full_model.pt")5.5 GPU 加速与性能优化
python
import torch
from torch.cuda.amp import autocast, GradScaler
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.nn.Linear(1024, 1024).to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
scaler = GradScaler(enabled=torch.cuda.is_available())
x = torch.randn(32, 1024, device=device)
y = torch.randn(32, 1024, device=device)
optimizer.zero_grad()
with autocast(enabled=torch.cuda.is_available()):
pred = model(x)
loss = torch.nn.functional.mse_loss(pred, y)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()优化要点
- 开启混合精度(AMP)
- 合理调大 batch size(显存允许时)
- 数据加载使用
num_workers和pin_memory
六、高级进阶:高级模型、性能优化、自定义组件、模型部署
6.1 高级模型开发
6.1.1 Transformer 完整训练思路(框架)
python
# 典型流程:
# Tokenizer -> Embedding -> TransformerEncoder/Decoder -> 任务头 -> Loss -> Optimizer -> Scheduler6.1.2 预训练模型微调(BERT / ResNet)
python
from torchvision.models import resnet50
import torch.nn as nn
model = resnet50(weights="DEFAULT")
for p in model.parameters():
p.requires_grad = False # 冻结特征层
model.fc = nn.Linear(model.fc.in_features, 10) # 替换分类头6.1.3 多任务学习(共享骨干)
python
import torch.nn as nn
class MultiTaskModel(nn.Module):
def __init__(self):
super().__init__()
self.backbone = nn.Linear(128, 64)
self.cls_head = nn.Linear(64, 3)
self.reg_head = nn.Linear(64, 1)
def forward(self, x):
feat = self.backbone(x)
return self.cls_head(feat), self.reg_head(feat)6.2 性能优化(量化、剪枝、蒸馏、并行)
python
import torch
import torch.nn as nn
model = nn.Sequential(nn.Linear(10, 10), nn.ReLU(), nn.Linear(10, 2))
model.eval()
# 动态量化(CPU 推理常用)
q_model = torch.quantization.quantize_dynamic(model, {nn.Linear}, dtype=torch.qint8)其他优化方向
- 剪枝:移除低重要性参数
- 蒸馏:学生模型学习教师模型输出
- 数据并行:
torch.nn.DataParallel/DistributedDataParallel
6.3 自定义组件开发
6.3.1 自定义损失函数
python
import torch
import torch.nn as nn
class MAELoss(nn.Module):
def forward(self, pred, target):
return torch.mean(torch.abs(pred - target))6.3.2 自定义优化器(简化示意)
python
# 实际项目通常使用 torch.optim 内置优化器6.3.3 自定义数据集与网络层
python
from torch.utils.data import Dataset
import torch.nn as nn
class MyDataset(Dataset):
def __init__(self, data, label):
self.data = data
self.label = label
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
return self.data[idx], self.label[idx]
class Swish(nn.Module):
def forward(self, x):
return x * x.sigmoid()6.4 模型部署(TorchScript / ONNX / TensorRT)
python
import torch
import torch.nn as nn
model = nn.Linear(10, 2).eval()
example = torch.randn(1, 10)
# TorchScript
ts_model = torch.jit.trace(model, example)
ts_model.save("model_ts.pt")
# ONNX
torch.onnx.export(model, example, "model.onnx", opset_version=17)部署说明
- TorchScript:PyTorch 原生部署友好
- ONNX:跨框架、跨平台部署
- TensorRT:NVIDIA GPU 推理加速
七、核心工具与资源:参数手册、模板库、学习资源
7.1 PyTorch 常用参数手册
Tensor 与设备
dtype:数据类型(torch.float32,torch.long)device:cpu/cudarequires_grad:是否追踪梯度
DataLoader
batch_size:批大小shuffle:是否打乱num_workers:数据加载子进程数pin_memory:GPU 训练推荐开启
Optimizer
lr:学习率weight_decay:L2 正则momentum:SGD 动量项
Scheduler
StepLR(step_size, gamma)CosineAnnealingLR(T_max)
7.2 优质实战模板
模板1:标准训练循环
python
def train_one_epoch(model, loader, criterion, optimizer, device):
model.train()
total_loss = 0.0
for x, y in loader:
x, y = x.to(device), y.to(device)
pred = model(x)
loss = criterion(pred, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
return total_loss / len(loader)模板2:验证循环
python
@torch.no_grad()
def evaluate(model, loader, criterion, device):
model.eval()
total_loss = 0.0
for x, y in loader:
x, y = x.to(device), y.to(device)
pred = model(x)
total_loss += criterion(pred, y).item()
return total_loss / len(loader)7.3 学习资源推荐
- 官方文档:PyTorch Docs
- 教程中心:PyTorch Tutorials
- torchvision 文档:TorchVision Docs
- 社区案例:GitHub 搜索
pytorch examples
八、常见问题与避坑指南:高频问题修复与高级避坑
8.1 高频问题解决方案
问题1:模型不收敛
常见原因
- 学习率不合适
- 数据未归一化
- 模型过大/过小
修正建议
- 调整
lr(如1e-3 -> 1e-4) - 加入归一化和正则化
- 先在小数据集验证可学习性
问题2:梯度消失/爆炸
修正代码
python
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)问题3:GPU 显存不足(OOM)
修正建议
- 减小
batch_size - 使用混合精度
- 检查无用 tensor 引用(及时
del)
问题4:数据加载报错
常见原因
__getitem__返回格式不一致- 图像路径或标签越界
问题5:模型加载失败
错误代码
python
model.load_state_dict(torch.load("model.pt"))
# 结构不匹配会报 missing/unexpected keys修正建议
- 保证模型结构一致
- 或使用
strict=False做兼容加载
8.2 高级避坑技巧
- 防过拟合:数据增强 + Dropout + 早停
- 提升速度:AMP + 合理 DataLoader 参数
- 提升泛化:交叉验证 + 更稳健的数据划分
- 硬件适配:根据 CPU/GPU 显存调整 batch 与模型规模
九、实战案例汇总(3-5个完整案例)
案例1:线性回归预测房价(回归)
需求分析:根据特征预测价格。
流程:数据准备 -> 线性模型 -> MSELoss -> SGD 训练 -> 指标评估。
效果:学习到特征与价格关系,可做 baseline。
案例2:手写数字分类(CV)
需求分析:10 类分类任务。
技术栈:torchvision.datasets.MNIST + CNN。
部署测试:保存模型并推理单张图片。
案例3:新闻文本情感分类(NLP)
需求分析:二分类情感识别。
模型结构:Embedding + LSTM + 全连接。
效果:完成基础 NLP 分类闭环。
案例4:迁移学习图像分类
需求分析:小样本图像数据分类。
方案:冻结 ResNet 主干 + 微调分类头。
效果:在小数据集上快速收敛。
案例5:模型导出与部署准备
需求分析:训练模型交给服务端部署。
方案:导出 TorchScript/ONNX,验证推理一致性。
效果:减少上线阻力,支持跨平台推理。
十、运行环境与依赖清单
10.1 推荐环境
- Python 3.9+
- torch 2.2+
- torchvision 0.17+
- numpy 1.24+
- matplotlib 3.7+
10.2 一键安装命令
bash
pip install torch torchvision torchaudio numpy matplotlib10.3 运行步骤
- 安装依赖
- 配置 CUDA(如有 GPU)
- 复制示例代码到
.py - 运行
python your_script.py
十一、总结
关键结论
- PyTorch 学习主线是:张量 -> 自动求导 -> 模型构建 -> 训练优化 -> 部署导出。
- 真正工程能力来自:稳定训练流程 + 可复用模板 + 性能优化策略。
- 遇到问题优先排查:数据、设备、梯度、损失、学习率。
下一步建议
- 先完成一个“分类任务全流程”项目
- 再做迁移学习和混合精度训练
- 最后打通 ONNX/TorchScript 部署闭环