WordPiece是如何基于词表对文本进行切分的
生活随笔
收集整理的这篇文章主要介绍了
WordPiece是如何基于词表对文本进行切分的
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
本文从PaddleNLP源码入手,分析WordPiece是如何基于词表对输入的文本进行子词切分的。
为了更好地阅读本文,你需要知道子词切分与tokenize相关的知识,可以参考我之前的文章:
- tokenizer简介
- tokenizers:BPE算法
WordPiece采用了一种贪心的最长匹配搜索算法来将原始文本切分成子词。
为简单起见,假设词表中只有三个子词:['un', 'aff', 'able'],我们要切分的单词是“unaffable”。具体做法是,初始化两个位置变量(start和end,分别表示最左侧字符的位置和最右侧字符的位置),然后将end逐个减1,每次移动后(包括初始时)都将从start到end的字符拼接起来,并查看它们是否在词表中。
另外,如果start不为0(即对应的字符不是开头的字符),那么需要在子词前面加上##。
本部分代码如下:
output_tokens = [] for token in whitespace_tokenize(text):# whitespace_tokenize是先将text按照空格切分,这对于输入一个句子的情况下有用# 接下来,把token想象成单词“unaffable”chars = list(token)if len(chars) > self.max_input_chars_per_word:# 这里做了一个限制:如果一个单词的长度超过了设定值(默认是100),那么便被标记为预先定义的字符,一般是`UNK`output_tokens.append(self.unk_token)continueis_bad = Falsestart = 0sub_tokens = []# 初始化了startwhile start < len(chars):end = len(chars)cur_substr = Nonewhile start < end:# 从最后一个字符逐个向左遍历,保证匹配到的子词是最长的substr = "".join(chars[start:end])if start > 0: # 添加特殊的连接符substr = "##" + substrif substr in self.vocab: # 姑且把vocab理解为一个列表或键为词表中单词的字典cur_substr = substrbreakend -= 1if cur_substr is None:# 这里是一个否决条件,如果end走了一遍仍没有找到合适的子词,那么说明当前从start到end组成的子词不在词表中is_bad = Truebreaksub_tokens.append(cur_substr)start = endif is_bad:# 只有有任意一部分不在词表中,那么当前token就被标记为`UNK`output_tokens.append(self.unk_token)else:output_tokens.extend(sub_tokens)总结
以上是生活随笔为你收集整理的WordPiece是如何基于词表对文本进行切分的的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: delphi调用dll
- 下一篇: 【谷歌地图--PlacesSDK集成】