【问题标题】:Tokens returned in transformers Bert model from encode()来自 encode() 的转换器 Bert 模型中返回的令牌
【发布时间】:2020-12-15 20:39:55
【问题描述】:

我有一个用于情绪分析的小型数据集。分类器将是一个简单的 KNN,但我想从 transformers 库中使用 Bert 模型获取词嵌入。请注意,我刚刚发现了这个库 - 我还在学习。

所以看在线示例,我试图了解从模型返回的尺寸。

例子:

from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

tokens = tokenizer.encode(["Hello, my dog is cute", "He is really nice"])
print(tokens)

tokens = tokenizer.encode("Hello, my dog is cute", "He is really nice")
print(tokens)

tokens = tokenizer.encode(["Hello, my dog is cute"])
print(tokens)

tokens = tokenizer.encode("Hello, my dog is cute")
print(tokens)

输出如下:

[101, 100, 100, 102]

[101, 7592, 1010, 2026, 3899, 2003, 10140, 102, 2002, 2003, 2428, 3835, 102]

[101, 100, 102]

[101, 7592, 1010, 2026, 3899, 2003, 10140, 102]

我似乎找不到encode() 的文档——我不知道为什么当输入作为列表传递时它会返回不同的东西。这是在做什么?

此外,是否有一种方法可以传递单词标记并返回实际单词 - 以解决上述问题?

提前谢谢你

【问题讨论】:

    标签: python machine-learning nlp bert-language-model huggingface-transformers


    【解决方案1】:

    您可以调用tokenizer.convert_ids_to_tokens() 来获取一个 id 的实际令牌:

    from transformers import BertTokenizer
    
    tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
    
    tokens = []
    
    tokens.append(tokenizer.encode(["Hello, my dog is cute", "He is really nice"]))
    
    tokens.append(tokenizer.encode("Hello, my dog is cute", "He is really nice"))
    
    tokens.append(tokenizer.encode(["Hello, my dog is cute"]))
    
    tokens.append(tokenizer.encode("Hello, my dog is cute"))
    
    for t in tokens:
        print(tokenizer.convert_ids_to_tokens(t))
    

    输出:

    ['[CLS]', '[UNK]', '[UNK]', '[SEP]']
    ['[CLS]', 'hello', ',', 'my', 'dog', 'is', 'cute', '[SEP]', 'he', 'is', 'really', 'nice', '[SEP]']
    ['[CLS]', '[UNK]', '[SEP]']
    ['[CLS]', 'hello', ',', 'my', 'dog', 'is', 'cute', '[SEP]']
    

    正如您在此处看到的,您的每个输入都经过标记化,并根据您的模型 (bert) 添加了特殊标记。编码功能没有正确处理您的列表,这可能是一个错误或预期的行为,具体取决于您如何定义它,因为它们是一种批处理方法batch_encode_plus

    tokenizer.batch_encode_plus(["Hello, my dog is cute", "He is really nice"], return_token_type_ids=False, return_attention_mask=False)
    

    输出:

    {'input_ids': [[101, 7592, 1010, 2026, 3899, 2003, 10140, 102], [101, 2002, 2003, 2428, 3835, 102]]}
    

    我不确定为什么没有记录 encode 方法,但可能是 huggingface 希望我们直接使用 call 方法:

    tokens = []
    
    tokens.append(tokenizer(["Hello, my dog is cute", "He is really nice"],  return_token_type_ids=False, return_attention_mask=False))
    
    tokens.append(tokenizer("Hello, my dog is cute", "He is really nice",  return_token_type_ids=False, return_attention_mask=False))
    
    tokens.append(tokenizer(["Hello, my dog is cute"], return_token_type_ids=False, return_attention_mask=False))
    
    tokens.append(tokenizer("Hello, my dog is cute", return_token_type_ids=False, return_attention_mask=False))
    
    print(tokens)
    

    输出:

    [{'input_ids': [[101, 7592, 1010, 2026, 3899, 2003, 10140, 102], [101, 2002, 2003, 2428, 3835, 102]]}, {'input_ids': [101, 7592, 1010, 2026, 3899, 2003, 10140, 102, 2002, 2003, 2428, 3835, 102]}, {'input_ids': [[101, 7592, 1010, 2026, 3899, 2003, 10140, 102]]}, {'input_ids': [101, 7592, 1010, 2026, 3899, 2003, 10140, 102]}]
    
    

    【讨论】:

    • 哦,非常感谢 - 这很有帮助。我的猜测是有一个标志可以在没有特殊字符的情况下进行编码
    • 是的add_special_tokens=False。只需查看__call__ 方法的文档即可。我认为所有的参数也是encode的有效参数。 @EdvBeq
    猜你喜欢
    • 2020-10-09
    • 2020-12-07
    • 2016-06-26
    • 2020-02-25
    • 1970-01-01
    • 2021-03-25
    • 2021-04-29
    • 1970-01-01
    相关资源
    最近更新 更多