趋近智
为了客观评估模型在训练阶段后的表现,一种可靠的方法必不可少。仅凭训练损失可能产生误导,因为模型可能在训练数据上表现出色,但无法泛化到新的、未见过的数据。评估循环可以解决这一挑战。它的作用是衡量模型在独立数据集(如验证集或测试集)上的表现,这些数据未在权重 (weight)更新过程中使用。
训练涉及根据训练数据调整模型参数 (parameter)。然而,评估纯粹是为了评测。我们想回答:“给定此输入,模型的预测与实际目标有多接近?”同时不改变模型本身。执行评估需要一个独特的流程,原因有以下几点:
评估循环与训练循环有相似之处(例如,遍历数据,执行前向传播),但存在重要区别:
$loss.backward()。$optimizer.step()和$optimizer.zero_grad()。model.eval()PyTorch 模型(nn.Module)有不同的训练和评估模式。你可以使用model.train()和model.eval()在它们之间切换。在开始评估循环之前调用model.eval()非常重要。此调用会通知Dropout和Batch Normalization等层,模型正处于评估阶段。
评估结束后,如果你计划恢复训练(例如,在每个周期后进行评估),请记得使用model.train()将模型切换回训练模式。
torch.no_grad()为防止PyTorch在评估期间跟踪操作并构建用于梯度计算的计算图,你应该将评估循环代码封装在torch.no_grad()上下文 (context)管理器中。
with torch.no_grad():
# 这里是评估代码...
# 此块中的操作将不会跟踪梯度。
使用torch.no_grad()主要有两个优点:
以下是评估函数的一个典型结构:
import torch
def evaluate_model(model, dataloader, criterion, device):
"""在提供的datasets上评估模型。"""
model.eval() # 将模型设置为评估模式
total_loss = 0.0
correct_predictions = 0
total_samples = 0
with torch.no_grad(): # 禁用梯度计算
for inputs, targets in dataloader:
# 将数据移动到与模型相同的设备上
inputs = inputs.to(device)
targets = targets.to(device)
# 前向传播
outputs = model(inputs)
# 计算损失(可选,但对监控有用)
loss = criterion(outputs, targets)
total_loss += loss.item() * inputs.size(0) # 累加批次损失
# 计算准确率(分类示例)
_, predicted_labels = torch.max(outputs, dim=1)
correct_predictions += (predicted_labels == targets).sum().item()
total_samples += targets.size(0)
# 计算整个数据集的平均损失和准确率
average_loss = total_loss / total_samples
accuracy = correct_predictions / total_samples
model.train() # 如果之后需要,切换回训练模式
return average_loss, accuracy
# --- 用法示例 ---
# 假设你已经有:
# model: 你的 nn.Module 模型
# validation_loader: 你的验证集 DataLoader
# criterion: 你的损失函数(例如,nn.CrossEntropyLoss)
# device: torch.device('cuda' if torch.cuda_is_available() else 'cpu')
# val_loss, val_accuracy = evaluate_model(model, validation_loader, criterion, device)
# print(f'Validation Loss: {val_loss:.4f}, Validation Accuracy: {val_accuracy:.4f}')
分步解析:
model.eval(): 将模型切换到评估模式。with torch.no_grad():: 进入不计算梯度的上下文 (context)。DataLoader提供的批次。outputs = model(inputs))。loss.item()获取当前批次损失的Python标量值,并在累加前乘以批次大小(inputs.size(0)),以处理最后一个批次大小可能存在的差异。torch.max获取最高概率的索引)。将预测与真实目标进行比较,并累加正确预测的数量和总样本数。model.train()(可选): 如果此评估发生在训练周期之间,将模型切换回训练模式。此评估循环为模型的泛化表现提供了必要的反馈,指导训练过程并帮助你构建更高效的深度学习 (deep learning)模型。同时监控这些评估指标和训练指标对理解模型行为非常重要。
此图显示了一个常见情况:在若干个周期后,验证损失开始增加,这表明过拟合 (overfitting)已经出现,即使训练损失持续下降。评估循环对于检测这种情况非常重要。
典型的深度学习训练流程,在每个训练周期后加入评估,以监控表现并决定是否继续或停止训练。
这部分内容有帮助吗?
torch.no_grad(), PyTorch Documentation, 2017 (PyTorch Foundation) - 官方 PyTorch 文档,解释了在评估期间使用 torch.no_grad() 进行内存和计算效率优化的目的和用法,以及 model.eval() 将模型层设置为推理模式。© 2026 ApX Machine LearningAI伦理与透明度•