BERT tokenization 处理英文句子 Wordpiece之后的处理技巧

Wordpiece可以将词转化为多个词片段,比如:Nanostructured 被切分为 ['Nan', '##ost', '##ru', '##cture', '##d'],相比直接使用空格进行分词表示的方式,通过种排列组合的方式组成更多的单词,可以把词的本身的意思和时态分开,有效的减少了词表的数量[1]。被切分出来的词叫做Subword,十分形象。

Transformers包中自带了tokenizer方法可以帮助我们实现Wordpiece,但是被切的词汇会改变原有的句子长度,在做序列标注的时候,经过token转化的句子长度无法和标签长度进行对应,此时一种解决方法是记录其词首的位置,用于后期的标注。

本文为其记录句首词的小trick,常见于序列标注任务中。使用numpy的累加方法cumsum来获取其词首位置。

import numpy as np
from transformers import BertTokenizer

bert_class = 'pretrained_model/bert-base-cased'  # 提前下好的预训练模型的位置
tokenizer = BertTokenizer.from_pretrained(bert_class, do_lower_case=False)
sentences = []  # 存储结果的列表
line = 'Nanostructured Pt-alloy electrocatalysts for PEM fuel cell oxygen reduction reaction' 样例句子

tokens = line.strip().split(' ')  # 按照空格进行分词

subwords = list(map(tokenizer.tokenize, tokens))
"""
[['Nan', '##ost', '##ru', '##cture', '##d'], ['P', '##t', '-', 'alloy'], ['electro', '##cat', '##aly', '##sts'], ['for'], ['P', '##EM'], ['fuel'], ['cell'], ['oxygen'], ['reduction'], ['reaction']]
"""
subword_lengths = list(map(len, subwords))
# [5, 4, 4, 1, 2, 1, 1, 1, 1, 1]

subwords = ['[CLS]'] + [item for indices in subwords for item in indices]
# ['[CLS]', 'Nan', '##ost', '##ru', '##cture', '##d', 'P', '##t', '-', 'alloy', 'electro', '##cat', '##aly', '##sts', ...]
# cls直接加到句首,并且列表

token_start_idxs = 1 + np.cumsum([0] + subword_lengths[:-1])
# 基于cumsum方法对长度进行累加,获取词首index,整体+1,相当于加入了cls标记占位的影响

sentences.append((tokenizer.convert_tokens_to_ids(subwords),token_start_idxs))
# 存入结果,这里可以携程循环用于data loader中

 

参考:

[1]  一文读懂BERT中的WordPiece: https://www.cnblogs.com/huangyc/p/10223075.html

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值