You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中CNN分类器训练时各Epoch准确率计算异常求助

解决PyTorch CNN训练中Epoch准确率计算错误的问题

嘿,我一眼就看出问题啦——你现在计算训练准确率的时候,只用到了最后一个batch的outputs和labels,根本没把整个epoch里所有样本的预测结果累积起来!这就是为啥准确率总是在0、0.25、0.75这种奇怪的数值跳来跳去,完全反映不了模型在整个训练集上的真实表现。

下面是具体的修复方案,包含训练准确率和测试准确率的正确计算方式:

1. 调整训练阶段的准确率计算逻辑

我们需要在每个epoch内,对所有batch的预测结果进行累积统计,而不是只取最后一个batch的数据。修改后的代码如下:

def get_accuracy(pred, actual):
    assert len(pred) == len(actual)
    _, predicted = torch.max(pred.data, 1)
    correct = (predicted == actual).sum().item()
    return correct, len(actual)  # 修改:返回正确数和样本数,方便累积统计

def train_model(model, trainloader, testloader, criterion, optimizer, epochs, device):
    for epoch in range(epochs):
        model.train()  # 切换到训练模式,启用Dropout/BatchNorm等训练特有的层
        running_loss = 0.00
        total_correct_train = 0
        total_samples_train = 0

        for i, data in enumerate(trainloader, 0):
            inputs, labels = data
            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()
            batch_correct, batch_total = get_accuracy(outputs, labels)
            total_correct_train += batch_correct
            total_samples_train += batch_total

        # 计算整个epoch的平均损失和训练准确率
        avg_loss = running_loss / len(trainloader)
        training_accuracy = total_correct_train / total_samples_train * 100  # 转成百分比格式

        # 计算测试准确率
        test_accuracy = calculate_test_accuracy(model, testloader, device)

        # 打印结果
        print('='*10, f'Iteration: {epoch+1}', '='*10)
        print(f'\nLoss: {avg_loss:.4f} \nTraining accuracy: {training_accuracy:.2f}% \nTest accuracy: {test_accuracy:.2f}%')
    
    print('Finished Training')

2. 实现测试准确率的计算函数

测试阶段需要关闭梯度计算(避免不必要的资源消耗),同时确保模型处于评估模式(禁用Dropout、固定BatchNorm统计量):

def calculate_test_accuracy(model, testloader, device):
    model.eval()  # 切换到评估模式
    total_correct_test = 0
    total_samples_test = 0

    with torch.no_grad():  # 关闭梯度计算,节省内存和计算时间
        for data in testloader:
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device)
            outputs = model(inputs)
            batch_correct, batch_total = get_accuracy(outputs, labels)
            total_correct_test += batch_correct
            total_samples_test += batch_total
    
    return (total_correct_test / total_samples_test) * 100  # 返回百分比形式的准确率

关键修改点说明

  • 准确率累积:不再只取最后一个batch的结果,而是在每个batch中统计正确数和样本数,最终用整个epoch的总正确数除以总样本数,得到真实的训练准确率。
  • 模型模式切换:训练时用model.train(),测试时用model.eval(),确保模型层的行为符合当前阶段的需求。
  • 梯度关闭:测试阶段用torch.no_grad(),避免计算梯度,大幅降低内存占用和计算耗时。

这样修改后,你就能得到每个epoch真实的训练准确率和测试准确率了,不会再出现那种奇怪的固定数值啦!

内容的提问来源于stack exchange,提问作者inferense

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:37:49