拥抱脸中的 tokenizer.encode 和 tokenizer.encode_plus 有啥区别

Posted

技术标签:

【中文标题】拥抱脸中的 tokenizer.encode 和 tokenizer.encode_plus 有啥区别【英文标题】:what's difference between tokenizer.encode and tokenizer.encode_plus in Hugging Face拥抱脸中的 tokenizer.encode 和 tokenizer.encode_plus 有什么区别 【发布时间】:2020-08-25 17:48:06 【问题描述】:

这是一个使用模型进行序列分类的示例,以确定两个序列是否是彼此的释义。这两个例子给出了两种不同的结果。你能帮我解释一下为什么tokenizer.encodetokenizer.encode_plus 给出不同的结果吗?

示例 1(带有.encode_plus()):

paraphrase = tokenizer.encode_plus(sequence_0, sequence_2, return_tensors="pt")
not_paraphrase = tokenizer.encode_plus(sequence_0, sequence_1, return_tensors="pt")

paraphrase_classification_logits = model(**paraphrase)[0]
not_paraphrase_classification_logits = model(**not_paraphrase)[0]

示例 2(带有.encode()):

paraphrase = tokenizer.encode(sequence_0, sequence_2, return_tensors="pt")
not_paraphrase = tokenizer.encode(sequence_0, sequence_1, return_tensors="pt")

paraphrase_classification_logits = model(paraphrase)[0]
not_paraphrase_classification_logits = model(not_paraphrase)[0]

【问题讨论】:

能否请您指定您的transformers 版本,至少给出您测试时使用的例句,以及您使用的模型版本(BERT、RoBERTa 等)。请参阅minimal reproducible example,了解理想样本的外观。 【参考方案1】:

主要区别在于encode_plus 提供的附加信息。如果您阅读了有关各个功能的文档,那么encode()会略有不同:

使用标记器和词汇表将字符串转换为 ids(整数)序列。 和self.convert_tokens_to_ids(self.tokenize(text))一样。

以及encode_plus()的描述:

返回包含编码序列或序列对的字典 和附加信息:序列分类的掩码和 如果指定了 max_length,则溢出元素。

根据您指定的模型和输入语句,不同之处在于额外编码的信息,特别是输入掩码。由于您一次输入两个句子,BERT(以及可能的其他模型变体)需要某种形式的掩码,它允许模型在两个序列之间进行辨别,请参阅here。由于encode_plus 提供此信息,但encode 不是,您会得到不同的输出结果。

【讨论】:

以上是关于拥抱脸中的 tokenizer.encode 和 tokenizer.encode_plus 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

tokenizer.tokenize(), tokenizer.encode() , tokenizer.encode_plus() 方法介绍及其区别

FaceShifter: Towards High Fidelity And Occlusion Aware Face Swapping

嵌套视图中的拥抱和抗压性

减少 BERT 的推理时间

拥抱面标记器中的填充如何工作?

Jupyter 笔记本中的 ModuleNotFoundError 拥抱脸数据集