【PyTorch训练】准确率计算(代码片段拆解)

发布于:2025-09-13 ⋅ 阅读:(23) ⋅ 点赞:(0)

标签:PyTorch, 准确率计算, 训练循环, 深度学习, 小白教程, 代码拆解

大家好。今天我们来聊聊PyTorch中一个常见的训练循环代码片段:

total_train += labels.size(0)  # 累加样本数量
correct_train += (predicted == labels).sum().item()  # 累加正确预测的数量

这个片段常出现在神经网络的训练或评估代码中。如果你是个深度学习小白,看到这个就“不懂”甚至“彻底懵逼”,别担心!这篇文章会从零基础一步步拆解清楚,用最通俗的语言、例子和代码让你彻底明白。读完后,你会知道它在计算准确率中的作用,为什么这么写,以及怎么在自己的模型中使用。

引言:这个代码在干什么?为什么重要?

在深度学习中,训练模型时,我们不只计算损失(loss),还要评估模型“猜对”了多少——这就是准确率(accuracy)。准确率 = 正确预测的数量 / 总样本数量。

但训练数据通常分成小批次(batch),比如DataLoader每次给32个样本。我们不能一次性算所有,得累加:每个batch算一点,最后汇总。

这个代码片段就是在做“累加”:

  • 第一行:累加当前batch的样本数量到总计数(total_train)。
  • 第二行:累加当前batch中正确预测的数量到正确计数(correct_train)。

最后,准确率 = correct_train / total_train * 100%。

为什么重要?它帮你监控训练过程:模型是否在进步?过拟合吗?没有这个,你就不知道模型性能,只看loss不够直观。在PyTorch项目中,这几乎是标准写法,常出现在epoch循环里。

1. 基础概念:PyTorch中的关键元素

先搞懂几个小白必知词,不然代码看不懂。

  • 张量(Tensor):PyTorch的“数组”。labels和predicted都是张量。

    • labels:真实标签,比如[0, 1, 2]表示三个样本的真实类别(0猫、1狗、2鸟)。
    • predicted:模型预测的标签,从前一篇文章的torch.max(outputs, 1)得到,比如[0, 1, 0](猜对了两个)。
  • DataLoader和Batch:训练数据分成小批次。labels.size(0)就是当前batch的大小(样本数),如32。

  • 累加(+=):像计数器。total_train从0开始,每batch加一点。

  • (predicted == labels):张量比较,返回布尔张量(如[True, True, False]),表示哪些猜对了。

  • .sum().item():sum()把True计数(True=1, False=0),item()转成Python数字。

这些是PyTorch的“魔法”,但其实很简单——就像Excel里的求和。

2. 代码详解:一行一行拆解

假设我们在训练循环中,已经有:

  • outputs = model(inputs) # 模型输出
  • _, predicted = torch.max(outputs, 1) # 获取预测(从上篇文章)
  • loss = criterion(outputs, labels) # 计算损失

现在进入这个片段:

第一行:total_train += labels.size(0) # 累加样本数量

  • labels.size(0):获取labels张量的第一个维度大小。通常labels是1D张量[batch_size],size(0)就是batch_size(当前批次样本数)。
  • +=:把这个数加到total_train(一个变量,初始化为0)。
  • 作用:记录总共处理了多少训练样本。为什么?因为准确率的分母是总样本。
  • 示例:如果batch_size=32,这行相当于total_train = total_train + 32。

第二行:correct_train += (predicted == labels).sum().item() # 累加正确预测的数量

  • (predicted == labels):逐元素比较两个张量,返回布尔张量(形状同predicted)。如predicted=[0,1,2], labels=[0,1,0] → [True, True, False]。
  • .sum():把布尔转数字求和(True=1),结果是张量,如tensor(2)。
  • .item():从张量取值,转成普通Python int,如2。
  • +=:加到correct_train(初始化为0)。
  • 作用:记录总共猜对了多少。准确率的分子。
  • 示例:上面例子加2到correct_train。

完整循环后:accuracy = correct_train / total_train(通常在epoch结束时计算)。

为什么.item()? 因为sum()返回张量,+=需要Python数字。item()“解包”它。

3. 实际例子:从代码到准确率

假设一个小batch:

  • labels = torch.tensor([0, 1, 2]) # 真实:样本1类0,样本2类1,样本3类2

  • predicted = torch.tensor([0, 1, 0]) # 预测:对了前两个,第三个错了

  • 第一行:labels.size(0) = 3 → total_train += 3(假设之前是0,现在=3)

  • 第二行:(predicted == labels) = [True, True, False] → sum()=2 → item()=2 → correct_train += 2(现在=2)

如果这是唯一batch,准确率=2/3 ≈ 66.7%。

多个batch累加类似:总total_train=所有batch大小之和,correct_train=所有正确之和。

4. 代码示例:用PyTorch完整演示训练循环片段

咱们写个小脚本,模拟一个epoch的准确率计算。需要PyTorch(pip install torch)。

import torch

# 初始化累加器
total_train = 0
correct_train = 0

# 模拟第一个batch
labels1 = torch.tensor([0, 1, 2])
predicted1 = torch.tensor([0, 1, 0])
total_train += labels1.size(0)  # +3
correct_train += (predicted1 == labels1).sum().item()  # +2

# 模拟第二个batch
labels2 = torch.tensor([3, 4])
predicted2 = torch.tensor([3, 4])
total_train += labels2.size(0)  # +2,现在total=5
correct_train += (predicted2 == labels2).sum().item()  # +2,现在correct=4

# 计算准确率
accuracy = correct_train / total_train * 100 if total_train > 0 else 0
print("总样本:", total_train)  # 5
print("正确数:", correct_train)  # 4
print("准确率:", accuracy, "%")  # 80.0 %

运行这个,你会看到累加过程!在真实模型中,这放在for batch in train_loader: 循环里,每个epoch重置累加器。

5. 常见困惑解答(小白专区)

  • 为什么用size(0),不是len(labels)? size(0)是PyTorch张量方法,更安全(labels可能是多维)。len()也行,但不推荐。
  • predicted和labels形状必须一样吗? 是的,都是[batch_size]的1D张量。
  • 如果batch_size不同? 没问题,+=会自动处理。
  • 训练 vs. 测试? 类似,但测试用total_test, correct_test。训练时可能不计算(只看loss),但常加来监控。
  • .sum().item()报错? 确保predicted和labels是同类型张量,且在CPU(item()在GPU张量上也行,但安全起见to(‘cpu’))。
  • 布尔sum怎么算? PyTorch自动把True当1,False当0。
  • 为什么不直接accuracy每batch算? 因为要整体准确率,累加更高效,尤其是大数据集。
  • 截图颜色:黑蓝绿? 黑是代码,蓝是变量/函数,绿是注释——IDE高亮帮你快速看懂。

结语:从小白到自信计算准确率

这个代码片段不是复杂逻辑,只是“计数器”:累加总样本和正确预测,用来算准确率。理解了张量比较和累加,你就能在任何PyTorch训练循环中使用它。结合上两篇文章(torch.max和雅可比),你已经掌握了从预测到评估的核心!