变形金刚 PreTrainedTokenizer add_tokens 功能
Posted
技术标签:
【中文标题】变形金刚 PreTrainedTokenizer add_tokens 功能【英文标题】:Transformers PreTrainedTokenizer add_tokens Functionality 【发布时间】:2020-05-20 21:57:46 【问题描述】:参考 Huggingface 中很棒的 Transformers 库的 documentation,我遇到了 add_tokens
函数。
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
num_added_toks = tokenizer.add_tokens(['new_tok1', 'my_new-tok2'])
model.resize_token_embeddings(len(tokenizer))
我通过在默认词汇表中添加以前不存在的单词来尝试上述方法。然而,在保持其他所有因素不变的情况下,我注意到使用更新后的tokenizer
的微调分类器的准确性有所下降。即使只添加了 10% 的先前缺失的单词,我也能够复制类似的行为。
我的问题
-
我错过了什么吗?
add_tokens
函数是否需要屏蔽标记,而不是整个单词,例如:'##ah'
、'##red'
、'##ik'
、'##si
' 等?如果是,是否有生成此类掩码令牌的程序?
任何帮助将不胜感激。
提前致谢。
【问题讨论】:
【参考方案1】:如果您向分词器添加标记,您确实使分词器对文本进行不同的分词,但这不是 BERT 训练时使用的分词,因此您基本上是在向输入添加噪声。词嵌入没有经过训练,网络的其余部分从未在上下文中看到它们。你需要大量数据来教 BERT 处理新添加的单词。
还有一些方法可以计算单个词嵌入,这样它就不会像 this paper 那样伤害 BERT,但它看起来相当复杂,应该没有任何区别。
BERT 使用基于单词片段的词汇表,因此单词是作为单个标记出现在词汇表中还是被拆分为多个单词片段并不重要。该模型可能在预训练期间看到了拆分词,并且会知道如何处理它。
关于##
-前缀标记,这些标记只能作为另一个单词的后缀添加。例如,walrus
被拆分为 ['wal', '##rus']
并且您需要将两个单词都包含在词汇表中,但不需要 ##wal
或 rus
。
【讨论】:
以上是关于变形金刚 PreTrainedTokenizer add_tokens 功能的主要内容,如果未能解决你的问题,请参考以下文章