**作用:**在PyTorch中,模型有训练(training)和评估(evaluation)两种模式,它们会影响某些层的行为。
# 设置训练模式
model.train()
# 设置评估模式
model.eval()
# 训练循环
model.train()
for epoch in range(num_epochs):
for batch_x, batch_y in train_loader:
optimizer.zero_grad()
output = model(batch_x)
loss = criterion(output, batch_y)
loss.backward()
optimizer.step()
# 评估循环
model.eval()
with torch.no_grad(): # 禁用梯度计算
for batch_x, batch_y in val_loader:
output = model(batch_x)
# 计算验证指标
**常见错误:**忘记在训练和评估阶段之间切换模式,可能导致性能下降或结果不准确。
# 检查GPU是否可用
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 将模型移动到指定设备
model = model.to(device)
# 将数据移动到指定设备
inputs = inputs.to(device)
labels = labels.to(device)
# 完整训练示例
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MyModel().to(device)
for batch_x, batch_y in train_loader:
# 将数据移到相应设备
batch_x = batch_x.to(device)
batch_y = batch_y.to(device)
outputs = model(batch_x)
loss = criterion(outputs, batch_y)
**最佳实践:**在训练开始时就确定设备,并始终保持数据和模型在同一设备上。
**作用:**获取模型的所有参数(权重和偏置)及其当前值。返回一个有序字典,包含每一层的参数张量。
# 获取模型参数
model_state = model.state_dict()
# 保存模型参数
torch.save(model_state, 'model_weights.pth')
**作用:**将保存的参数加载到模型中,用于模型的权重恢复或迁移学习。
# 加载保存的参数
model_state = torch.load('model_weights.pth')
model.load_state_dict(model_state)
# 完整的保存和加载示例
# 保存模型
torch.save({
'epoch': epoch,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss,
}, 'checkpoint.pth')
# 加载模型
checkpoint = torch.load('checkpoint.pth')
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']
**最佳实践:**定期保存模型检查点,包含额外信息(如训练轮次、优化器状态等)以便恢复训练。
**作用:**获取模型中所有可训练的参数。
# parameters() 返回参数迭代器
for param in model.parameters():
print(param.shape)
# named_parameters() 返回参数名称和值的迭代器
for name, param in model.named_parameters():
print(f"Layer: {name} | Size: {param.shape}")
**作用:**获取模型的直接子模块(不包括子模块的子模块)。
# children() 返回直接子模块的迭代器
for child in model.children():
print(child)
# named_children() 返回子模块名称和模块的迭代器
for name, child in model.named_children():
print(f"Child name: {name}\\nChild module: {child}\\n")
**作用:**获取模型的所有模块(包括子模块的子模块)。
# modules() 返回所有模块的迭代器
for module in model.modules():
print(module)
# named_modules() 返回模块名称和模块的迭代器
for name, module in model.named_modules():
print(f"Module name: {name}\\nModule: {module}\\n")
**作用:**通过名称获取特定的参数或子模块。
# 获取特定参数
param = model.get_parameter('conv1.weight')
# 获取特定子模块
submodule = model.get_submodule('encoder.layer1')
**作用:**向模型动态添加新的子模块。
# 添加新模块
model.add_module('new_layer', nn.Linear(100, 10))
# 实际应用示例
class DynamicModel(nn.Module):
def __init__(self):
super().__init__()
self.add_module('conv1', nn.Conv2d(1, 20, 5))
self.add_module('relu1', nn.ReLU())
**最佳实践:**在调试或修改模型结构时,使用这些方法可以方便地检查和操作模型的各个组件。
# float32
model = model.float()
# float16
model = model.half()
# bfloat16
model = model.bfloat16()
# float64
model = model.double()
# 使用混合精度训练
from torch.cuda.amp import autocast, GradScaler
# 初始化梯度缩放器
scaler = GradScaler()
# 训练循环
for batch_x, batch_y in train_loader:
# 使用自动混合精度
with autocast():
output = model(batch_x)
loss = criterion(output, batch_y)
# 使用梯度缩放器处理反向传播
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
**最佳实践:**对于大型模型,建议使用混合精度训练来平衡训练速度和模型性能。在推理阶段,可以根据具体需求选择合适的精度类型。
**作用:**将一个函数递归地应用到模型的每个子模块上。
# 权重初始化示例
def init_weights(m):
if isinstance(m, nn.Linear):
torch.nn.init.xavier_uniform_(m.weight)
m.bias.data.fill_(0.01)
# 应用到整个模型
model.apply(init_weights)
**作用:**将模型中所有可训练参数的梯度设置为零。通常在每次反向传播前调用。
在PyTorch中,梯度会默认累积。如果不清零,每次反向传播计算的梯度会与之前的梯度相加。这可能导致:
因此,在每次反向传播前调用zero_grad()来清零梯度是非常重要的。这样可以确保每个批次的梯度计算都是独立的,不受之前迭代的影响。
# 训练循环中使用
for batch_x, batch_y in train_loader:
optimizer.zero_grad() # 清零梯度
outputs = model(batch_x)
loss = criterion(outputs, batch_y)
loss.backward()
optimizer.step()
**作用:**设置模型参数是否需要计算梯度。用于微调或冻结某些层。
# 冻结所有参数
for param in model.parameters():
param.requires_grad_(False)
# 只训练最后几层
for param in model.classifier.parameters():
param.requires_grad_(True)
**最佳实践:**根据具体任务需求选择合适的方法,并在正确的时机调用这些方法以确保模型正常工作。