Transformers AutoModelForSequenceClassification 的 logits 怎样映射成类别概率
来源:17golang原创
时间:2026-11-14 20:42:09 172浏览 收藏
Transformers 的 AutoModelForSequenceClassification 返回的 logits 是分类头的原始分数,不是百分比。单标签分类时,对最后一维做 softmax 才能得到每个类别的相对概率;类别编号还要通过模型配置里的 id2label 翻译成业务名称。
官方地址:https://huggingface.co/docs/transformers/
最稳妥的读取链路是:保留outputs.logits的批量维度,使用config.id2label解释索引,再根据problem_type选择 softmax、sigmoid 或直接读取回归值。
logits.shape通常是[batch_size, num_labels]。argmax只决定最可能的索引,不能代替概率计算。- 单标签、多标签和回归的后处理方式不同,不能一律套 softmax。
先分清 logits、类别编号和概率
以二分类为例,模型可能返回 [1.8, -0.4]。这两个数只表示两个类别的相对得分,数值可以为负,也不要求相加等于 1。对最后一维做 softmax 后,才会得到形如 [0.9002, 0.0998] 的归一化结果。
批量输入时不要写成 logits[0] 后再误以为只剩一个类别维度。正确的形状是每行对应一条文本,每列对应一个标签;dim=-1 可以明确沿类别维度计算。

从配置读取标签顺序
模型输出第 0 列是什么类别,不能靠字母顺序或自己的猜测决定。Transformers 配置提供 id2label 和 label2id,而 num_labels 表示分类头的类别数。展示结果时先取最大分数的索引,再用同一个配置对象翻译。
from transformers import AutoConfig
# 配置只负责描述模型和标签,不会加载模型权重。
config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased-finetuned-sst-2-english")
label_id = 1
label_name = config.id2label.get(label_id, f"LABEL_{label_id}")
print(label_name)
如果配置没有可靠的标签名称,就保留 LABEL_0 这样的占位符,并在业务层维护明确的映射;不要把模型输出的位置直接当作中文类别名。
按任务类型选择后处理
单标签分类表示一条输入只能属于一个类别,使用 softmax(logits, dim=-1),每行概率和为 1。多标签分类允许一条输入同时命中多个标签,通常对每个 logit 独立使用 sigmoid,各列之间不必相加为 1。回归任务则通常直接读取输出值,不应把它伪装成类别概率。

这也是为什么只看模型名称不够:应结合配置的 problem_type、num_labels 以及训练任务定义判断后处理方式。
最小推理示例:概率与标签一起返回
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
model_id = "distilbert/distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForSequenceClassification.from_pretrained(model_id)
texts = ["The interface is clear.", "The request failed."]
# padding 让同一批输入能组成规则张量,attention_mask 让模型忽略补齐位置。
inputs = tokenizer(texts, return_tensors="pt", padding=True, truncation=True)
# 推理阶段关闭梯度,避免为展示概率额外保留反向传播图。
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
probabilities = torch.softmax(logits, dim=-1)
predicted_ids = probabilities.argmax(dim=-1)
labels = [model.config.id2label.get(int(i), f"LABEL_{int(i)}") for i in predicted_ids]
for text, label, scores in zip(texts, labels, probabilities):
# 每一行 scores 与 config.id2label 的索引一一对应。
print(text, label, scores.tolist())
这里的对照重点不是某个固定分数,而是形状和索引关系:probabilities[i] 对应第 i 条输入,probabilities[i, j] 对应该输入的第 j 个标签。
常见误区与结果核对
| 现象 | 原因 | 处理 |
|---|---|---|
| 把 logits 当百分比 | 原始分数没有归一化 | 单标签任务沿最后一维做 softmax |
| 标签名称对不上 | 手写顺序与模型配置不一致 | 使用同一份 id2label |
| 多标签概率总和大于 1 | 独立标签本来就不是互斥事件 | 使用 sigmoid,并单独设置业务阈值 |
| 分类输出维度不符合预期 | 模型配置或任务类型选错 | 先打印 logits.shape、num_labels、problem_type |
最后可把三个字段记录到日志:logits.shape、model.config.id2label 和实际采用的后处理函数。这样比只记录一个最终标签更容易定位模型配置错位。
相关问题
softmax 应该在哪个维度计算? 对常见的分类输出使用 dim=-1,即沿类别维度计算,不要跨 batch 维度归一化。
argmax 后还需要 softmax 吗? 如果只需要类别编号,argmax 就够;如果需要概率、排序或置信度展示,还应计算 softmax。
为什么多标签任务不能用 softmax? softmax 会强制所有类别竞争同一个总和,而多标签任务允许多个类别同时成立,应对每个 logit 独立使用 sigmoid。
-
284 收藏
-
387 收藏
-
328 收藏
-
426 收藏
-
147 收藏
-
212 收藏
-
科技周边 · 人工智能 | 18分钟前 | python · 人工智能 · 并行处理 index Hugging Face Datasets Datasets shard num_shards contiguous417 收藏
-
280 收藏
-
科技周边 · 人工智能 | 21分钟前 | python · Transformers TextIteratorStreamer 流式生成 AsyncTextIteratorStreamer StoppingCriteria198 收藏
-
279 收藏
-
161 收藏
-
453 收藏
-
科技周边 · 人工智能 | 28分钟前 | 人工智能 · padding Transformers tokenizer max_length attention_mask truncation return_tensors352 收藏
-
243 收藏
-
457 收藏
-
253 收藏
-
114 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习