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

调用Multiclass Accuracy的compute前未调用update导致指标为0

问题描述

使用torchmetrics的MulticlassAccuracy等指标时,出现警告提示compute方法在update方法之前被调用,同时所有准确率类指标输出均为0。

训练代码片段

def _train_one_epoch(self, epoch: int) -> None:
    self.model.train()
    train_running_loss = 0.0
    training_progress = 0
    # len of all batches
    total_batches = (
        len(self.dataset_config.train_data) // self.training_config.batch_size
    )
    for inputs, labels in self.train_loader:
        # progress bar
        training_progress += 1
        print(
            f"Training Progress: [-- {training_progress/total_batches*100:.2f}% --] in epoch: {epoch} from {self.training_config.epochs} epochs",
            end="\r",
        )
        # move the inputs and labels to device
        inputs = inputs.to(self.training_config.device)
        labels = labels.to(self.training_config.device)
        # zero the parameter gradients
        self.optimizer.zero_grad()
        # forward pass
        outputs = self.model(inputs)
        # calculate the loss
        loss = self.training_config.criterion(outputs, labels)
        # backward pass
        loss.backward()
        # update the weights
        self.optimizer.step()
        # Calculate the metrics
        train_running_loss += loss.item() * inputs.size(0)
        preds = torch.argmax(outputs, dim=1)
    train_epoch_loss = train_running_loss / len(self.dataset_config.train_data)

    # Metrics on all valid data
    train_accuracy = self.accuracy.compute()
    train_precision = self.precision.compute()
    train_recall = self.recall.compute()
    train_f1_score = self.f1_score.compute()
    self.writer.add_scalar("Training/Loss", train_epoch_loss, epoch)
    self.writer.add_scalar("Training/Accuracy", train_accuracy, epoch)
    self.writer.add_scalar("Training/Precision", train_precision, epoch)
    self.writer.add_scalar("Training/Recall", train_recall, epoch)
    self.writer.add_scalar("Training/F1", train_f1_score, epoch)
    # Reset the metrics
    self.accuracy.reset()
    self.precision.reset()
    self.recall.reset()
    self.f1_score.reset()

警告及输出内容

/home/sadegh/miniconda3/envs/ml/lib/python3.11/site-packages/torchmetrics/utilities/prints.py:36: UserWarning: The ``compute`` method of metric MulticlassAccuracy was called before the ``update`` method which may lead to errors, as metric states have not yet been updated.
  warnings.warn(*args, **kwargs)
/home/sadegh/miniconda3/envs/ml/lib/python3.11/site-packages/torchmetrics/utilities/prints.py:36: UserWarning: The ``compute`` method of metric MulticlassPrecision was called before the ``update`` method which may lead to errors, as metric states have not yet been updated.
  warnings.warn(*args, **kwargs)
/home/sadegh/miniconda3/envs/ml/lib/python3.11/site-packages/torchmetrics/utilities/prints.py:36: UserWarning: The ``compute`` method of metric MulticlassRecall was called before the ``update`` method which may lead to errors, as metric states have not yet been updated.
  warnings.warn(*args, **kwargs)
/home/sadegh/miniconda3/envs/ml/lib/python3.11/site-packages/torchmetrics/utilities/prints.py:36: UserWarning: The ``compute`` method of metric MulticlassF1Score was called before the ``update`` method which may lead to errors, as metric states have not yet been updated.
  warnings.warn(*args, **kwargs)
Validation Progress: [-- 9.68% --] in epoch: 8 from 25 epochs Epoch: 8/25 | Valid Loss: 1.9874 | Valid Accuracy: 0.0000 | Valid Precision: 0.0000 | Valid Recall: 0.0000 | Valid F1: 0.0000

查看torchmetrics文档后发现示例中并未调用update方法,请问问题出在哪里?


问题原因及解决办法

核心问题

你没有调用指标的update()方法来累积每个batch的预测结果和真实标签。torchmetrics的指标需要通过update()更新内部状态,之后compute()才能计算出正确的全局指标值。

文档示例没显式调用update(),是因为很多示例采用了自动更新的场景:

  • 将指标作为torch.nn.Module的一部分,通过直接调用指标实例(触发__call__方法)自动执行update
  • 结合MetricCollection或PyTorch Lightning等框架时,框架会自动处理指标更新逻辑

而你的代码是手动管理指标实例,必须显式调用update()。

修正代码

在每个batch的循环内,计算出preds之后,添加指标更新操作:

# Calculate the metrics
train_running_loss += loss.item() * inputs.size(0)
preds = torch.argmax(outputs, dim=1)
# 新增:更新各指标的内部状态
self.accuracy.update(preds, labels)
self.precision.update(preds, labels)
self.recall.update(preds, labels)
self.f1_score.update(preds, labels)

修改后,每个batch的预测和标签数据会被传入指标累积计算,后续调用compute()就能得到正确的epoch指标值,警告也会消失。

内容的提问来源于stack exchange,提问作者sadegh-pz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:09:53