从 huggingface 特征提取管道获取句子嵌入

Getting sentence embedding from huggingface Feature Extraction Pipeline

如何从 huggingface 的特征提取管道中获取整个句子的嵌入?

我了解如何获取每个标记的特征(如下),但我如何获取整个句子的整体特征?

feature_extraction = pipeline('feature-extraction', model="distilroberta-base", tokenizer="distilroberta-base")
features = feature_extraction("i am sentence")

如果你有每个标记的嵌入,你可以通过汇集(总结)它们来创建一个整体的句子嵌入。请注意,如果您有 D-dimensional 个标记嵌入,您应该通过以下方法之一获得 D-dimensional 个句子嵌入:

  1. 计算所有标记嵌入的平均值。

  2. 计算所有标记嵌入中每个 D-dimensions 的最大值。

为了进一步解释我在 Whosebuguser2010 的回答下发表的评论,我将使用“准系统”模型,但行为与 pipeline 组件相同。

BERT 和派生模型(包括 DistilRoberta,这是您在管道中使用的模型)通常用特殊标记表示句子的开始和结束(第一个标记大多表示为 [CLS])这通常是在整个序列上进行 predictions/generating 嵌入的最简单方法。社区内有一个关于哪种方法更好的讨论(另请参阅 Whosebuguser2010 here 的更详细答案),但是,如果您只是想要一个“快速”解决方案,那么使用 [CLS] 令牌是当然是一个有效的策略。

现在,虽然 FeatureExtractionPipelinedocumentation 不是很清楚,但在您的示例中,我们可以通过直接模型调用轻松比较输出,特别是它们的长度:

from transformers import pipeline, AutoTokenizer

# direct encoding of the sample sentence
tokenizer = AutoTokenizer.from_pretrained('distilroberta-base')
encoded_seq = tokenizer.encode("i am sentence")

# your approach
feature_extraction = pipeline('feature-extraction', model="distilroberta-base", tokenizer="distilroberta-base")
features = feature_extraction("i am sentence")

# Compare lengths of outputs
print(len(encoded_seq)) # 5
# Note that the output has a weird list output that requires to index with 0.
print(len(features[0])) # 5

检查 encoded_seq 的内容时,您会注意到第一个标记用 0 索引,表示 beginning-of-sequence 标记(在我们的例子中是嵌入标记)。由于输出长度相同,因此您可以通过执行

之类的操作来简单地访问初步句子嵌入

sentence_embedding = features[0][0]

如果您想对整个句子进行有意义的嵌入,请使用 SentenceTransformers。池化在其中得到了很好的实现,它还提供了各种 API 来微调模型以在 sentence/text-chunk 级别

上生成 features/embeddings
pip install sentence-transformers

安装sentence-transformers后,可以使用以下代码生成句子嵌入

from sentence_transformers import SentenceTransformer
model_st = SentenceTransformer('distilroberta-base')
embeddings = model_st.encode("I am a sentence')
print(embeddings)

访问官方site了解更多关于句子转换的信息。