首页 > 解决方案 > 如何从预训练的转换器中获取词嵌入

问题描述

我正在处理多语言数据的单词级分类任务,我正在使用 XLM-R,我知道 XLM-Rsentencepiece 用作标记器,有时将单词标记为子词。

例如句子“deception master”被分词为de ception master,单词 deception 被分词成两个子词。

我怎样才能得到deception. 我可以采用子词的平均值来获得词的嵌入,就像这里所做的那样。但是我必须在 TensorFlow 中实现我的代码,并且 TensorFlow 计算图不支持 NumPy。

在将子词的平均值放入 NumPy 数组并将该数组作为模型的输入之后,我可以存储最终的隐藏嵌入,但我想微调转换器。

如何从转换器给出的子词嵌入中获取词嵌入

标签: pythontensorflowhuggingface-transformerstransfer-learningtransformer

解决方案


将子词嵌入加入到词中以进行词标记通常不是解决这个问题的方法。通常的方法是相反的:保持子词不变,但调整标签以尊重预训练模型的标记化。

原因之一是数据通常是成批的。当将子词合并成单词时,批处理中的每个句子最终都会有不同的长度,这需要独立处理每个句子并再次填充批处理——这会很慢。此外,如果您不对相邻嵌入进行平均,您会从损失函数中获得更细粒度的信息,这会明确说明哪个子词对错误负责。

使用 SentencePiece 进行标记时,您可以获得原始字符串中的索引:

from transformers import XLMRobertaTokenizerFast
tokenizer = XLMRobertaTokenizerFast.from_pretrained("xlm-roberta-base")
tokenizer("deception master", return_offsets_mapping=True)

这将返回以下字典:

{'input_ids': [0, 8, 63928, 31347, 2],
 'attention_mask': [1, 1, 1, 1, 1],
 'offset_mapping': [(0, 0), (0, 2), (2, 9), (10, 16), (0, 0)]}

使用偏移量,您可以确定子词是否对应于您要标记的词。有多种策略可用于对标签进行编码。最简单的方法是将标签复制到每个子词。一种更奇特的方法是使用命名实体识别中使用的方案,例如IOB 标记,它明确说明标记段的请求是什么。


推荐阅读