当前位置:   article > 正文

HuggingFace学习笔记--Tokenizer的使用_tokenlizer

tokenlizer

1--AutoTokenizer的使用

官方文档

        AutoTokenizer() 常用于分词,其可调用现成的模型来对输入句子进行分词。

1-1--简单Demo

测试代码:

  1. # 分词器测试Demo
  2. from transformers import AutoTokenizer
  3. if __name__ == "__main__":
  4. checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" # 使用该模型
  5. tokenlizer = AutoTokenizer.from_pretrained(checkpoint) # 加载该模型对应的分词器
  6. raw_input = [
  7. "I love kobe bryant.",
  8. "Me too."
  9. ]
  10. inputs = tokenlizer(raw_input, padding = True, return_tensors = "pt") # padding并返回pytorch版本的tensor
  11. print("After tokenlizer: \n", inputs) # 打印分词后的结果
  12. str1 = tokenlizer.decode(inputs['input_ids'][0]) # 将词ID恢复
  13. print("str1: \n", str1)
  14. print("All done!")

输出结果:

  1. After tokenlizer:
  2. {
  3. 'input_ids': tensor([[101, 1045, 2293, 24113, 12471, 1012, 102],
  4. [101, 2033, 2205, 1012, 102, 0, 0]]),
  5. 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1],
  6. [1, 1, 1, 1, 1, 0, 0]])
  7. }
  8. str1:
  9. [CLS] i love kobe bryant. [SEP]

分析:

        上述代码将输入的句子进行分词,并将每一个词利用一个 ID 进行映射;例如上述代码中,101 对应 [CLS],1045 对应 I,2293 对应 love,24113 对应 kobe,12471 对应 bryant,1012 对应 . 符号,102 对应 [SEP];

        input_ids 存储了每一个句子分词后对应的 ID,0 表示 padding 的词;由于上面测试代码设置了padding,因此会将每一个句子自动padding为最长句子的长度,padding的词用 0 来表示。

        attention_mask 标记了哪些词是真正有意义的,只有为 1 的词才会参与后续的 attention 等计算。

        利用 decode 可以将词 ID 重新解码为句子。

1-2--常用参数

1-2-1--padding

        设置 padding 时,可以指定具体的 padding 长度;

  1. from transformers import AutoTokenizer
  2. if __name__ == "__main__":
  3. checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
  4. tokenlizer = AutoTokenizer.from_pretrained(checkpoint)
  5. raw_input = [
  6. "I love kobe bryant.",
  7. "Me too."
  8. ]
  9. input1 = tokenlizer(raw_input, padding = "longest", return_tensors = "pt") # padding长度与输入中的最长句子相同
  10. input2 = tokenlizer(raw_input, padding = "max_length", return_tensors = "pt") # padding到最大句子长度,默认是512
  11. input3 = tokenlizer(raw_input, padding = "max_length", max_length = 10, return_tensors = "pt") # 指定最大长度是10
  12. print("After tokenlizer: \n", input1['input_ids'].shape)
  13. print("After tokenlizer: \n", input2['input_ids'].shape)
  14. print("After tokenlizer: \n", input3['input_ids'].shape)

输出结果:

  1. After tokenlizer:
  2. torch.Size([2, 7])
  3. After tokenlizer:
  4. torch.Size([2, 512])
  5. After tokenlizer:
  6. torch.Size([2, 10])

1-2-2--truncation

        设置 truncation 时,用于截断,可以指定截断的长度。

  1. from transformers import AutoTokenizer
  2. if __name__ == "__main__":
  3. checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
  4. tokenlizer = AutoTokenizer.from_pretrained(checkpoint)
  5. raw_input = [
  6. "I love kobe bryant.",
  7. "Me too."
  8. ]
  9. # 长度超过5的部分会被截断
  10. input1 = tokenlizer(raw_input, padding = "longest", truncation = True, max_length=5, return_tensors = "pt")
  11. print("After tokenlizer: \n", input1)
  12. str1 = tokenlizer.decode(input1['input_ids'][0]) # 将词ID恢复
  13. print("str1: \n", str1)

输出结果:

  1. After tokenlizer:
  2. {
  3. 'input_ids': tensor([[ 101, 1045, 2293, 24113, 102],
  4. [ 101, 2033, 2205, 1012, 102]]),
  5. 'attention_mask': tensor([[1, 1, 1, 1, 1],
  6. [1, 1, 1, 1, 1]])
  7. }
  8. str1:
  9. [CLS] i love kobe [SEP]

2--BertTokenizer的使用

2-1--简单Demo

① 编码两个句子:

  1. from transformers import BertTokenizer
  2. if __name__ == "__main__":
  3. tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
  4. sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
  5. # 编码两个句子
  6. inputs = tokenizer.encode(
  7. text = sents[0],
  8. text_pair = sents[1],
  9. truncation = True, # 截断
  10. padding = 'max_length', # padding到最大长度
  11. add_special_tokens = True,
  12. max_length = 20, # 设置最大长度
  13. return_tensors = None # None默认返回list,可取值tf,pt,np
  14. )
  15. print(inputs)
  16. print(tokenizer.decode(inputs))

输出结果:

  1. inputs:
  2. [101, 2769, 1599, 3614, 4906, 3683, 2357, 5812, 2617, 4294, 119, 102, 2769, 738, 3221, 119, 102, 0, 0, 0]
  3. decode:
  4. [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] 我 也 是. [SEP] [PAD] [PAD] [PAD]

② 增强编码

  1. from transformers import BertTokenizer
  2. if __name__ == "__main__":
  3. tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
  4. sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
  5. # 增强编码两个句子
  6. inputs = tokenizer.encode_plus(
  7. text = sents[0],
  8. text_pair = sents[1],
  9. truncation = True, # 截断
  10. padding = 'max_length', # padding到最大长度
  11. add_special_tokens = True,
  12. max_length = 30, # 设置最大长度
  13. return_tensors = None, # None默认返回list,可取值tf,pt,np,
  14. return_token_type_ids = True,
  15. return_attention_mask = True,
  16. return_special_tokens_mask = True,
  17. return_length = True
  18. )
  19. for k, v in inputs.items():
  20. print(k, ':', v)
  21. print(tokenizer.decode(inputs['input_ids']))

输出结果:

  1. input_ids : [101, 2769, 1599, 3614, 4906, 3683, 2357, 5812, 2617, 4294, 119, 102, 2769, 738, 3221, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  2. token_type_ids : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  3. special_tokens_mask : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  4. attention_mask : [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  5. length : 30
  6. decode:
  7. [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] 我 也 是. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]

③ 批量编码:

  1. from transformers import BertTokenizer
  2. if __name__ == "__main__":
  3. tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
  4. sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
  5. # 批量编码句子
  6. inputs = tokenizer.batch_encode_plus(
  7. batch_text_or_text_pairs = [sents[0], sents[1]],
  8. truncation = True, # 截断
  9. padding = 'max_length', # padding到最大长度
  10. add_special_tokens = True,
  11. max_length = 20, # 设置最大长度
  12. return_tensors = None, # None默认返回list,可取值tf,pt,np,
  13. return_token_type_ids = True,
  14. return_attention_mask = True,
  15. return_special_tokens_mask = True,
  16. return_length = True
  17. )
  18. for k, v in inputs.items():
  19. print(k, ':', v)
  20. print("decode: \n", tokenizer.decode(inputs['input_ids'][0]))
  21. print("decode: \n", tokenizer.decode(inputs['input_ids'][1]))

输出结果:

  1. input_ids : [[101, 2769, 1599, 3614, 4906, 3683, 2357, 5812, 2617, 4294, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0], [101, 2769, 738, 3221, 119, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
  2. token_type_ids : [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
  3. special_tokens_mask : [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
  4. length : [12, 6]
  5. attention_mask : [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
  6. decode:
  7. [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]
  8. decode:
  9. [CLS] 我 也 是. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]

④ 批量编码成对的句子:

  1. from transformers import BertTokenizer
  2. if __name__ == "__main__":
  3. tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
  4. sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
  5. # 批量编码成对的句子
  6. inputs = tokenizer.batch_encode_plus(
  7. batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
  8. truncation = True, # 截断
  9. padding = 'max_length', # padding到最大长度
  10. add_special_tokens = True,
  11. max_length = 20, # 设置最大长度
  12. return_tensors = None, # None默认返回list,可取值tf,pt,np,
  13. return_token_type_ids = True,
  14. return_attention_mask = True,
  15. return_special_tokens_mask = True,
  16. return_length = True
  17. )
  18. for k, v in inputs.items():
  19. print(k, ':', v)
  20. print("decode: \n", tokenizer.decode(inputs['input_ids'][0]))
  21. print("decode: \n", tokenizer.decode(inputs['input_ids'][1]))

输出结果:

  1. input_ids : [[101, 2769, 1599, 3614, 4906, 3683, 2357, 5812, 2617, 4294, 119, 102, 2769, 738, 3221, 119, 102, 0, 0, 0], [101, 2769, 1599, 3614, 800, 4638, 1400, 814, 6663, 2832, 102, 2769, 1599, 3614, 800, 4638, 3294, 2349, 5125, 102]]
  2. token_type_ids : [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
  3. special_tokens_mask : [[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1]]
  4. length : [17, 20]
  5. attention_mask : [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
  6. decode:
  7. [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] 我 也 是. [SEP] [PAD] [PAD] [PAD]
  8. decode:
  9. [CLS] 我 喜 欢 他 的 后 仰 跳 投 [SEP] 我 喜 欢 他 的 曼 巴 精 [SEP]

⑤ 获取字典:

  1. from transformers import BertTokenizer
  2. if __name__ == "__main__":
  3. tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
  4. sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
  5. # 批量编码成对的句子
  6. inputs = tokenizer.batch_encode_plus(
  7. batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
  8. truncation = True, # 截断
  9. padding = 'max_length', # padding到最大长度
  10. add_special_tokens = True,
  11. max_length = 20, # 设置最大长度
  12. return_tensors = None, # None默认返回list,可取值tf,pt,np,
  13. return_token_type_ids = True,
  14. return_attention_mask = True,
  15. return_special_tokens_mask = True,
  16. return_length = True
  17. )
  18. # 获取字典
  19. token_dict = tokenizer.get_vocab()
  20. print(type(token_dict))
  21. print(len(token_dict))
  22. print('喜' in token_dict) # 中文是按字来编码的,因此喜在字典里
  23. print('喜欢' in token_dict) # 同理,喜欢不在字典里

输出结果:

  1. <class 'dict'>
  2. 21128
  3. True
  4. False

⑥ 添加新字典:

  1. from transformers import BertTokenizer
  2. if __name__ == "__main__":
  3. tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
  4. sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
  5. # 批量编码成对的句子
  6. inputs = tokenizer.batch_encode_plus(
  7. batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
  8. truncation = True, # 截断
  9. padding = 'max_length', # padding到最大长度
  10. add_special_tokens = True,
  11. max_length = 20, # 设置最大长度
  12. return_tensors = None, # None默认返回list,可取值tf,pt,np,
  13. return_token_type_ids = True,
  14. return_attention_mask = True,
  15. return_special_tokens_mask = True,
  16. return_length = True
  17. )
  18. # 添加新词
  19. tokenizer.add_tokens(new_tokens=['喜欢', '跳投'])
  20. # 添加新符号
  21. tokenizer.add_special_tokens({'eos_token': '[EOS]'})
  22. # 获取字典
  23. token_dict = tokenizer.get_vocab()
  24. print('喜欢' in token_dict) # 添加新词后,喜欢在字典里
  25. print('喜欢: ', token_dict['喜欢'])
  26. print('跳投: ', token_dict['跳投'])
  27. print('[EOS]: ', token_dict['[EOS]'])
  28. # 编码新句子,测试新词的编码
  29. test = tokenizer.encode(
  30. text = '我喜欢科比的后仰跳投[EOS]',
  31. text_pair = None,
  32. truncation = True,
  33. padding = 'max_length',
  34. add_special_tokens = True,
  35. max_length = 15,
  36. return_tensors = None
  37. )
  38. print(test)

输出结果:

  1. True
  2. 喜欢: 21128
  3. 跳投: 21129
  4. [EOS]: 21130
  5. [101, 2769, 21128, 4906, 3683, 4638, 1400, 814, 21129, 21130, 102, 0, 0, 0, 0]
  6. # 将喜欢、跳投和[EOS]直接编码,并没有拆开按字来编码

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/281441
推荐阅读
相关标签
  

闽ICP备14008679号