从零开始:使用 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 创建虚拟环境:
bash
# 创建虚拟环境
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 的版本:
bash
# 安装支持 CUDA 的 PyTorch
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
你也可以使用 pip 安装最新版本:
bash
# 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 是否正确安装:
python
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 上运行计算。
python
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 提供了丰富的张量运算函数:
python
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 的核心功能之一是自动计算梯度,这是深度学习训练的基础:
python
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
模块,包含构建神经网络所需的各种组件。
线性层与激活函数
最基本的神经网络由线性层和激活函数组成:
python
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
类来定义:
python
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
,可以显著提高模型性能:
python
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
类来简化数据处理:
python
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 # 只查看第一个批次
损失函数与优化器
选择合适的损失函数和优化器对模型训练至关重要:
python
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)
训练循环
下面是一个完整的训练循环示例:
python
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("训练完成!")
评估与测试
训练后,需要评估模型在测试数据上的性能:
python
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 的现代特性。
导入必要的库
python
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 # 用于混合精度训练
准备数据
python
# 数据预处理
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 模型
python
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)
训练与评估完整流程(带混合精度训练)
python
# 定义损失函数和优化器
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 的现代特性。
学习率调整
随着训练的进行,适当调整学习率可以帮助模型更好地收敛:
python
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)
当模型在验证集上的性能不再提升时,停止训练可以防止过拟合:
python
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:
python
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
python
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")
量化模型以减小尺寸和加速推理
python
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 提供了多种分布式训练方法,包括数据并行和模型并行:
python
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 功能,可以将模型部署到移动设备:
python
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 和 权重衰减):
python
# 添加 Dropout
self.dropout = nn.Dropout(0.5) # 在网络中间层添加
# 添加权重衰减(L2正则化)
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)
GPU 内存不足怎么办?
当模型或数据集过大,GPU 内存不足时:
- 减小批量大小:这是最直接的方法
- 使用梯度累积:累积多个小批量的梯度后再更新参数
- 混合精度训练:使用 float16 代替 float32 进行部分计算
梯度累积示例:
python
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 初始化
梯度裁剪示例:
python
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
以上就是 PyTorch 深度学习入门的完整指南。