python - RobertaForSequenceClassification 中的 logits 和概率代表什么?
问题描述
作为“自然语言处理”场景的新手,我正在实验学习并实现了以下代码段:
from transformers import RobertaTokenizer, RobertaForSequenceClassification
import torch
path = "D:/LM/rb/"
tokenizer = RobertaTokenizer.from_pretrained(path)
model = RobertaForSequenceClassification.from_pretrained(path)
inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")
outputs = model(**inputs)
pred_logits = outputs.logits
print(pred_logits)
probs = pred_logits.softmax(dim=-1).detach().cpu().flatten().numpy().tolist()
print(probs)
我知道应用该模型会返回“torch.FloatTensor
包含取决于配置(RobertaConfig)和输入的各种元素”,并且可以使用.logits
. 如图所示,我已将.softmax函数应用于张量以返回归一化概率并将结果转换为列表。我输出以下内容:
[0.5022980570793152, 0.49770188331604004]
这些概率是否代表某种整体“被掩盖”的概率?
第一个和第二个索引在输入上下文中代表什么?
编辑:
model.num_labels
输出:
2
@cronoik解释说,该模型“尝试对序列是否属于某个类别进行分类”
我是否可以假设因为没有训练有素的输出层,这些类还没有任何意义?
例如,我可以假设句子 post analysis 属于第 1 类的概率是 0.5。但是,什么是 1 级?
此外,具有预训练输出层的模型卡(例如open-ai 检测器)有助于区分“真实”和“虚假”,因此我可以假设句子所属的类别。但是,如果没有某种类型的“mapping.txt”文件,如何确认这些“标签”?
解决方案
您已经初始化了一个模型,该RobertaForSequenceClassification
模型在默认情况下(如果没有用于序列分类的训练输出层)尝试对序列是否属于一个类或另一个类进行分类。我使用了“属于一个类或另一个类”的表达方式,因为这些类还没有任何意义。输出层未经训练,需要微调才能赋予这些类意义。可能是并且可能是或者相反。例如,用于微调 IMDb 评论数据集的序列分类模型的教程将负面评论定义为(链接)。roberta-base
roberta-large
Class 0
X
Class 1
Y
Class 0
Class 1
您可以通过以下方式检查支持的类的数量:
model.num_labels
输出:
2
您得到的输出是每个类的非归一化概率(即logits)。您应用了 softmax 函数来规范化这些概率,这导致第一类为 0.5022980570793152,第二类为 0.49770188331604004。
也许您感到困惑,因为这些值彼此接近。让我们尝试一个带有预训练输出层(模型卡)的模型:
sentimodel = RobertaForSequenceClassification.from_pretrained('cardiffnlp/twitter-roberta-base-sentiment')
print(sentimodel.num_labels)
outputs = sentimodel(**inputs)
print(outputs.logits.softmax(dim=-1).tolist())
输出:
3
[[0.0015561950858682394, 0.019568447023630142, 0.9788752794265747]]
这些值表示句子Hello, my dog is cute
为negative
、neutral
或的概率positive
。我们知道这些类是什么,因为作者提供了阐明它的映射。如果模型的作者没有提供这样的映射(通过自述文件或原始训练代码),我们只能通过随机样本测试来猜测每个类代表什么。
您提到的模型卡没有提供有关将类映射到它们所代表的任何有用信息,但模型是由 huggingface 本身提供的,它们提供了用于训练模型的代码的链接。dataset.py表示fake
由Class 0
和real
表示Class 1
。_