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

如何解决PyTorch中使用F1 Score作评估指标时的张量维度不匹配问题

错误原因与解决方案

第一次报错(形状不匹配)原因

  • 你的模型当前是单分类任务实现:使用了LogSoftmax激活+F.nll_loss损失,输入标签形状为[batch_size](每个样本仅对应一个类别)。
  • 你最初写的F_score是多标签任务逻辑:要求标签形状为[batch_size, 类别数](每个样本可对应多个类别),二者维度不匹配因此报错。

第二次报错(维度越界)原因

  • 修改后你通过torch.max(output, dim = 1)得到的预测结果prob是形状为[batch_size]的1维张量,但后续代码仍使用.sum(1)在第1维度求和,1维张量仅存在第0维度,因此触发索引越界。
  • 额外逻辑问题:单分类任务的F1计算逻辑和多标签完全不同,不能直接沿用多标签按类别维度求和的逻辑。

修正方案

方案1:确认是单分类任务(每个样本仅对应1个类别)

直接替换为单分类加权F1的实现即可,纯PyTorch实现代码如下:

def F_score(output, label, beta=1):
    # 取概率最高的类别作为预测结果
    pred = torch.argmax(output, dim=1)
    num_classes = output.shape[1]
    
    # 初始化每个类别的混淆矩阵指标
    class_tp = torch.zeros(num_classes, device=output.device)
    class_fp = torch.zeros(num_classes, device=output.device)
    class_fn = torch.zeros(num_classes, device=output.device)
    class_counts = torch.bincount(label, minlength=num_classes)
    
    for c in range(num_classes):
        class_tp[c] = ((pred == c) & (label == c)).sum()
        class_fp[c] = ((pred == c) & (label != c)).sum()
        class_fn[c] = ((pred != c) & (label == c)).sum()
    
    # 计算每个类别的precision、recall、F1
    precision = class_tp / (class_tp + class_fp + 1e-12)
    recall = class_tp / (class_tp + class_fn + 1e-12)
    class_f1 = (1 + beta**2) * precision * recall / (beta**2 * precision + recall + 1e-12)
    
    # 按类别样本数加权得到最终加权F1
    weighted_f1 = (class_f1 * class_counts / class_counts.sum()).sum()
    return weighted_f1

方案2:确认是多标签任务(每个样本可对应多个类别)

需要修改三处代码适配多标签逻辑:

  1. 模型最后一层的nn.LogSoftmax(dim = 1)替换为nn.Sigmoid()
  2. 验证步骤的损失函数从F.nll_loss(out, targets)替换为F.binary_cross_entropy(out, targets)
  3. 数据集的标签处理为[batch_size, 258]形状,每个位置用0/1表示样本是否属于对应类别
    修改完成后你最初写的多标签版本F_score即可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 12:06:08