如何防止BERT将特定单词拆分为字片段

6
我正在使用一个预训练的BERT模型将文本分词为有意义的单元。但由于文本中有很多专有名词,我不希望BERT将其拆分成词片段。是否有什么解决方法? 例如:
tokenizer = BertTokenizer('bert-base-uncased-vocab.txt')
tokens = tokenizer.tokenize("metastasis")

创建如下令牌:
['meta', '##sta', '##sis']

然而,我希望将整个单词作为一个记号来保留,就像这样:

['metastasis']

也许' '.join([x for x in tokens]).replace(' ##', '')可以吗? - Wiktor Stribiżew
谢谢您的回答,但我不能这样做,因为我想要这些词片段用于其他单词(非特定的单词)。例如提取:['extract', '##ing']。 - parvaneh shayegh
通常情况下您不需要这样做,子词分词在解决OOV单词和减少词汇量方面非常有用。为什么需要添加例外呢? - Wiktor Stribiżew
请纠正我如果我错了,但在我的例子中,“metastasis”的标记是“meta”、“sta”和“sis”。然而,我想将“metastasis”作为一个整体单词保留下来,因为它与“meta”没有任何关系。 - parvaneh shayegh
3个回答

7

您可以自由地向现有的预训练分词器中添加新的标记,但是接下来您需要使用改进后的分词器(包含额外的标记)对模型进行训练。

例如:

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
v = tokenizer.get_vocab()
print(len(v))
tokenizer.add_tokens(['whatever', 'underdog'])
v = tokenizer.get_vocab()
print(len(v))

如果像“whatever”一样的令牌已经存在,则不会添加。
输出:
30522
30523

1

我认为如果我使用这个解决方案,就像

tokenizer.add_tokens(['whatever', 'underdog'])

词汇量大小已经改变,这意味着我不能使用transformers预训练模型吗?因为嵌入的大小不正确。

0

根据这里的讨论,使用我自己的额外词汇字典(包含特定单词)的一种方法是修改vocab.txt文件的前1000行([未使用]行)以包含这些特定单词。例如,我用“metastasis”替换了vocab.txt中的“[unused1]”,在使用修改后的vocab.txt进行标记化后,我得到了以下输出:

tokens = tokenizer.tokenize("metastasis")
Output: ['metastasis']

1
您的讨论链接已损坏。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接