Transfromers的tokenizer

1. 获取tokenizer对象

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')

2. encode的几种方法对比

在这里插入图片描述

总结:tokenizer默认和encode_plus含义一样,即加好了token_type_ids,mask等label,类似于dict一样访问这个函数

tokenizer.encode 只是把 input_ids的结果拿下来,然后后面的属性可以自己在dataload定义, 比如是否加入 【sep】等

.join()的含义:
‘a’.join(‘b b b’) = ‘ba aba ab’
这样预处理是为了对于 tokenizer的中文没有区别,但是对于处理电话,如果不区分可能会导致 电话变成 unknow,切割开 可以使得这个token保留下来

3. tokenizer加入指定的vocab

way1:

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese', additional_special_tokens=['用户1:', '用户2:'])

这样可能会导致embedding的矩阵维度不对,会导致重新训练
这时候,可以考虑vocab.txt里面unused的label,这样可以避免重新train
way2:

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
tokenizer.vocab['用户1:'] = tokenizer.vocab.pop('[unused1]')
tokenizer.vocab['用户2:'] = tokenizer.vocab.pop('[unused2]')

4. 关于 替代 unused# token的问题

1. 存在的问题:unused 直接切分 并不能像 PAD 类似一样,做到不切分,这意味我们使用 unused 去赋值自己的special token是没有用的
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
print(tokenizer.encode('[unused9]'))
print(tokenizer.tokenize('[unused9]'))
print(tokenizer.convert_tokens_to_ids('[unused9]'))
print(tokenizer.encode('[SEP]'))

result:

[101, 138, 163, 11316, 8303, 8160, 140, 102]
['[', 'u', '##nus', '##ed', '##9', ']']
9
[101, 102, 102]

如何解决:

2. 替换vocab中的unused + never_split
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese',never_split=['[unused1]','[咨询师:]'])
tokenizer.vocab['[咨询师:]'] = tokenizer.vocab.pop('[unused2]')
print(tokenizer.tokenize('[unused1]'))
print(tokenizer.encode('[unused1]'))
print(tokenizer.tokenize('[咨询师:]'))
print(tokenizer.encode('[咨询师:]'))
tokenizer.save_vocabulary("./")
tokenizer = BertTokenizer.from_pretrained('./vocab.txt',never_split=['[unused1]','[咨询师:]'])
print(tokenizer.tokenize('[unused1]'))
print(tokenizer.encode('[unused1]'))
print(tokenizer.tokenize('[咨询师:]'))
print(tokenizer.encode('[咨询师:]'))
print(len(tokenizer.get_vocab()))

result:

['[unused1]']
[101, 1, 102]
['[', '咨', '询', '师', ':', ']']
[101, 138, 1486, 6418, 2360, 8038, 140, 102]
['[unused1]']
[101, 1, 102]
['[', '咨', '询', '师', ':', ']']
[101, 138, 1486, 6418, 2360, 8038, 140, 102]
21128

还是把咨询师切开了, 修改vocab文件,重新打开也没用
这时候,我想到 stackoverflow上面说修改文件时可行的,那么有可能是中文的问题,所以把咨询师改成英文huawei,测试效果如下:

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
tokenizer.vocab['[huawei]'] = tokenizer.vocab.pop('[unused2]')
print(tokenizer.tokenize('[unused1]'))
print(tokenizer.encode('[unused1]'))
print(tokenizer.tokenize('[huawei]'))
print(tokenizer.encode('[huawei]'))
print('-------------------------------------------------------')
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese',never_split=['[unused1]','[huawei]'])
tokenizer.vocab['[huawei]'] = tokenizer.vocab.pop('[unused2]')
print(tokenizer.tokenize('[unused1]'))
print(tokenizer.encode('[unused1]'))
print(tokenizer.tokenize('[huawei]'))
print(tokenizer.encode('[huawei]'))
print('-------------------------------------------------------')
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese',never_split=['[unused1]','[hua wei]'])
tokenizer.vocab['[hua wei]'] = tokenizer.vocab.pop('[unused3]')
print(tokenizer.tokenize('[unused1]'))
print(tokenizer.encode('[unused1]'))
print(tokenizer.tokenize('[hua wei]'))
print(tokenizer.encode('[hua wei]'))
print(len(tokenizer.get_vocab()))
结果:

```python
['[', 'u', '##nus', '##ed', '##1', ']']
[101, 138, 163, 11316, 8303, 8148, 140, 102]
['[', 'huawei', ']']
[101, 138, 12247, 140, 102]
-------------------------------------------------------
['[unused1]']
[101, 1, 102]
['[huawei]']
[101, 2, 102]
-------------------------------------------------------
['[unused1]']
[101, 1, 102]
['[', 'hu', '##a', 'wei', ']']
[101, 138, 12199, 8139, 11875, 140, 102]
21128

得出结论:如果是 英文 且没用空格区分,则never_split函数有效

3. 使用add_token() 操作
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
print(tokenizer.vocab_size)
tokenizer.add_tokens('客户1')
print(tokenizer.encode('客户1'))
print(tokenizer.vocab_size)

未完待续(embedding维度不对了)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值