赞
踩
AutoTokenizer() 常用于分词,其可调用现成的模型来对输入句子进行分词。
测试代码:
- # 分词器测试Demo
- from transformers import AutoTokenizer
-
- if __name__ == "__main__":
- checkpoint = "distilbert-base-uncased-finetuned-sst-2-english" # 使用该模型
- tokenlizer = AutoTokenizer.from_pretrained(checkpoint) # 加载该模型对应的分词器
-
- raw_input = [
- "I love kobe bryant.",
- "Me too."
- ]
-
- inputs = tokenlizer(raw_input, padding = True, return_tensors = "pt") # padding并返回pytorch版本的tensor
- print("After tokenlizer: \n", inputs) # 打印分词后的结果
-
- str1 = tokenlizer.decode(inputs['input_ids'][0]) # 将词ID恢复
- print("str1: \n", str1)
-
- print("All done!")
输出结果:
- After tokenlizer:
- {
- 'input_ids': tensor([[101, 1045, 2293, 24113, 12471, 1012, 102],
- [101, 2033, 2205, 1012, 102, 0, 0]]),
- 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1],
- [1, 1, 1, 1, 1, 0, 0]])
- }
- str1:
- [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 重新解码为句子。
设置 padding 时,可以指定具体的 padding 长度;
- from transformers import AutoTokenizer
-
- if __name__ == "__main__":
- checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
- tokenlizer = AutoTokenizer.from_pretrained(checkpoint)
-
- raw_input = [
- "I love kobe bryant.",
- "Me too."
- ]
-
- input1 = tokenlizer(raw_input, padding = "longest", return_tensors = "pt") # padding长度与输入中的最长句子相同
- input2 = tokenlizer(raw_input, padding = "max_length", return_tensors = "pt") # padding到最大句子长度,默认是512
- input3 = tokenlizer(raw_input, padding = "max_length", max_length = 10, return_tensors = "pt") # 指定最大长度是10
- print("After tokenlizer: \n", input1['input_ids'].shape)
- print("After tokenlizer: \n", input2['input_ids'].shape)
- print("After tokenlizer: \n", input3['input_ids'].shape)
输出结果:
- After tokenlizer:
- torch.Size([2, 7])
- After tokenlizer:
- torch.Size([2, 512])
- After tokenlizer:
- torch.Size([2, 10])
设置 truncation 时,用于截断,可以指定截断的长度。
- from transformers import AutoTokenizer
-
- if __name__ == "__main__":
- checkpoint = "distilbert-base-uncased-finetuned-sst-2-english"
- tokenlizer = AutoTokenizer.from_pretrained(checkpoint)
-
- raw_input = [
- "I love kobe bryant.",
- "Me too."
- ]
-
- # 长度超过5的部分会被截断
- input1 = tokenlizer(raw_input, padding = "longest", truncation = True, max_length=5, return_tensors = "pt")
- print("After tokenlizer: \n", input1)
-
- str1 = tokenlizer.decode(input1['input_ids'][0]) # 将词ID恢复
- print("str1: \n", str1)
输出结果:
- After tokenlizer:
- {
- 'input_ids': tensor([[ 101, 1045, 2293, 24113, 102],
- [ 101, 2033, 2205, 1012, 102]]),
- 'attention_mask': tensor([[1, 1, 1, 1, 1],
- [1, 1, 1, 1, 1]])
- }
- str1:
- [CLS] i love kobe [SEP]
① 编码两个句子:
- from transformers import BertTokenizer
-
- if __name__ == "__main__":
- tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
- sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
-
- # 编码两个句子
- inputs = tokenizer.encode(
- text = sents[0],
- text_pair = sents[1],
- truncation = True, # 截断
- padding = 'max_length', # padding到最大长度
- add_special_tokens = True,
- max_length = 20, # 设置最大长度
- return_tensors = None # None默认返回list,可取值tf,pt,np
- )
-
- print(inputs)
- print(tokenizer.decode(inputs))
输出结果:
- inputs:
- [101, 2769, 1599, 3614, 4906, 3683, 2357, 5812, 2617, 4294, 119, 102, 2769, 738, 3221, 119, 102, 0, 0, 0]
- decode:
- [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] 我 也 是. [SEP] [PAD] [PAD] [PAD]
② 增强编码
- from transformers import BertTokenizer
-
- if __name__ == "__main__":
- tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
- sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
-
- # 增强编码两个句子
- inputs = tokenizer.encode_plus(
- text = sents[0],
- text_pair = sents[1],
- truncation = True, # 截断
- padding = 'max_length', # padding到最大长度
- add_special_tokens = True,
- max_length = 30, # 设置最大长度
- return_tensors = None, # None默认返回list,可取值tf,pt,np,
- return_token_type_ids = True,
- return_attention_mask = True,
- return_special_tokens_mask = True,
- return_length = True
- )
-
- for k, v in inputs.items():
- print(k, ':', v)
-
- print(tokenizer.decode(inputs['input_ids']))
输出结果:
- 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]
-
- 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]
-
- 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]
-
- 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]
-
- length : 30
-
- decode:
- [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] 我 也 是. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]
③ 批量编码:
- from transformers import BertTokenizer
-
- if __name__ == "__main__":
- tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
- sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
-
- # 批量编码句子
- inputs = tokenizer.batch_encode_plus(
- batch_text_or_text_pairs = [sents[0], sents[1]],
- truncation = True, # 截断
- padding = 'max_length', # padding到最大长度
- add_special_tokens = True,
- max_length = 20, # 设置最大长度
- return_tensors = None, # None默认返回list,可取值tf,pt,np,
- return_token_type_ids = True,
- return_attention_mask = True,
- return_special_tokens_mask = True,
- return_length = True
- )
-
- for k, v in inputs.items():
- print(k, ':', v)
-
- print("decode: \n", tokenizer.decode(inputs['input_ids'][0]))
- print("decode: \n", tokenizer.decode(inputs['input_ids'][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]]
-
- 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]]
-
- 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]]
-
- length : [12, 6]
-
- 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]]
-
- decode:
- [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]
-
- decode:
- [CLS] 我 也 是. [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]
④ 批量编码成对的句子:
- from transformers import BertTokenizer
-
- if __name__ == "__main__":
- tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
- sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
-
- # 批量编码成对的句子
- inputs = tokenizer.batch_encode_plus(
- batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
- truncation = True, # 截断
- padding = 'max_length', # padding到最大长度
- add_special_tokens = True,
- max_length = 20, # 设置最大长度
- return_tensors = None, # None默认返回list,可取值tf,pt,np,
- return_token_type_ids = True,
- return_attention_mask = True,
- return_special_tokens_mask = True,
- return_length = True
- )
-
- for k, v in inputs.items():
- print(k, ':', v)
-
- print("decode: \n", tokenizer.decode(inputs['input_ids'][0]))
- print("decode: \n", 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], [101, 2769, 1599, 3614, 800, 4638, 1400, 814, 6663, 2832, 102, 2769, 1599, 3614, 800, 4638, 3294, 2349, 5125, 102]]
-
- 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]]
-
- 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]]
-
- length : [17, 20]
-
- 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]]
-
- decode:
- [CLS] 我 喜 欢 科 比 布 莱 恩 特. [SEP] 我 也 是. [SEP] [PAD] [PAD] [PAD]
-
- decode:
- [CLS] 我 喜 欢 他 的 后 仰 跳 投 [SEP] 我 喜 欢 他 的 曼 巴 精 [SEP]
⑤ 获取字典:
- from transformers import BertTokenizer
-
- if __name__ == "__main__":
- tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
- sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
-
- # 批量编码成对的句子
- inputs = tokenizer.batch_encode_plus(
- batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
- truncation = True, # 截断
- padding = 'max_length', # padding到最大长度
- add_special_tokens = True,
- max_length = 20, # 设置最大长度
- return_tensors = None, # None默认返回list,可取值tf,pt,np,
- return_token_type_ids = True,
- return_attention_mask = True,
- return_special_tokens_mask = True,
- return_length = True
- )
-
- # 获取字典
- token_dict = tokenizer.get_vocab()
-
- print(type(token_dict))
- print(len(token_dict))
- print('喜' in token_dict) # 中文是按字来编码的,因此喜在字典里
- print('喜欢' in token_dict) # 同理,喜欢不在字典里
输出结果:
- <class 'dict'>
- 21128
- True
- False
⑥ 添加新字典:
- from transformers import BertTokenizer
-
- if __name__ == "__main__":
- tokenizer = BertTokenizer.from_pretrained(pretrained_model_name_or_path = 'bert-base-chinese')
- sents = ['我喜欢科比布莱恩特.', '我也是.', '我喜欢他的后仰跳投', '我喜欢他的曼巴精神']
-
- # 批量编码成对的句子
- inputs = tokenizer.batch_encode_plus(
- batch_text_or_text_pairs=[(sents[0], sents[1]), (sents[2], sents[3])],
- truncation = True, # 截断
- padding = 'max_length', # padding到最大长度
- add_special_tokens = True,
- max_length = 20, # 设置最大长度
- return_tensors = None, # None默认返回list,可取值tf,pt,np,
- return_token_type_ids = True,
- return_attention_mask = True,
- return_special_tokens_mask = True,
- return_length = True
- )
-
- # 添加新词
- tokenizer.add_tokens(new_tokens=['喜欢', '跳投'])
- # 添加新符号
- tokenizer.add_special_tokens({'eos_token': '[EOS]'})
- # 获取字典
- token_dict = tokenizer.get_vocab()
- print('喜欢' in token_dict) # 添加新词后,喜欢在字典里
- print('喜欢: ', token_dict['喜欢'])
- print('跳投: ', token_dict['跳投'])
- print('[EOS]: ', token_dict['[EOS]'])
-
- # 编码新句子,测试新词的编码
- test = tokenizer.encode(
- text = '我喜欢科比的后仰跳投[EOS]',
- text_pair = None,
- truncation = True,
- padding = 'max_length',
- add_special_tokens = True,
- max_length = 15,
- return_tensors = None
- )
- print(test)
输出结果:
- True
- 喜欢: 21128
- 跳投: 21129
- [EOS]: 21130
- [101, 2769, 21128, 4906, 3683, 4638, 1400, 814, 21129, 21130, 102, 0, 0, 0, 0]
-
- # 将喜欢、跳投和[EOS]直接编码,并没有拆开按字来编码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。