从零开始:使用 PyTorch 构建深度学习网络
目录
- PyTorch 简介
- 环境配置
- PyTorch 基础
- 构建神经网络
- 训练模型
- 评估与测试
- 案例实战:手写数字识别
- 进阶技巧
- 常见问题解答
PyTorch 简介
PyTorch 是一个开源的深度学习框架,由 Facebook(现在的 Meta)的人工智能研究团队开发。它以其动态计算图和简洁的 API 而受到广泛欢迎,尤其在学术研究领域。与其他深度学习框架相比,PyTorch 的特点是直观、灵活且易于调试。
为什么选择 PyTorch?
- Python 友好:PyTorch 的设计理念非常符合 Python 的编程风格,如果你熟悉 NumPy,学习 PyTorch 将会非常顺利。
- 动态计算图:不同于 TensorFlow 1.x 的静态图,PyTorch 使用动态计算图,这意味着你可以在运行时修改网络结构,使调试和实验更加方便。
- 强大的社区支持:庞大的用户基础和丰富的学习资源。
- 良好的生态系统:包括计算机视觉(torchvision)、自然语言处理(transformers)、音频处理(torchaudio)等领域的专用库。
- 现代化 API:PyTorch 2.0+ 提供了编译器优化、更好的性能和更简洁的 API。
环境配置
开始使用 PyTorch 前,需要先配置环境。以下是基本步骤:
安装 PyTorch
推荐使用 Anaconda 或 Miniconda 创建虚拟环境:
# 创建虚拟环境
conda create -n pytorch_env python=3.11
# 激活环境
conda activate pytorch_env
# 安装 PyTorch(CPU 版本)
conda install pytorch torchvision torchaudio cpuonly -c pytorch
如果你有 NVIDIA GPU,可以安装支持 CUDA 的版本:
# 安装支持 CUDA 的 PyTorch
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
你也可以使用 pip 安装最新版本:
# CPU 版本
pip install torch torchvision torchaudio
# GPU 版本 (CUDA 12.1)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
验证安装
创建一个简单的 Python 脚本来验证 PyTorch 是否正确安装:
import torch
# 打印 PyTorch 版本
print(f"PyTorch 版本: {torch.__version__}")
# 检查 GPU 是否可用
print(f"GPU 是否可用: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"GPU 名称: {torch.cuda.get_device_name(0)}")
# 检查 MPS(适用于 Apple Silicon)
print(f"MPS 是否可用: {getattr(torch, 'has_mps', False)}")
PyTorch 基础
在构建神经网络前,先了解 PyTorch 的核心概念。
张量(Tensor)
张量是 PyTorch 中的基本数据结构,类似于 NumPy 的多维数组,但可以在 GPU 上运行计算。
import torch
# 创建张量
x = torch.tensor([[1, 2], [3, 4]])
print(x)
print(f"Shape: {x.shape}")
print(f"Data type: {x.dtype}")
# 创建特定类型的张量
x_float = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
print(x_float)
# 常用的张量创建函数
zeros = torch.zeros(2, 3)
ones = torch.ones(2, 3)
rand = torch.rand(2, 3) # 均匀分布 [0,1)
randn = torch.randn(2, 3) # 标准正态分布
print(f"Zeros:\n{zeros}")
print(f"Ones:\n{ones}")
print(f"Random (uniform):\n{rand}")
print(f"Random (normal):\n{randn}")
张量运算
PyTorch 提供了丰富的张量运算函数:
import torch
# 创建两个张量
a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32)
b = torch.tensor([[5, 6], [7, 8]], dtype=torch.float32)
# 基本算术运算
print(f"a + b = \n{a + b}")
print(f"a - b = \n{a - b}")
print(f"a * b = \n{a * b}") # 元素级乘法
print(f"a / b = \n{a / b}")
# 矩阵乘法
print(f"矩阵乘法 a @ b = \n{a @ b}")
# 或使用 torch.matmul
print(f"torch.matmul(a, b) = \n{torch.matmul(a, b)}")
# 其他常用运算
print(f"Sum: {a.sum()}")
print(f"Mean: {a.mean()}")
print(f"Max: {a.max()}")
print(f"Min: {a.min()}")
自动微分
PyTorch 的核心功能之一是自动计算梯度,这是深度学习训练的基础:
import torch
# 创建需要梯度的张量
x = torch.tensor([[1., 2.], [3., 4.]], requires_grad=True)
print(x)
# 进行一些操作
y = x * 2
z = y.sum()
print(f"z = {z}")
# 反向传播计算梯度
z.backward()
# 查看 x 的梯度
print(f"梯度 dz/dx = \n{x.grad}") # 应该全是 2
构建神经网络
PyTorch 提供了 nn
模块,包含构建神经网络所需的各种组件。
线性层与激活函数
最基本的神经网络由线性层和激活函数组成:
import torch
import torch.nn as nn
# 定义一个简单的全连接层
linear = nn.Linear(in_features=10, out_features=5)
# 创建输入数据(批量大小为3,每个样本有10个特征)
x = torch.randn(3, 10)
# 前向传播
output = linear(x)
print(f"输入形状: {x.shape}")
print(f"输出形状: {output.shape}")
# 激活函数
relu = nn.ReLU()
sigmoid = nn.Sigmoid()
tanh = nn.Tanh()
# 应用激活函数
print(f"ReLU: {relu(output)}")
print(f"Sigmoid: {sigmoid(output)}")
print(f"Tanh: {tanh(output)}")
定义神经网络类
在 PyTorch 中,神经网络通常通过继承 nn.Module
类来定义:
import torch
import torch.nn as nn
class SimpleNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleNN, self).__init__()
# 第一个全连接层
self.fc1 = nn.Linear(input_size, hidden_size)
# 激活函数
self.relu = nn.ReLU()
# 第二个全连接层
self.fc2 = nn.Linear(hidden_size, output_size)
def forward(self, x):
# 定义前向传播过程
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 创建网络实例
input_size = 10
hidden_size = 20
output_size = 5
model = SimpleNN(input_size, hidden_size, output_size)
# 打印模型结构
print(model)
# 创建一个输入样本
x = torch.randn(1, input_size)
# 前向传播
output = model(x)
print(f"输出: {output}")
使用 PyTorch 2.x 的新特性
PyTorch 2.x 引入了一些强大的新特性,比如 torch.compile
,可以显著提高模型性能:
import torch
import torch.nn as nn
class ModernNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
# 使用 Sequential 简化网络定义
self.network = nn.Sequential(
nn.Linear(input_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, hidden_size // 2),
nn.ReLU(),
nn.Linear(hidden_size // 2, output_size)
)
def forward(self, x):
return self.network(x)
# 创建网络实例
model = ModernNN(input_size=10, hidden_size=32, output_size=5)
# 使用 torch.compile 加速模型(PyTorch 2.0+ 新特性)
# 在生产环境运行速度提升可达 2x 或更多
if hasattr(torch, 'compile'):
model = torch.compile(model)
# 输入数据
x = torch.randn(100, 10) # 批量大小为100的输入
# 使用 @torch.inference_mode 可以在推理时降低内存使用
@torch.inference_mode()
def predict(model, x):
return model(x)
# 调用推理函数
outputs = predict(model, x)
print(f"输出形状: {outputs.shape}")
训练模型
训练神经网络涉及多个步骤:数据准备、定义损失函数、优化器配置和训练循环。
数据加载与预处理
PyTorch 提供了 Dataset
和 DataLoader
类来简化数据处理:
import torch
from torch.utils.data import Dataset, DataLoader
import numpy as np
# 创建一个简单的数据集类
class SimpleDataset(Dataset):
def __init__(self, size, input_dim, output_dim):
# 生成随机数据
self.x = torch.randn(size, input_dim)
# 生成随机标签(分类问题)
self.y = torch.randint(0, output_dim, (size,))
def __len__(self):
return len(self.x)
def __getitem__(self, idx):
return self.x[idx], self.y[idx]
# 创建数据集实例
dataset = SimpleDataset(size=1000, input_dim=10, output_dim=5)
# 创建数据加载器
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
# 查看一个批次的数据
for inputs, labels in dataloader:
print(f"Inputs shape: {inputs.shape}")
print(f"Labels shape: {labels.shape}")
break # 只查看第一个批次
损失函数与优化器
选择合适的损失函数和优化器对模型训练至关重要:
import torch
import torch.nn as nn
import torch.optim as optim
# 假设我们已经定义了模型
model = SimpleNN(input_size=10, hidden_size=20, output_size=5)
# 定义损失函数(交叉熵损失,适用于分类问题)
criterion = nn.CrossEntropyLoss()
# 定义优化器(随机梯度下降)
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 其他常用优化器
# Adam 优化器
optimizer_adam = optim.Adam(model.parameters(), lr=0.001)
# RMSprop 优化器
optimizer_rmsprop = optim.RMSprop(model.parameters(), lr=0.001)
训练循环
下面是一个完整的训练循环示例:
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
# 假设我们已经定义了模型、数据集和数据加载器
model = SimpleNN(input_size=10, hidden_size=20, output_size=5)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练参数
num_epochs = 10
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
# 训练循环
for epoch in range(num_epochs):
running_loss = 0.0
for inputs, labels in dataloader:
# 将数据移到设备(CPU/GPU)
inputs, labels = inputs.to(device), labels.to(device)
# 清零梯度
optimizer.zero_grad()
# 前向传播
outputs = model(inputs)
# 计算损失
loss = criterion(outputs, labels)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 累加损失
running_loss += loss.item()
# 打印每个 epoch 的平均损失
epoch_loss = running_loss / len(dataloader)
print(f"Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss:.4f}")
print("训练完成!")
评估与测试
训练后,需要评估模型在测试数据上的性能:
import torch
# 切换到评估模式
model.eval()
# 创建测试数据集和数据加载器
test_dataset = SimpleDataset(size=200, input_dim=10, output_dim=5)
test_loader = DataLoader(test_dataset, batch_size=32)
# 在测试数据上评估
correct = 0
total = 0
# 不计算梯度
with torch.no_grad():
for inputs, labels in test_loader:
inputs, labels = inputs.to(device), labels.to(device)
# 前向传播
outputs = model(inputs)
# 获取预测结果
_, predicted = torch.max(outputs.data, 1)
# 统计正确预测的数量
total += labels.size(0)
correct += (predicted == labels).sum().item()
# 计算准确率
accuracy = 100 * correct / total
print(f"测试集准确率: {accuracy:.2f}%")
# 返回训练模式
model.train()
案例实战:手写数字识别
下面将使用 MNIST 数据集实现一个完整的手写数字识别模型,并应用 PyTorch 的现代特性。
导入必要的库
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import torch.nn.functional as F
from torch.cuda.amp import GradScaler, autocast # 用于混合精度训练
准备数据
# 数据预处理
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
# 下载 MNIST 数据集
train_dataset = torchvision.datasets.MNIST(
root='./data',
train=True,
transform=transform,
download=True
)
test_dataset = torchvision.datasets.MNIST(
root='./data',
train=False,
transform=transform,
download=True
)
# 创建数据加载器,使用新的 PyTorch 2.x 的 persistent workers 特性提高数据加载效率
train_loader = DataLoader(
train_dataset,
batch_size=128, # 更大的批次大小
shuffle=True,
num_workers=4, # 多进程加载
persistent_workers=True, # 保持工作进程活跃,减少启动开销
pin_memory=True # 使用固定内存提高GPU传输速度
)
test_loader = DataLoader(
test_dataset,
batch_size=1000,
shuffle=False,
num_workers=4,
persistent_workers=True,
pin_memory=True
)
定义现代化的 CNN 模型
class ModernMNISTModel(nn.Module):
def __init__(self):
super().__init__()
# 使用更现代的网络架构
self.features = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(64, 128, kernel_size=3, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2, padding=1) # 确保尺寸正确
)
self.classifier = nn.Sequential(
nn.AdaptiveAvgPool2d((1, 1)), # 自适应池化到固定尺寸
nn.Flatten(),
nn.Linear(128, 64),
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.features(x)
x = self.classifier(x)
return x
# 创建模型实例
model = ModernMNISTModel()
# 使用 torch.compile 编译模型(PyTorch 2.0+)
if hasattr(torch, 'compile'):
model = torch.compile(model)
训练与评估完整流程(带混合精度训练)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=1e-4) # 使用 AdamW 替代 Adam
scheduler = torch.optim.lr_scheduler.OneCycleLR( # 使用 OneCycleLR 调度器
optimizer,
max_lr=0.005,
epochs=10,
steps_per_epoch=len(train_loader)
)
# 设备配置
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
# 混合精度训练
scaler = GradScaler()
# 训练参数
num_epochs = 10
# 训练循环
for epoch in range(num_epochs):
model.train() # 设置为训练模式
running_loss = 0.0
for i, (images, labels) in enumerate(train_loader):
images, labels = images.to(device), labels.to(device)
# 清零梯度
optimizer.zero_grad()
# 使用混合精度训练
with autocast():
# 前向传播
outputs = model(images)
loss = criterion(outputs, labels)
# 反向传播和优化
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
# 更新学习率
scheduler.step()
running_loss += loss.item()
# 每100批次打印统计信息
if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}, LR: {scheduler.get_last_lr()[0]:.6f}')
# 测试模型
model.eval() # 设置为评估模式
with torch.no_grad():
correct = 0
total = 0
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
# 使用 torch.inference_mode() 优化推理
with torch.inference_mode():
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Epoch [{epoch+1}/{num_epochs}], 测试准确率: {100 * correct / total:.2f}%')
# 保存模型
torch.save({
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'epoch': num_epochs
}, 'mnist_model_modern.pth')
print("模型已保存!")
# 测试推理性能
import time
model.eval()
test_images, test_labels = next(iter(test_loader))
test_images = test_images.to(device)
# 预热
with torch.inference_mode():
for _ in range(10):
_ = model(test_images[:10])
# 计时
start_time = time.time()
with torch.inference_mode():
for _ in range(50):
_ = model(test_images)
end_time = time.time()
print(f"推理性能: {50 * len(test_images) / (end_time - start_time):.2f} 图像/秒")
进阶技巧
掌握了基础知识后,这里介绍一些提高模型性能的进阶技巧和 PyTorch 的现代特性。
学习率调整
随着训练的进行,适当调整学习率可以帮助模型更好地收敛:
from torch.optim.lr_scheduler import StepLR, ReduceLROnPlateau, CosineAnnealingLR
# 每10个 epoch 将学习率乘以 gamma
scheduler = StepLR(optimizer, step_size=10, gamma=0.1)
# 当验证损失不再下降时减小学习率
scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5)
# 余弦退火学习率(在深度学习中表现优异)
scheduler = CosineAnnealingLR(optimizer, T_max=10)
# 在训练循环中使用
for epoch in range(num_epochs):
# 训练代码...
# 更新学习率(取决于scheduler类型)
if isinstance(scheduler, ReduceLROnPlateau):
scheduler.step(val_loss)
else:
scheduler.step()
早停法(Early Stopping)
当模型在验证集上的性能不再提升时,停止训练可以防止过拟合:
best_val_loss = float('inf')
patience = 5
counter = 0
best_model_path = 'best_model.pth'
for epoch in range(num_epochs):
# 训练代码...
# 计算验证损失
val_loss = validate(model, val_loader, criterion)
# 更新最佳损失和检查早停
if val_loss < best_val_loss:
best_val_loss = val_loss
counter = 0
# 保存最佳模型
torch.save({
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'epoch': epoch,
'loss': val_loss,
}, best_model_path)
print(f"保存最佳模型,验证损失: {val_loss:.4f}")
else:
counter += 1
if counter >= patience:
print(f"Early stopping at epoch {epoch+1}")
break
使用预训练模型与迁移学习
对于复杂任务,使用预训练模型可以大幅提高性能,PyTorch 2.x 提供了更简洁的 API:
import torch
import torchvision.models as models
# 使用新的 API 加载预训练模型
# weights 参数代替了旧的 pretrained=True
resnet = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V2)
# 冻结预训练层
for param in resnet.parameters():
param.requires_grad = False
# 替换最后的全连接层,适应新任务
num_features = resnet.fc.in_features
resnet.fc = torch.nn.Linear(num_features, num_classes) # 只训练这一层
# 也可以使用 HuggingFace 获取最新的预训练模型
# pip install transformers
from transformers import AutoImageProcessor, AutoModelForImageClassification
# 加载预训练的视觉模型
processor = AutoImageProcessor.from_pretrained("microsoft/resnet-50")
model = AutoModelForImageClassification.from_pretrained("microsoft/resnet-50")
# 加载并预处理图像
from PIL import Image
import requests
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
inputs = processor(images=image, return_tensors="pt")
# 使用模型进行推理
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
# 获取预测结果
predicted_class_idx = logits.argmax(-1).item()
print("预测类别:", model.config.id2label[predicted_class_idx])
PyTorch 2.x 的模型加速与部署
PyTorch 2.x 提供了多种模型优化和部署技术:
使用 TorchScript 和 torch.compile
import torch
# 定义模型
model = YourModel()
model.eval()
# 使用 torch.compile 加速(PyTorch 2.0+)
optimized_model = torch.compile(
model,
mode='reduce-overhead', # 可选模式: 'default', 'reduce-overhead', 'max-autotune'
fullgraph=True
)
# 或使用 TorchScript 导出模型
example_input = torch.randn(1, 3, 224, 224)
scripted_model = torch.jit.script(model)
# 或 traced_model = torch.jit.trace(model, example_input)
# 保存模型用于部署
scripted_model.save("model_scripted.pt")
量化模型以减小尺寸和加速推理
import torch.quantization
# 准备量化
model.eval()
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
torch.quantization.prepare(model, inplace=True)
# 校准模型(需要代表性数据)
with torch.no_grad():
for data, _ in calibration_dataloader:
model(data)
# 转换到量化模型
torch.quantization.convert(model, inplace=True)
# 保存量化模型
torch.jit.save(torch.jit.script(model), "quantized_model.pt")
分布式训练
PyTorch 提供了多种分布式训练方法,包括数据并行和模型并行:
import torch.distributed as dist
import torch.multiprocessing as mp
from torch.nn.parallel import DistributedDataParallel as DDP
def setup(rank, world_size):
# 初始化进程组
dist.init_process_group("nccl", rank=rank, world_size=world_size)
def train(rank, world_size):
setup(rank, world_size)
# 创建模型
model = YourModel().to(rank)
# 将模型包装为分布式模型
ddp_model = DDP(model, device_ids=[rank])
# 数据加载器需要修改为分布式
sampler = torch.utils.data.distributed.DistributedSampler(
dataset,
num_replicas=world_size,
rank=rank
)
dataloader = DataLoader(dataset, sampler=sampler, ...)
# 训练循环
for epoch in range(num_epochs):
sampler.set_epoch(epoch) # 确保不同进程看到不同数据
for data, target in dataloader:
# 常规训练步骤
...
# 启动多进程训练
world_size = torch.cuda.device_count()
mp.spawn(train, args=(world_size,), nprocs=world_size, join=True)
使用现代 PyTorch 特性进行移动设备部署
PyTorch 提供了 TorchMobile 功能,可以将模型部署到移动设备:
import torch
# 准备模型
model = YourModel()
model.eval()
# 转换为 TorchScript
example_input = torch.rand(1, 3, 224, 224)
traced_model = torch.jit.trace(model, example_input)
# 优化移动设备部署
traced_model_optimized = torch.utils.mobile_optimizer.optimize_for_mobile(traced_model)
# 保存为移动格式
traced_model_optimized.save("model_mobile.pt")
# 可以进一步转换为适用于更多平台的格式,如 ONNX
torch.onnx.export(
model,
example_input,
"model.onnx",
export_params=True,
opset_version=12,
do_constant_folding=True,
input_names=['input'],
output_names=['output'],
dynamic_axes={
'input': {0: 'batch_size'},
'output': {0: 'batch_size'}
}
)
常见问题解答
如何处理过拟合?
过拟合是指模型在训练数据上表现良好,但在测试数据上表现不佳。解决方法包括:
- 增加数据量:更多样本通常会降低过拟合风险
- 数据增强:通过旋转、缩放等变换增加训练数据的多样性
- 正则化:使用 L1、L2 正则化或 Dropout
- 简化模型:减少模型的复杂度(层数或参数数量)
示例代码(添加 Dropout 和 权重衰减):
# 添加 Dropout
self.dropout = nn.Dropout(0.5) # 在网络中间层添加
# 添加权重衰减(L2正则化)
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
GPU 内存不足怎么办?
当模型或数据集过大,GPU 内存不足时:
- 减小批量大小:这是最直接的方法
- 使用梯度累积:累积多个小批量的梯度后再更新参数
- 混合精度训练:使用 float16 代替 float32 进行部分计算
梯度累积示例:
accumulation_steps = 4 # 累积4个批次
optimizer.zero_grad()
for i, (inputs, labels) in enumerate(dataloader):
outputs = model(inputs)
loss = criterion(outputs, labels) / accumulation_steps # 缩小损失
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
如何解决梯度消失/爆炸问题?
- 使用 ReLU 等现代激活函数:避免 Sigmoid 和 Tanh 在饱和区的梯度消失
- 批量归一化(Batch Normalization):稳定各层的输入分布
- 梯度裁剪:防止梯度爆炸
- 合理的权重初始化:如 Xavier 或 He 初始化
梯度裁剪示例:
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
以上就是 PyTorch 深度学习入门的完整指南。