文章目录
- 1、指标评估整体介绍
- [2、 `torchmetrics` 文本分类指标 - 通用](#2、
torchmetrics文本分类指标 - 通用) - [3、`torchmetrics` 文本分类指标 - 多分类](#3、
torchmetrics文本分类指标 - 多分类) - [4、准确率、精确率、召回率、F1分数 及其 类](#4、准确率、精确率、召回率、F1分数 及其 类)
- [5、`torchmetrics` - Accuracy 详解(准确率)](#5、
torchmetrics- Accuracy 详解(准确率)) - [6、`torchmetrics` 模块式 metric - 常用 属性、方法](#6、
torchmetrics模块式 metric - 常用 属性、方法)
torchmetrics堪称模型评估界的"绝世秘籍",招式精妙且威力无穷。若想真正参透其中玄机、融会贯通,列位看官莫急,且听我细细拆解。这是
torchmetrics系列文章的第一篇。
1、指标评估整体介绍
【 metric n.度量标准 】 【 metrics n.指标 】 【 matrix n.矩阵 】
📚 TorchMetrics 是什么?
TorchMetrics 最初是 PyTorch Lightning 的一部分,后来独立出来。它是一个专为 PyTorch 设计的模型评估指标库,旨在解决机器学习中指标实现不一致的问题,提供标准化、可重复的参考实现。
它不仅是 sklearn.metrics 在 PyTorch 生态中的优秀替代品,更提供了强大的分布式训练支持。其核心使命是提供标准化、可扩展、易于复现的评估方式。
主要特点:
- 标准化接口 :提供统一的
update()和compute()接口,增加了不同项目和实验间的可复现性(Reproducibility)。 - 自动累积与同步:自动处理跨 batch 的指标累积和多设备间的同步,非常适合大规模评估。
- 设备兼容与优化 :指标和数据会自动放置在相同设备(CPU/GPU)上,得益于原生PyTorch实现,其计算速度通常快于
sklearn。 - 减少样板代码:封装了状态管理、设备同步等复杂逻辑,让代码更简洁。
- 指标丰富且可扩展:内置超过100种评估指标,覆盖广泛领域,同时也易于创建自定义指标。
🚀 安装与首个示例
安装非常简单,推荐使用 pip 或 conda:
bash
# pip 安装
pip install torchmetrics
# conda 安装
conda install -c conda-forge torchmetrics
注意 :本文章的代码基于 TorchMetrics v1.0 及以上版本 。早期版本在指标初始化时可不强制传入
task等参数,而新版本为保障行为明确,通常要求显式指定任务类型。建议使用最新版,并养成显式传参的习惯。
安装后,可以用下面几个示例快速体验。它们演示了计算、累积和分布式三种核心用法。
- 函数式接口(快速计算)
适合单次、无状态的计算,用法类似 sklearn.metrics。
python
import torch
import torchmetrics
# 模拟分类问题的预测分数和真实标签
preds = torch.randn(10, 5).softmax(dim=-1) # 5类概率
target = torch.randint(5, (10,)) # 真实类别索引
# 直接调用函数计算准确率(需指明任务类型及类别数)
acc = torchmetrics.functional.accuracy(
preds, target, task='multiclass', num_classes=5
)
print(acc)
- 模块化接口(状态管理)
这是 TorchMetrics 的核心用法。内部维护状态,能自动管理跨 batch 的累计,非常适合训练循环。
在 TorchMetrics 库中,torchmetrics.Metric 是所有内置指标(如 Accuracy, Precision, F1Score 等)以及用户自定义指标的抽象基类(Abstract Base Class)。
python
import torch
import torchmetrics
# 初始化一个指标对象,显式指定 task 和 num_classes
metric = torchmetrics.Accuracy(task='multiclass', num_classes=5)
n_batches = 10
for i in range(n_batches):
preds = torch.randn(10, 5).softmax(dim=-1)
target = torch.randint(5, (10,))
# 每次调用,指标对象内部会积累统计量(如正确数、总数)
# 这里直接调用对象(等价于 metric.update(preds, target) 然后返回当前累积结果)
acc = metric(preds, target)
print(f"Accuracy on batch {i}: {acc:.4f}")
# 在所有 batch 计算完毕后,调用 .compute() 得到全局结果
total_acc = metric.compute()
print(f"Accuracy on all data: {total_acc:.4f}")
# 重置状态,为下一个 epoch 或评估周期做准备
metric.reset()
- 在 PyTorch Lightning 中使用(自动日志记录)
与 PyTorch Lightning 深度集成,能自动完成指标的状态重置和日志记录,代码极为简洁。
python
import torch
import torchmetrics
import pytorch_lightning as pl
class MyModel(pl.LightningModule):
def __init__(self, num_classes=10):
super().__init__()
# 同样需要指定任务参数,假设为10类分类问题
self.accuracy = torchmetrics.Accuracy(task='multiclass', num_classes=num_classes)
def training_step(self, batch, batch_idx):
x, y = batch
preds = self(x) # 假设输出 logits,shape (batch, num_classes)
loss = torch.nn.functional.cross_entropy(preds, y)
preds_probs = preds.softmax(dim=-1) # 指标通常期望概率或 logits
self.accuracy(preds_probs, y)
# on_epoch=True 会自动累积并记录整个 epoch 的指标
self.log('train_acc', self.accuracy, on_step=False, on_epoch=True)
return loss
def on_train_epoch_end(self):
# Lightning 会在 epoch 结束时自动调用 metric.reset(),无需手动操作
pass
⚙️ 核心设计:两个主要接口与工作流程
TorchMetrics 提供了两种主要的使用方式,以适应不同场景。
- 函数式接口 (Functional Interface) :
torchmetrics.functional下的函数,无状态,直接输入张量进行计算,并立即返回结果。适合快速实验、单次评估。 - 模块式接口 (Module Interface) :继承自
torch.nn.Module的类,有状态。优势包括:- 跨 batch 累积统计量,最后通过
compute()一次性算出全局结果; - 设备移动时自动同步内部状态;
- 可直接作为模型的一部分,或配合
MetricCollection一起使用。
调用metric(preds, target)会内部执行update()并返回当前的累积结果(如果调用时不需要立即显示,也可以手动调用metric.update(preds, target)先累积)。
- 跨 batch 累积统计量,最后通过
- 典型工作流程 :
- 实例化与设备移动 : 创建指标对象(如
metric = torchmetrics.Accuracy(task='multiclass', num_classes=10).cuda()),与模型移动到同一设备。 - 迭代更新 : 在每个 batch 中调用
metric(preds, target)或metric.update(preds, target)累积状态。 - 结果计算 : epoch 结束时调用
metric.compute()获取累计后的最终指标。 - 状态重置 : 调用
metric.reset()清理内部状态,为下一轮评估做准备。
- 实例化与设备移动 : 创建指标对象(如
🗂️ 指标全景:分类纵览
TorchMetrics 提供了覆盖各种深度学习任务的超过100种指标。以下是按任务分类的部分常用指标:
| 任务类别 | 常用指标 |
|---|---|
| 分类 | Accuracy, Precision, Recall, F1Score, FBetaScore, AUROC, AveragePrecision, ConfusionMatrix, MatthewsCorrCoef |
| 回归 | MeanSquaredError (MSE), MeanAbsoluteError (MAE), R2Score, MeanSquaredLogError (MSLE), PearsonCorrCoef, SpearmanCorrCoef |
| 图像 | PeakSignalNoiseRatio (PSNR), StructuralSimilarityIndexMeasure (SSIM), FrechetInceptionDistance (FID), LearnedPerceptualImagePatchSimilarity (LPIPS) |
| 文本 | BLEUScore, ROUGEScore, Perplexity, WER, BERTScore (需安装 bert-score 包) |
| 音频 | SignalNoiseRatio (SNR), SignalDistortionRatio (SDR), PerceptualEvaluationOfSpeechQuality (PESQ) |
| 检索 | RetrievalMAP, RetrievalMRR, RetrievalNormalizedDCG, RetrievalPrecision, RetrievalRecall |
| 目标检测 | MeanAveragePrecision (mAP) |
| **其他/包装器 ** | MetricCollection, ClasswiseWrapper, MultioutputWrapper, Bootstrapper等实用工具 |
分类指标详解
Accuracy:计算所有样本中正确分类的比例。Precision和Recall:分别衡量模型预测正类的准确性(精确率)和模型找出所有正类的能力(召回率)。对于多分类,可通过average参数选择macro,micro,weighted等平均方式。F1Score/FBetaScore:Precision和Recall的调和(或加权调和)平均值,FBetaScore通过beta参数可以更偏重Precision或Recall。AUROC/ROC:ROC计算曲线数据(假阳性率与真阳性率),AUROC计算其下方面积,衡量模型在不同阈值下的综合排序能力。输入通常是正类的概率或 logits(不是整数标签)。ConfusionMatrix:提供模型在每个类别上表现的详细视图。- 输入格式提醒 :分类指标通常期望预测为 概率、logits 或类别索引 ,具体取决于任务设置。例如
multiclass任务下,preds可以是概率矩阵([N, C])或类别索引([N]);binary任务下preds一般是概率向量([N])或类别索引。建议统一将概率传入,以避免歧义。
回归指标详解
MeanSquaredError(MSE):预测值与真实值之差平方的期望值,对大误差敏感。MeanAbsoluteError(MAE):预测值与真实值之差绝对值的期望值,对异常值更鲁棒。R2Score(R²) :衡量模型解释目标变量方差的程度,越接近1效果越好。输入要求preds和target形状一致。
🔧 自定义指标
你可以通过继承 torchmetrics.Metric 类来创建自定义指标。主要步骤包括:
- 在
__init__方法中调用self.add_state(...)注册内部状态(如正确数、总数)。 - 实现
update(self, preds, target)方法,从每个 batch 的数据中更新状态。 - 实现
compute(self)方法,基于累积的状态计算并返回最终指标。
这是一个简单的自定义准确率示例:
python
import torch
from torchmetrics import Metric
class MyAccuracy(Metric):
def __init__(self):
super().__init__()
# dist_reduce_fx='sum' 表示在分布式评估时,该状态会在不同进程间求和
self.add_state("correct", default=torch.tensor(0), dist_reduce_fx="sum")
self.add_state("total", default=torch.tensor(0), dist_reduce_fx="sum")
def update(self, preds: torch.Tensor, target: torch.Tensor):
# 假设 preds 和 target 都是类别索引且 shape 为 (batch_size,)
assert preds.shape == target.shape
self.correct += torch.sum(preds == target)
self.total += target.numel()
def compute(self):
return self.correct.float() / self.total
✨ 高级特性:MetricCollection
当需要同时计算多个指标时,可以使用 MetricCollection 将它们组合在一起。它能高效地处理参数的传递和结果的整合。
python
import torch
from torchmetrics import MetricCollection, Accuracy, Precision, Recall, F1Score
# 将所有需要的指标放入一个 MetricCollection,并显式指定任务参数
# 这里假设是二分类任务,输入是概率或类别索引
metrics = MetricCollection({
'acc': Accuracy(task='binary'),
'precision': Precision(task='binary'),
'recall': Recall(task='binary'),
'f1': F1Score(task='binary')
})
# 模拟一个batch的二分类数据
preds = torch.rand(100) # 正类的概率 [0,1]
target = torch.randint(0, 2, (100,))
# 一次性计算所有指标
result = metrics(preds, target)
print(result) # 例如 {'acc': 0.52, 'precision': 0.48, 'recall': 0.51, 'f1': 0.49}
🔬 TorchMetrics vs. Scikit-learn Metrics
- 设计哲学与框架依赖 :
sklearn.metrics设计简洁,输入通常是 NumPy 数组或 Python 列表;TorchMetrics原生支持 PyTorch 张量,与训练流程无缝集成。 - 计算性能 :原生 PyTorch 实现使其能直接在 GPU 上计算,避免 CPU-GPU 数据传输。有基准测试表明其计算速度比
sklearn更快。 - 分布式训练支持 :
TorchMetrics专为此设计,能跨多卡、多机自动同步和归并指标,而sklearn.metrics在分布式计算中需要手动实现,容易导致错误。 - 数值精度:由于底层实现和浮点数精度,两者可能存在微小差异(通常在 1e-7 量级),但这对模型的相对比较和选择没有实质影响。
- 使用体验 :在 PyTorch 中,
TorchMetrics免去了将张量转为 NumPy 的步骤,且支持累积计算,代码更简洁且不易出错。
💡 最佳实践与注意事项
- 正确管理状态 :遵循实例化 → 累积 → 计算 → 重置的工作流。在 PyTorch Lightning 中,如果你使用
self.log并传入了一个Metric对象,Lightning 会在每个 epoch 结束时自动调用metric.reset();但在自定义 PyTorch 训练循环中,务必在每个 epoch 开始前或结束后手动调用metric.reset(),否则指标会跨 epoch 累积,导致结果错误。 - 生命周期管理 :指标对象旨在维护内部状态,不应在每个 batch 上重新初始化。通常在模型
__init__或外层循环前创建一次,反复使用。 - 正确指定任务参数 :使用分类指标时,必须根据实际情况明确指定
task参数。例如:- 多分类(互斥类别)使用
task='multiclass'并设置num_classes。 - 二分类使用
task='binary'。 - 多标签分类使用
task='multilabel'并设置num_labels。 - 还需要按需设置
average(如'macro','micro','weighted')等参数。参数缺失或错误会直接导致计算异常。
- 多分类(互斥类别)使用
- 数值比较的容错 :进行精确比较时,建议设置一个误差范围(如
1e-6),而不是直接进行相等比较,以避免浮点误差带来的误判。 - 选择合适的接口:根据场景选择接口。简单评估可使用函数式接口;复杂的训练和验证循环中,建议使用模块化接口;使用PyTorch Lightning时,模块化接口可获得最佳体验。
💎 总结
TorchMetrics 是 PyTorch 生态中一个成熟、高效且可靠的模型评估工具。它通过标准化的接口、出色的设备兼容性和对分布式训练的完美支持,解决了 PyTorch 模型评估中的多个痛点,能帮助开发者编写更健壮、可复现的代码,专注于模型研发。
2、 torchmetrics 文本分类指标 - 通用
针对文本分类任务,选择指标的关键在于你的数据分布是否均衡 以及任务的容错率。简单来说,不能只看准确率(Accuracy),以下是你必须关注的核心指标组合:
- 基础"三剑客" (必选)
无论什么文本分类任务,这三个指标通常是一起看的,用来综合评估模型表现:
- 精确率 (Precision) :"查得准不准?"
- 含义:模型预测为"正类"的样本中,有多少是真的?
- 场景 :比如垃圾邮件检测。你非常不希望把正常邮件误判为垃圾邮件(误杀),这时候就要看 Precision。
- 召回率 (Recall) :"查得全不全?"
- 含义:所有真实的"正类"样本中,有多少被模型找出来了?
- 场景 :比如疾病诊断 或违规内容识别。你绝对不能漏掉任何一个真正的病人或违规贴,宁可错杀不可放过,这时候 Recall 最重要。
- F1-Score :"综合得分"
- 含义:精确率和召回率的调和平均数。
- 作用 :当 Precision 和 Recall 互相打架(一个高一个低)时,F1 能给你一个平衡的参考。这是最常用于汇报的指标之一。
- 多分类专用指标 (进阶)
如果文本分类不止两类(比如新闻分类:体育、财经、娱乐...),你需要关注聚合方式:
- Macro-F1 :把所有类别的 F1 算出来取平均值。
- 特点 :平等对待每个类别。如果你关心"娱乐"这种小类别的效果是否和"体育"大类别一样好,看这个。
- Micro-F1 :先统计全局的 TP/FP/FN,再算 F1。
- 特点 :受大类影响大。如果数据集里 90% 都是体育新闻,Micro-F1 基本就反映了模型在体育新闻上的表现。
- 特殊场景指标
- 混淆矩阵 (Confusion Matrix) :
- 这不是一个单一数值,而是一张表。当你发现模型效果不好时,用它来抓虫。比如你会发现模型经常把"正面情绪"误判为"中性情绪",但在其他类别上很准。
- AUC-ROC :
- 如果你的数据极度不平衡(比如 99% 是正常评论,1% 是恶意攻击),单纯看 Accuracy 会骗人(全猜正常也有 99% 准确率)。这时候 AUC 能更客观地反映模型的排序能力。
📌 总结建议
- 如果是均衡数据(各类文章数量差不多) :重点关注 Accuracy 和 Macro-F1。
- 如果不均衡(有的类很少) :忽略 Accuracy,死磕 Macro-F1 和 Recall。
- 如果需要向老板汇报 :直接报 F1-Score 或 Top-1 Accuracy。
3、torchmetrics 文本分类指标 - 多分类
针对你的任务------单样本属于10个互斥标签中的一个 (这在机器学习中称为多分类任务),评估指标的选择非常有讲究。
简单来说,你不能只看准确率(Accuracy),因为它容易掩盖模型在"少数类"上的无能。以下是为你整理的核心指标组合:
- 必看的综合指标:Macro-F1 Score
这是多分类任务中最"硬核"的指标。
- 为什么选它?
- 如果你有10个标签,其中"标签A"有900条数据,"标签B"只有10条。如果模型把所有样本都预测为"标签A",它的准确率(Accuracy)高达90%,看起来很美,但实际上它完全学不会识别"标签B"。
- Macro-F1 会先计算每个标签的 F1 分数,然后取平均值。这意味着小类别的表现和大类别一样重要。如果 Macro-F1 很高,说明模型对这10个类别都有不错的识别能力,没有"偏科"。
- 基础参考指标:Accuracy (Top-1 Accuracy)
- 含义: 100篇文章里,有多少篇是完全猜对的。
- 适用场景: 当你的10个标签的数据量比较均衡(比如每个标签都有1000条左右)时,这个指标最直观,老板和业务方最容易听懂。
- 诊断工具:混淆矩阵
这不仅仅是一个数字,而是一张 10x10 的热力图。
- 作用: 帮你发现模型到底"傻"在哪里。
- 怎么看?
- 看对角线:越亮越好(代表预测正确)。
- 看非对角线:如果你发现"体育"类的文章经常被预测成"汽车",说明这两个类别的特征太像了,模型分不清楚,你需要针对性地增加这两类的训练数据或优化特征。
- 进阶指标(视情况而定)
- Weighted-F1:如果你觉得大类别(样本多的类)确实应该占主导地位,可以使用加权平均 F1,它会根据每个类别的样本数量进行加权。
- Top-k Accuracy:如果你的应用场景允许推荐多个结果(比如给用户推荐3个可能的标签),可以看 Top-3 Accuracy,即正确答案只要在前3个预测里就算对。
📌 总结建议
在你的实验报告或监控面板中,建议按以下优先级展示:
- Macro-F1(核心指标,反映真实水平)
- Accuracy(直观指标,反映整体效果)
- 混淆矩阵(用于分析具体哪两个类别容易搞混)
4、准确率、精确率、召回率、F1分数 及其 类
- 准确率(Accuracy)
直白解释:
所有预测中,猜对的比例(不管是正类还是负类,猜对了就算)。
公式:
准确率 = (猜对的个数) / (总样本数)
对应 torchmetrics 类:
torchmetrics.classification.Accuracy
- 精确率(Precision)
直白解释:
模型说"这是正类"的那些样本里,到底有多少真的是正类。
换句话说:模型有没有乱报正类(冤枉好人)。
公式:
精确率 = (正确报出的正类数) / (所有报为正类的数量)
对应 torchmetrics 类:
torchmetrics.classification.Precision
- 召回率(Recall)
直白解释:
在所有真正的正类样本中,模型成功找出了多少。
换句话说:模型有没有漏掉正类(放过坏人)。
公式:
召回率 = (正确报出的正类数) / (所有真正的正类数量)
对应 torchmetrics 类:
torchmetrics.classification.Recall
- F1 分数
直白解释:
精确率和召回率的"综合得分"。
当你既不想乱报(高精确率),又不想漏报(高召回率),就用 F1 来平衡两者。
公式:
F1 = 2 × (精确率 × 召回率) / (精确率 + 召回率)
对应 torchmetrics 类:
torchmetrics.classification.F1Score
一句话总结(记忆用)
- 准确率 :总的猜对比例 →
Accuracy - 精确率 :报为正类的里头,有多少是对的 →
Precision - 召回率 :真正的正类里头,找到了多少 →
Recall - F1 分数 :精确率和召回率的"折中分" →
F1Score
5、torchmetrics - Accuracy 详解(准确率)
📘 TorchMetrics Accuracy 深度拆解
什么是 Accuracy?
在 torchmetrics (v1.0+) 中,Accuracy 是一个通用的入口类。它通过 task 参数来自动适配二分类、多分类或多标签模式。这种设计比旧版本的独立类(如 Accuracy(num_classes=10))更加统一和规范。
注意 :你也可以直接使用
from torchmetrics.classification import MulticlassAccuracy,效果是一样的,但通用版Accuracy写起来更灵活。
两种使用模式
在使用之前,你需要知道它有两种形态:
- 模块式 (Module Style) :推荐用于训练/验证循环 。
- 特点:有状态(Stateful)。可以累积多个 Batch 的数据,最后算总账(Epoch 级别)。
- 用法 :实例化对象 -> 循环调用
update()-> 结束调用compute()。
- 函数式 (Functional Style) :推荐用于即时计算或无状态场景 。
- 特点:无状态(Stateless)。给什么数据算什么结果,不记录历史。
- 用法 :直接调用
torchmetrics.functional.accuracy(...)。
完整函数签名与参数详解
这是 torchmetrics.Accuracy 类的初始化签名。请注意,虽然它是同一个类,但很多参数的有效性取决于 task 的选择。
python
from torchmetrics import Accuracy
metric = Accuracy(
# --- 必填参数 ---
task: Literal["binary", "multiclass", "multilabel"], # [必填] 任务类型
# --- 核心可选参数 ---
threshold: float = 0.5, # [可选] 阈值,默认0.5
num_classes: Optional[int] = None, # [可选] 类别数 (multiclass/multilabel必填)
num_labels: Optional[int] = None, # [可选] 标签数 (multilabel专用)
average: Optional[Literal["micro", "macro", "weighted", "none"]] = "micro", # [可选] 平均方式
multidim_average: Literal["global", "samplewise"] = "global", # [可选] 多维平均方式
top_k: Optional[int] = 1, # [可选] Top-k,默认1
# --- 高级可选参数 ---
ignore_index: Optional[int] = None, # [可选] 忽略的标签索引
validate_args: bool = True # [可选] 是否检查参数合法性
)
🔍 参数深度解析
| 参数名 | 默认值 | 详解与注意事项 |
|---|---|---|
task |
无 | 最关键的参数 。 • "binary": 二分类。 • "multiclass": 多分类(互斥,如文本分类)。 • "multilabel": 多标签(非互斥)。 |
num_classes |
None |
• Multiclass/Multilabel 任务必填 。 • 告诉库一共有多少个类别,用于内部张量分配。 |
average |
"micro" |
• Micro : 全局统计 TP/FP/FN 后计算。受大样本类别主导。 • Macro : 先算每个类的指标再平均。平等对待每个类别 。 • Weighted : 按样本量加权平均。 • None(可能是小写 none): 返回每个类别的指标数组,不聚合。(就能看到每个类别的指标分别是多少) |
top_k |
1 |
• 仅用于 Multiclass 。 • 默认为 1,即 Top-1 Accuracy。 • 若设为 3,只要正确标签在预测概率最高的前3个里,就算对。 |
ignore_index |
None |
• 用于忽略特定的目标值(例如 Padding 的索引 -100),这些位置不参与准确率计算。 |
输入与输出规范
📥 torchmetrics 输入 (preds, target) 核心规范
无论是模块式 (acc_metric.update(...)) 还是函数式 (accuracy(...)),输入的数据类型首选且最推荐 torch.Tensor(张量) 。
(注:虽然传入 Numpy 数组或 Python 列表通常不会报错,库会在内部自动转为张量,但为了保证 GPU 设备一致性和计算效率,强烈建议直接传入张量)
具体形状、类型和任务对应关系如下:
preds(模型预测值)
- Multiclass (多分类)
- 情况 A(最常见) :传入模型输出的原始分数(Logits)或概率(Probabilities)。
- 类型 :
torch.Tensor(通常是FloatTensor浮点型) - 形状 :
(N, C)------ N是样本数,C是类别总数。 - 说明 :库内部会自动对 C 这个维度做
argmax找出概率最大的类别。
- 类型 :
- 情况 B :传入已经预测好的类别索引。
- 类型 :
torch.Tensor(必须是LongTensor整型) - 形状 :
(N,)------ 一维张量。
- 类型 :
- 情况 A(最常见) :传入模型输出的原始分数(Logits)或概率(Probabilities)。
- Binary (二分类)
- 类型 :
torch.Tensor(FloatTensor或LongTensor) - 形状 :
(N,)或(N, 1)。 - 说明 :如果是浮点数(0~1),库会根据
threshold(默认0.5)将其转为 0 或 1。
- 类型 :
- Multilabel (多标签分类)
- 类型 :
torch.Tensor(FloatTensor或LongTensor) - 形状 :
(N, C)------ N是样本数,C是标签总数。 - 说明 :每个样本可以同时属于多个标签(如
[1, 0, 1]表示属于第0类和第2类)。
- 类型 :
- Semantic Segmentation (语义分割 - 补充)
- Multiclass :
- 类型 :
torch.Tensor(FloatTensor) - 形状 :
(N, C, H, W)------ N是样本数,C是类别数,H/W是图像高宽。
- 类型 :
- Binary :
- 类型 :
torch.Tensor(FloatTensor或LongTensor) - 形状 :
(N, H, W)。
- 类型 :
- Multiclass :
target(真实标签)
- Multiclass (多分类)
- 类型 :
torch.Tensor(必须是LongTensor整型) - 形状 :
(N,)------ 一维张量。 - 内容 :值为类别的索引,范围在
0到C-1之间。
- 类型 :
- Binary (二分类)
- 类型 :
torch.Tensor(LongTensor或FloatTensor) - 形状 :
(N,)或(N, 1)。 - 内容 :值为
0或1。
- 类型 :
- Multilabel (多标签分类)
- 类型 :
torch.Tensor(LongTensor或FloatTensor) - 形状 :
(N, C)------ 与多分类的preds形状一致。 - 内容 :值为
0或1(One-hot 形式,1 表示该样本拥有此标签)。
- 类型 :
- Semantic Segmentation (语义分割 - 补充)
- 类型 :
torch.Tensor(必须是LongTensor整型) - 形状 :
(N, H, W)。 - 内容:每个像素点对应的类别索引(0 到 C-1)。
- 类型 :
输出:
输出的是一个张量。
💡 核心总结
- 数据类型 :全程用 PyTorch 张量 (
torch.Tensor)。 - 形状铁律 :
preds和target的第一个维度(Batch Size / N)必须完全相同。 - 多分类特例 :
preds是(N, C)的浮点张量,而target是(N,)的整型张量。 - 分割任务特例 :
preds多一个类别维度(N, C, H, W),而target是直接的空间类别图(N, H, W)。
常用操作代码示例
场景一:模块式 (标准做法)
适用于训练循环,能够跨 Batch 累积计算。
在 TorchMetrics 库中,torchmetrics.Metric 是所有内置指标(如 Accuracy, Precision, F1Score 等)以及用户自定义指标的抽象基类(Abstract Base Class)。
python
import torch
from torchmetrics import Accuracy
# 1. 实例化 (Multiclass 任务)
acc_metric = Accuracy(task="multiclass", num_classes=10, average='macro')
print(type(acc_metric)) # MulticlassAccuracy
# 2. 模拟两个 Batch 的数据
preds_batch1 = torch.randn(20, 10) # 20个样本,10个类别的概率
target_batch1 = torch.randint(0, 10, (20,))
preds_batch2 = torch.randn(20, 10)
target_batch2 = torch.randint(0, 10, (20,))
# 3. 更新状态 (Update)
# 此时不会计算最终结果,只是把中间变量累加起来
acc_metric.update(preds_batch1, target_batch1)
acc_metric.update(preds_batch2, target_batch2)
# 4. 计算最终结果 (Compute)
# 此时才进行除法运算,得出这40个样本的平均准确率
final_acc = acc_metric.compute()
print(f"Total Accuracy: {final_acc}")
# 5. 重置 (Reset)
# 下一个 Epoch 开始前必须调用
acc_metric.reset()
场景二:训练中的 Forward 用法
在训练循环中,我们通常希望每跑一个 batch 就打印一次当前的准确率,同时又要累积状态。这时可以直接调用对象本身(相当于调用了 forward)。
python
# 假设在 training_step 中
outputs = model(data)
loss = criterion(outputs, target)
# 这一步既执行了 update,又返回了当前 batch 的 compute 结果
batch_acc = acc_metric(outputs, target)
self.log('train_loss', loss)
self.log('train_acc', batch_acc) # 用于实时查看训练进度
场景三:函数式 (快速计算)
适用于只需要计算当前这一批数据的准确率,不需要累积。
python
import torch
import torchmetrics
preds = torch.randn(10, 5).softmax(dim=-1) # 10个样本,5个类别
target = torch.randint(0, 5, (10,))
# 直接调用 functional 接口
# 注意:这里需要指定所有必要参数,因为它没有记忆
acc = torchmetrics.functional.accuracy(
preds,
target,
task="multiclass",
num_classes=5
)
print(f"Batch Accuracy: {acc}")
场景四:Top-K 准确率
当你想知道模型"猜对前三名的概率"时:
python
# 初始化时指定 top_k=3
top3_acc = Accuracy(task="multiclass", num_classes=10, top_k=3)
# 输入必须是概率分布或Logits (N, C),不能是索引
preds = torch.randn(32, 10)
target = torch.randint(0, 10, (32,))
res = top3_acc(preds, target) # 直接调用 forward 也可以
💡 总结
对于文本分类任务,最常用的配置就是:
Accuracy(task="multiclass", num_classes=10, average='macro')。
记住 "模块式 + Update/Compute" 的模式,以及在训练循环中使用 metric(preds, target) 的技巧,这是在 PyTorch Lightning 或标准训练循环中最稳健的用法。
6、torchmetrics 模块式 metric - 常用 属性、方法
🛠️ TorchMetrics 模块式指标对象:属性与方法全解析
模块式创建的指标对象继承自 torchmetrics.Metric,而 Metric 本身又继承自 torch.nn.Module。这意味着它既是一个有状态的评估工具 ,也是一个标准的 PyTorch 模块 。它的核心设计哲学是 "累积-计算-重置"三阶段分离,专为跨 batch 的大规模评估和分布式训练而优化。
🧱 一、基础设置与属性(入门必读)
在调用任何方法之前,务必将指标对象的"物理位置"和内部状态搞清楚。这是新手最容易踩坑的地方。
| 属性 / 方法 | 类型 | 说明 |
|---|---|---|
.to(device) / .cuda() |
方法 | 【极其重要】 将指标及其所有内部状态张量移动到指定设备(GPU/CPU)。指标不会自动跟随模型或数据移动,必须在初始化后显式调用。 |
.device |
torch.device |
查看指标当前所在的设备,用于调试设备不匹配问题。 |
metric_state |
Dict[str, Tensor] |
返回当前所有内部状态(通过 add_state 注册的变量)的字典。键为状态名,值为当前累积的张量。 |
.correct / .total 等 |
Tensor |
直接通过属性名访问具体的内部状态变量,方便手动检查和调试。 |
关于
dtype:Metric类本身没有统一的dtype属性。如需查看状态张量的数据类型,可通过metric.metric_state['correct'].dtype等方式查看。
示例:
python
import torch
import torchmetrics
# 初始化并立即移动到 GPU
metric = torchmetrics.Accuracy(task='multiclass', num_classes=10).to('cuda')
print(metric.device) # cuda:0
print(metric.metric_state) # {'correct': tensor(0, device='cuda:0'), 'total': tensor(0, device='cuda:0')}
print(metric.correct) # tensor(0, device='cuda:0')
⚙️ 二、核心生命周期方法(日常训练/验证必用)
这是你写训练循环时每天都要接触的四个核心方法。它们遵循 "累积 → 计算 → 重置 → 累积" 的循环。
其中输入的 preds、target 都必须为张量
| 方法 | 签名 | 功能 | 返回值 |
|---|---|---|---|
update |
update(preds, target) |
累积状态。接收当前 batch 的数据,计算中间统计量(如正确数、总数),并累加到内部变量中。只做累加,不做除法。 | None |
compute |
compute() |
计算最终结果。基于所有累积的状态,一次性计算出最终的指标值(可以是标量、向量或字典)。不重置状态,可多次调用得到相同结果。 | Tensor 或 Dict |
reset |
reset() |
重置状态。将所有内部累积变量恢复到初始值(通常为 0)。 | None |
forward |
forward(preds, target) |
更新 + 计算 。等价于先执行 self.update(preds, target),然后返回 self.compute()。可通过 metric(preds, target) 直接调用。 |
Tensor 或 Dict |
调用方式的选择逻辑
| 场景 | 推荐方法 | 原因 |
|---|---|---|
| 训练日志(想立刻看到当前 batch 的效果) | metric(preds, target)(即 forward) |
一次调用完成累积和显示,方便记录到 TensorBoard。 |
| 验证循环内(只累积不显示,追求速度) | metric.update(preds, target) |
只做加法,不做除法和复杂运算,速度最快。 |
| 验证循环结束后(需要整个数据集的最终得分) | metric.compute() |
一次性基于所有累积数据计算全局指标。 |
| Epoch 开始前/结束后(新周期必须清空旧数据) | metric.reset() |
如果忘记调用,指标会跨 epoch 累积,结果完全错误。 |
完整典型循环
python
metric = torchmetrics.Accuracy(task='multiclass', num_classes=10).to('cuda')
# -- 验证阶段 --
for batch in val_dataloader:
preds, target = batch
metric.update(preds, target) # 只累积,不返回
final_score = metric.compute() # 获取整个验证集的准确率
print(f"Validation Accuracy: {final_score:.3f}")
metric.reset() # 清空状态,准备下一轮
🔧 三、自定义指标专用方法(开发者必看)
当你需要创建自己的指标类时,以下方法是核心。
| 方法 | 说明 |
|---|---|
add_state(name, default, dist_reduce_fx, persistent=True) |
在 __init__ 中调用,注册一个持久化状态变量。default 指定初始值,dist_reduce_fx 指定分布式聚合方式(如 "sum"、"mean")。 |
set_dtype(obj) |
将所有状态的 dtype 统一转换为特定类型。一般在 __init__ 结尾调用。 |
dist_reduce_fx 常用取值:
| 取值 | 含义 |
|---|---|
"sum" |
多卡时将所有设备的该状态值求和 (适用于 correct、total 等计数变量)。 |
"mean" |
多卡时将所有设备的该状态值取平均(适用于某些比率型中间值)。 |
"cat" |
将所有设备的张量拼接起来。 |
None |
不做任何分布式归约,仅在单卡上维护状态。 |
自定义指标示例:
python
from torchmetrics import Metric
import torch
class MyAccuracy(Metric):
def __init__(self):
super().__init__()
self.add_state("correct", default=torch.tensor(0), dist_reduce_fx="sum")
self.add_state("total", default=torch.tensor(0), dist_reduce_fx="sum")
def update(self, preds, target):
self.correct += torch.sum(preds == target)
self.total += target.numel()
def compute(self):
return self.correct.float() / self.total
📦 四、模块化管理属性(继承自 nn.Module)
这些属性/方法继承自 torch.nn.Module,让指标对象可以像模型一样被管理。
| 方法 / 属性 | 说明 |
|---|---|
named_children() |
查看指标包含的子模块(如 MetricCollection 中的子指标)。 |
parameters() |
一般的 Metric 内部没有可学习参数,但某些特殊指标(如 FID)可能包含可训练的统计量。 |
train(mode) / eval() |
切换训练/评估模式。如果自定义指标中嵌入了 BatchNorm 或 Dropout 等层,模式切换会影响其行为。 |
to(device) |
移动指标到指定设备,所有内部状态张量会自动跟随。 |
state_dict() |
保存指标内部状态,可用于 checkpoint 恢复。 |
load_state_dict() |
加载保存的内部状态,保证评估的连续性。 |
persistent(mode=True/False) |
控制指标状态是否会被 model.state_dict() 保存。设为 False 时,保存模型权重时该指标的累积数据会被忽略(通常这正是我们想要的,因为重启训练时指标本就该清零)。 |
.clone() |
创建指标的深拷贝,包括当前的内部状态。 |
📊 五、可视化与调试
| 方法 / 属性 | 说明 |
|---|---|
plot(val=None, ...) |
部分指标(如 ConfusionMatrix、ROC 等)提供内置绘图方法,可直接可视化结果。 |
🧩 六、与 MetricCollection 协同
当多个指标被包装在 MetricCollection 中时,以上核心方法(forward、update、compute、reset)仍然适用,但行为略有变化:
metric_collection(preds, target):返回一个字典,包含所有子指标的即时累积值。metric_collection.compute():返回一个字典,包含所有子指标的最终累积值。metric_collection.reset():同时清空所有子指标的状态。- 每个子指标仍可通过键名单独访问:
metric_collection['acc'].correct。
python
from torchmetrics import MetricCollection, Accuracy, F1Score
metrics = MetricCollection({
'acc': Accuracy(task='multiclass', num_classes=10),
'f1': F1Score(task='multiclass', num_classes=10)
}).to('cuda')
result = metrics(preds, target)
print(result) # {'acc': tensor(0.52, device='cuda:0'), 'f1': tensor(0.48, device='cuda:0')}
💡 七、完整生命周期总结表
| 阶段 | 推荐操作 | 目的 |
|---|---|---|
| 初始化并确定设备 | metric = Metric(...).to(device) |
必须显式指定设备,防止张量位置不匹配 |
| 训练单步(日志) | val = metric(preds, target) |
累积并获取当前 batch 的值,用于 TensorBoard 打印 |
| 验证循环内(最优性能) | metric.update(preds, target) |
默默累积,不做除法,速度最快 |
| 验证循环结束 | final = metric.compute() |
基于全部累积数据计算最终得分 |
| Epoch 结束/新周期开始 | metric.reset() |
清空内存,防止数据跨 epoch 污染 |
| 调试/检查状态 | metric.metric_state 或 metric.correct |
查看当前累积了多少正确样本、总样本等 |
| 保存 checkpoint | torch.save(metric.state_dict(), ...) |
持久化当前评估进度 |
| 恢复 checkpoint | metric.load_state_dict(torch.load(...)) |
恢复之前的评估状态 |
以上就是 torchmetrics 模块式指标对象的完整属性与方法指南,覆盖了从入门、日常使用到自定义开发的全场景。这份知识能帮你避免绝大多数设备不匹配、状态污染等常见问题。