Skip to content

PyTorch 完整实战手册

导航目录

一、前言:简介、价值、场景、安装、依赖、环境验证

1.1 PyTorch 简介

核心说明
PyTorch 是目前最主流的深度学习框架之一,特点是动态计算图、开发灵活、Python 风格友好、调试体验好,并且拥有完整生态(torchvisiontorchaudiotorchtext 等)。

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/simple

1.4.2 pip 安装(CUDA 版)

bash
# 示例:CUDA 12.1(请按官方命令选择你的 CUDA 版本)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

1.4.3 conda 安装

bash
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia

1.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 基础开发流程

  1. 环境搭建
  2. 导入依赖
  3. 张量创建与操作
  4. 自动求导实现
  5. 简单模型搭建
  6. 模型训练与测试

完整可运行基础代码示例

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 和 1

2.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.0

2.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 新手常见误区与避坑

  • 张量类型不匹配(float vs long
  • 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 * 10

3.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 = 8

4.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_workerspin_memory

六、高级进阶:高级模型、性能优化、自定义组件、模型部署

6.1 高级模型开发

6.1.1 Transformer 完整训练思路(框架)

python
# 典型流程:
# Tokenizer -> Embedding -> TransformerEncoder/Decoder -> 任务头 -> Loss -> Optimizer -> Scheduler

6.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
  • devicecpu / cuda
  • requires_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 学习资源推荐


八、常见问题与避坑指南:高频问题修复与高级避坑

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 matplotlib

10.3 运行步骤

  1. 安装依赖
  2. 配置 CUDA(如有 GPU)
  3. 复制示例代码到 .py
  4. 运行 python your_script.py

十一、总结

关键结论

  • PyTorch 学习主线是:张量 -> 自动求导 -> 模型构建 -> 训练优化 -> 部署导出
  • 真正工程能力来自:稳定训练流程 + 可复用模板 + 性能优化策略
  • 遇到问题优先排查:数据、设备、梯度、损失、学习率

下一步建议

  • 先完成一个“分类任务全流程”项目
  • 再做迁移学习和混合精度训练
  • 最后打通 ONNX/TorchScript 部署闭环