我设计了一个基于BERT的模型来解决NER任务。我正在将transformers库与"dccuchile/bert-base-spanish-wwm-cased"预训练模型一起使用。问题出在我的模型检测到实体但令牌为'[UNK]'时。我怎么知道该令牌后面的字符串是什么?

我知道未知令牌无法还原为原始令牌,但是我想至少在将输入传递给模型之前捕获该值。

代码非常简单:

    sentenceIds = tokenizer.encode(sentence,add_special_tokens = True)

    inputs = pad_sequences([sentenceIds], maxlen=256, dtype="long",
                              value=0, truncating="post", padding="post")

    att_mask = torch.tensor([[int(token_id > 0) for token_id in inputs[0]]]).to(device)
    inputs = torch.tensor(inputs).to(device)

    with torch.no_grad():
        outputs = model(inputs,
                          token_type_ids=None,
                          attention_mask=att_mask)


如您所见,它真的很简单,只需标记化,填充或截断,创建tentionMask并调用模型即可。

我尝试使用regex,试图找到它周围的两个标记以及类似的东西,但我无法正确解决。

最佳答案

分词器分两个步骤工作。首先,它会进行预加标记,这基本上是在空格上分割并分隔标点符号。让我们用一个随机的捷克语来看一下:

tokenizer.basic_tokenizer.tokenize("Kočka leze dírou.")


这给您:['kocka', 'leze', 'dirou', '.']

在第二步中,它应用了词条拆分算法,因此您得到:

tokenizer.tokenize("Kočka leze dírou.")


您得到:['[UNK]', 'le', '##ze', 'di', '##ro', '##u', '.']

如果无法将令牌拆分为子词,则整个词将变为[UNK]。以##开头的令牌被附加到先前的令牌之后,因此您可以通过这种方式找出[UNK]最初的来源。

(在我看来,西班牙WordPiece标记程序无法解析仅包含拉丁字符的单词,这很奇怪。)

10-04 20:42