WordPiece是如何基于词表对文本进行切分的
生活随笔
收集整理的這篇文章主要介紹了
WordPiece是如何基于词表对文本进行切分的
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本文從PaddleNLP源碼入手,分析WordPiece是如何基于詞表對輸入的文本進(jìn)行子詞切分的。
為了更好地閱讀本文,你需要知道子詞切分與tokenize相關(guān)的知識,可以參考我之前的文章:
- tokenizer簡介
- tokenizers:BPE算法
WordPiece采用了一種貪心的最長匹配搜索算法來將原始文本切分成子詞。
為簡單起見,假設(shè)詞表中只有三個子詞:['un', 'aff', 'able'],我們要切分的單詞是“unaffable”。具體做法是,初始化兩個位置變量(start和end,分別表示最左側(cè)字符的位置和最右側(cè)字符的位置),然后將end逐個減1,每次移動后(包括初始時)都將從start到end的字符拼接起來,并查看它們是否在詞表中。
另外,如果start不為0(即對應(yīng)的字符不是開頭的字符),那么需要在子詞前面加上##。
本部分代碼如下:
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:# 這里做了一個限制:如果一個單詞的長度超過了設(shè)定值(默認(rèn)是100),那么便被標(biāo)記為預(yù)先定義的字符,一般是`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走了一遍仍沒有找到合適的子詞,那么說明當(dāng)前從start到end組成的子詞不在詞表中is_bad = Truebreaksub_tokens.append(cur_substr)start = endif is_bad:# 只有有任意一部分不在詞表中,那么當(dāng)前token就被標(biāo)記為`UNK`output_tokens.append(self.unk_token)else:output_tokens.extend(sub_tokens)總結(jié)
以上是生活随笔為你收集整理的WordPiece是如何基于词表对文本进行切分的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: delphi调用dll
- 下一篇: Python - 安装sentencep