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

XLM-Roberta文本二分类训练中计算训练准确率报错解决方案

报错原因

核心问题是API混用:你在执行准确率计算逻辑前,已经通过.numpy()把logits从PyTorch张量转换为NumPy数组,而.float()是PyTorch张量的专属类型转换方法,NumPy数组不存在这个方法,因此触发AttributeError。
除此之外代码还有3处逻辑问题,即使修复这个报错也无法得到正确的训练准确率:

  • 二分类场景下,初始化XLM-Roberta时如果设置num_labels=2,模型输出的logits形状为(batch_size, 2),分别对应两个类别的原始输出得分,直接和0.5做阈值比较的逻辑完全不成立。
  • 统计正确数的correct变量定义在batch循环内部,循环结束后你拿到的只是最后一个batch的正确样本数,不是整个epoch的累计正确数。
  • 准确率分母用了len(train_dataloader)(即训练集的batch总数),而不是训练集总样本量,计算结果完全不符合准确率定义。
修复方法
  1. 调整代码执行顺序:先在PyTorch张量层面完成预测值计算、正确数统计,需要做其他NumPy相关操作时再转数组,避免混用两套API。
  2. 修正二分类输出处理逻辑:对两维的logits做softmax计算,取正类(标签为1)的概率做阈值判断,或者直接取argmax得到预测标签。
  3. 修正准确率统计逻辑:在epoch循环外初始化全局正确数、总样本数的统计变量,每个batch计算完后累加,epoch结束后用总正确数除以总样本数得到真实准确率,统计完后重置变量供下一个epoch使用。

对应修改后的核心代码片段如下:

#  epoch循环开始前初始化统计变量
correct_train = 0
total_train = 0

for epoch in range(0, epochs):
    # ...... 其他原有代码不变 ......
    for i, batch in enumerate(train_dataloader):
        # ...... 前面的输入加载、前向传播代码不变 ......
        outputs = model(b_input_ids, 
                  attention_mask=b_input_mask, 
                  labels=b_labels)
        model.zero_grad()        
        loss = outputs[0]
        logits = outputs[1]

        #  ========== 准确率计算部分修改开始 ==========
        #  先在PyTorch张量层面计算预测结果
        #  二分类num_labels=2时用下面这行,取正类概率做阈值判断
        pred_labels = (torch.softmax(logits, dim=1)[:, 1] > 0.5).long()
        #  如果你设置num_labels=1用BCE损失,就换成下面这行
        # pred_labels = (torch.sigmoid(logits.squeeze()) > 0.5).long()
        
        #  累加当前batch的正确数和样本数
        correct_train += (pred_labels == b_labels).sum().item()
        total_train += b_labels.size(0)
        #  ========== 准确率计算部分修改结束 ==========

        #  统计完准确率再转NumPy,不影响其他逻辑
        logits = logits.detach().cpu().numpy()
        label_ids = b_labels.to('cpu').numpy()

        # ...... 后面的反向传播、参数更新代码不变 ......

    # epoch结束后打印准确率,之后重置统计变量
    print('Train loss:', total_train_loss)
    print('Train acc:', 100 * correct_train / total_train)
    print("  Training epoch took: {:}".format(training_time))
    correct_train = 0
    total_train = 0

如果你想用NumPy语法写准确率计算逻辑也可以,把.float()换成NumPy的类型转换写法(logits>0.5).astype(np.float32)即可,但还是建议优先修正前面说的logits维度问题,否则结果依然错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:27:14