日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WordPiece、BPE详解及代码

發布時間:2023/12/16 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WordPiece、BPE详解及代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.BPE是干什么用的?

WordPiece字面理解是把word拆成piece一片一片,其實就是這個意思。
WordPiece的一種主要的實現方式叫做BPE(Byte-Pair Encoding)雙字節編碼。
“loved”,“loving”,“loves"這三個單詞。其實本身的語義都是“愛”的意思,但是如果我們以單詞為單位,那它們就算不一樣的詞,在英語中不同后綴的詞非常的多,就會使得詞表變的很大,訓練速度變慢,訓練的效果也不是太好。
BPE算法通過訓練,能夠把上面的3個單詞拆分成"lov”,“ed”,“ing”,"es"幾部分,這樣可以把詞的本身的意思和時態分開,有效的減少了詞表的數量。

BPE的作用如下:

1.傳統詞表示方法無法很好的處理未知或罕見的詞匯(OOV問題:out of vocabulary)

2.傳統詞tokenization方法不利于模型學習詞綴之前的關系

3.Character embedding作為OOV的解決方法粒度太細

4.Subword粒度在詞與字符之間,能夠較好的平衡OOV問題

2.BPE算法

1.準備足夠大的訓練語料

2.確定期望的subword詞表大小

3.將單詞拆分為字符序列并在末尾添加后綴“ </ w>”,統計單詞頻率。本階段的subword的粒度是字符。例如,“ low”的頻率為5,那么我們將其改寫為“ l o w </ w>”:5
(備注:為什么加入"< /w >"在解碼階段有說明)

4.統計每一個連續字節對的出現頻率,選擇最高頻者合并成新的subword

5.重復第4步直到達到第2步設定的subword詞表大小或下一個最高頻的字節對出現頻率為1

例子

{'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w e s t </w>': 6, 'w i d e s t </w>': 3}Iter 1, 最高頻連續字節對"e""s"出現了6+3=9次,合并成"es"。輸出: {'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w es t </w>': 6, 'w i d es t </w>': 3}Iter 2, 最高頻連續字節對"es""t"出現了6+3=9, 合并成"est"。輸出: {'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w est </w>': 6, 'w i d est </w>': 3}Iter 3, 以此類推,最高頻連續字節對為"est""</w>" 輸出: {'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w est</w>': 6, 'w i d est</w>': 3}Iter n, 繼續迭代直到達到預設的subword詞表大小或下一個最高頻的字節對出現頻率為1

說明
每次合并后詞表可能出現3種變化:

+1,表明加入合并后的新字詞,同時原來在2個子詞還保留(2個字詞不是完全同時連續出現)

+0,表明加入合并后的新字詞,同時原來2個子詞中一個保留,一個被消解(一個字詞完全隨著另一個字詞的出現而緊跟著出現)

-1,表明加入合并后的新字詞,同時原來2個子詞都被消解(2個字詞同時連續出現)

實際上,隨著合并的次數增加,詞表大小通常先增加后減小。

3.BPE代碼實現

import re, collectionsdef get_stats(vocab):pairs = collections.defaultdict(int)for word, freq in vocab.items():symbols = word.split()for i in range(len(symbols)-1):pairs[symbols[i],symbols[i+1]] += freqreturn pairsdef merge_vocab(pair, v_in):v_out = {}bigram = re.escape(' '.join(pair))p = re.compile(r'(?<!\S)' + bigram + r'(?!\S)')for word in v_in:w_out = p.sub(''.join(pair), word)v_out[w_out] = v_in[word]return v_outvocab = {'l o w </w>': 5, 'l o w e r </w>': 2, 'n e w e s t </w>': 6, 'w i d e s t </w>': 3} num_merges = 1000 for i in range(num_merges):pairs = get_stats(vocab)if not pairs:breakbest = max(pairs, key=pairs.get)vocab = merge_vocab(best, vocab)print(best)# print output # ('e', 's') # ('es', 't') # ('est', '</w>') # ('l', 'o') # ('lo', 'w') # ('n', 'e') # ('ne', 'w') # ('new', 'est</w>') # ('low', '</w>') # ('w', 'i') # ('wi', 'd') # ('wid', 'est</w>') # ('low', 'e') # ('lowe', 'r') # ('lower', '</w>')

編碼:構建完詞表之后,對詞表按照長度進行排序。對于要預訓練的text,先將其按照詞表的順序進行分解(即編碼)。
如下例子:

# 給定單詞序列 [“the</w>, “highest</w>, “mountain</w>]# 假設已有排好序的subword詞表 [“errrr</w>, “tain</w>, “moun”, “est</w>, “high”, “the</w>, “a</w>]# 迭代結果 "the</w>" -> ["the</w>"] "highest</w>" -> ["high", "est</w>"] "mountain</w>" -> ["moun", "tain</w>"]

解碼

# 編碼序列 [“the</w>, “high”, “est</w>, “moun”, “tain</w>]# 解碼序列 “the</w> highest</w> mountain</w>

直接拼接起來,"< /w >"就可以隔離開不同的單詞。所以,加入"< /w >"是為了在解碼階段隔離開不同的單詞。

4.適用范圍

BPE一般適用在歐美語言,因為歐美語言大多是字符形式,涉及前綴、后綴的單詞比較多。而中文的漢字一般不用BPE進行編碼,因為中文是字無法進行拆分。對中文的處理通常只有分詞分字兩種。理論上分詞效果更好,更好的區別語義。分字效率高、簡潔,因為常用的字不過3000字,詞表更加簡短。
參考鏈接:
一文讀懂BERT中的WordPiece
NLP Subword三大算法原理:BPE、WordPiece、ULM

總結

以上是生活随笔為你收集整理的WordPiece、BPE详解及代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。