深入理解NLP Subword算法:BPE、WordPiece、ULM

深入理解NLP Subword算法:BPE、WordPiece、ULM

本文首發于微信公眾號【AI充電站】,感謝大家的贊同、收藏和轉發()

轉自:深入理解NLP Subword算法:BPE、WordPiece、ULM

前言

Subword算法如今已經成為了一個重要的NLP模型性能提升方法。自從2018年BERT橫空出世橫掃NLP界各大排行榜之后,各路預訓練語言模型如同雨后春筍般涌現,其中Subword算法在其中已經成為標配。所以作為NLP界從業者,有必要了解下Subword算法的原理。

目錄

  1. 與傳統空格分隔tokenization技術的對比
  2. Byte Pair Encoding
  3. WordPiece
  4. Unigram Language Model
  5. 總結

1. 與傳統空格分隔tokenization技術的對比

  • 傳統詞表示方法無法很好的處理未知或罕見的詞匯(OOV問題)

  • 傳統詞tokenization方法不利于模型學習詞綴之間的關系

    • E.g. 模型學到的“old”, “older”, and “oldest”之間的關系無法泛化到“smart”, “smarter”, and “smartest”。
  • Character embedding作為OOV的解決方法粒度太細

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

2. Byte Pair Encoding (Sennrich et al., 2015)[1]^{[1]}[1]

BPE(字節對)編碼或二元編碼是一種簡單的數據壓縮形式,其中最常見的一對連續字節數據被替換為該數據中不存在的字節[2]^{[2]}[2]。 后期使用時需要一個替換表來重建原始數據。OpenAI GPT-2 與Facebook RoBERTa均采用此方法構建subword vector.

  • 優點

    • 可以有效地平衡詞匯表大小和步數(編碼句子所需的token數量)。
  • 缺點

    • 基于貪婪和確定的符號替換,不能提供帶概率的多個分片結果。

2.1 算法[3]^{[3]}[3]

  1. 準備足夠大的訓練語料
  2. 確定期望的subword詞表大小
  3. 將單詞拆分為字符序列并在末尾添加后綴“ </ w>”,統計單詞頻率。 本階段的subword的粒度是字符。 例如,“ low”的頻率為5,那么我們將其改寫為“ l o w </ w>”:5
  4. 統計每一個連續字節對的出現頻率,選擇最高頻者合并成新的subword
  5. 重復第4步直到達到第2步設定的subword詞表大小或下一個最高頻的字節對出現頻率為1

停止符"</w>“的意義在于表示subword是詞后綴。舉例來說:“st"字詞不加”</w>“可以出現在詞首如"st ar”,加了”</w>“表明改字詞位于詞尾,如"wide st</w>”,二者意義截然不同。

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

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

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

例子

輸入:

{'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"和"" 輸出:

{'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。

2.2 BPE實現[4]^{[4]}[4]

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>')

2.3 編碼和解碼[4]^{[4]}[4]

  • 編碼

在之前的算法中,我們已經得到了subword的詞表,對該詞表按照子詞長度由大到小排序。編碼時,對于每個單詞,遍歷排好序的子詞詞表尋找是否有token是當前單詞的子字符串,如果有,則該token是表示單詞的tokens之一。

我們從最長的token迭代到最短的token,嘗試將每個單詞中的子字符串替換為token。 最終,我們將迭代所有tokens,并將所有子字符串替換為tokens。 如果仍然有子字符串沒被替換但所有token都已迭代完畢,則將剩余的子詞替換為特殊token,如。

例子

# 給定單詞序列
[“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>"]

編碼的計算量很大。 在實踐中,我們可以pre-tokenize所有單詞,并在詞典中保存單詞tokenize的結果。 如果我們看到字典中不存在的未知單詞。 我們應用上述編碼方法對單詞進行tokenize,然后將新單詞的tokenization添加到字典中備用。

  • 解碼

將所有的tokens拼在一起。

例子:

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

3. WordPiece (Schuster et al., 2012)[5]^{[5]}[5]

WordPiece算法可以看作是BPE的變種。不同點在于,WordPiece基于概率生成新的subword而不是下一最高頻字節對。

3.1 算法[3]^{[3]}[3]

  1. 準備足夠大的訓練語料
  2. 確定期望的subword詞表大小
  3. 將單詞拆分成字符序列
  4. 基于第3步數據訓練語言模型
  5. 從所有可能的subword單元中選擇加入語言模型后能最大程度地增加訓練數據概率的單元作為新的單元
  6. 重復第5步直到達到第2步設定的subword詞表大小或概率增量低于某一閾值

4. Unigram Language Model (Kudo, 2018)[6]^{[6]}[6]

ULM是另外一種subword分隔算法,它能夠輸出帶概率的多個子詞分段。它引入了一個假設:所有subword的出現都是獨立的,并且subword序列由subword出現概率的乘積產生。WordPiece和ULM都利用語言模型建立subword詞表。

4.1 算法[3]^{[3]}[3]

  1. 準備足夠大的訓練語料
  2. 確定期望的subword詞表大小
  3. 給定詞序列優化下一個詞出現的概率
  4. 計算每個subword的損失
  5. 基于損失對subword排序并保留前X%。為了避免OOV,建議保留字符級的單元
  6. 重復第3至第5步直到達到第2步設定的subword詞表大小或第5步的結果不再變化

5. 總結

  1. subword可以平衡詞匯量和對未知詞的覆蓋。 極端的情況下,我們只能使用26個token(即字符)來表示所有英語單詞。一般情況,建議使用16k或32k子詞足以取得良好的效果,Facebook RoBERTa甚至建立的多達50k的詞表。
  2. 對于包括中文在內的許多亞洲語言,單詞不能用空格分隔。 因此,初始詞匯量需要比英語大很多。

參考

  1. Sennrich, Rico, Barry Haddow, and Alexandra Birch. "Neural machine translation of rare words with subword units."arXiv preprint arXiv:1508.07909(2015).
  2. Byte pair encoding - Wikipedia https://en.wikipedia.org/wiki/Byte_pair_encoding
  3. 3 subword algorithms help to improve your NLP model performance https://medium.com/@makcedward/how-subword-helps-on-your-nlp-model-83dd1b836f46
  4. Lei Mao’s Log Book – Byte Pair Encoding https://leimao.github.io/blog/Byte-Pair-Encoding/
  5. Schuster, Mike, and Kaisuke Nakajima. “Japanese and korean voice search.” 2012 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP). IEEE, 2012.
  6. Kudo, Taku. “Subword regularization: Improving neural network translation models with multiple subword candidates.” arXiv preprint arXiv:1804.10959 (2018).

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532390.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532390.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532390.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

http 錯誤 404.0 - not found_電腦Regsvr32 用法和錯誤消息的說明

? 對于那些可以自行注冊的對象鏈接和嵌入 (OLE) 控件&#xff0c;例如動態鏈接庫 (DLL) 文件或 ActiveX 控件 (OCX) 文件&#xff0c;您可以使用 Regsvr32 工具 (Regsvr32.exe) 來將它們注冊和取消注冊。Regsvr32.exe 的用法RegSvr32.exe 具有以下命令行選項&#xff1a; Regs…

mysql error 1449_MySql錯誤:ERROR 1449 (HY000)

筆者系統為 mac &#xff0c;不知怎的&#xff0c;Mysql 竟然報如下錯誤&#xff1a;ERROR 1449 (HY000): The user specified as a definer (mysql.infoschemalocalhost) does not exist一時沒有找到是什么操作導致的這個錯誤。然后經過查詢&#xff0c;參考文章解決了問題。登…

MobileNet 系列:從V1到V3

MobileNet 系列&#xff1a;從V1到V3 轉自&#xff1a;輕量級神經網絡“巡禮”&#xff08;二&#xff09;—— MobileNet&#xff0c;從V1到V3 自從2017年由谷歌公司提出&#xff0c;MobileNet可謂是輕量級網絡中的Inception&#xff0c;經歷了一代又一代的更新。成為了學習輕…

mysql 查詢表的key_mysql查詢表和字段的注釋

1,新建表以及添加表和字段的注釋.create table auth_user(ID INT(19) primary key auto_increment comment 主鍵,NAME VARCHAR(300) comment 姓名,CREATE_TIME date comment 創建時間)comment 用戶信息表;2,修改表/字段的注釋.alter table auth_user comment 修改后的表注…

mysql 高級知識點_這是我見過最全的《MySQL筆記》,涵蓋MySQL所有高級知識點!...

作為運維和編程人員&#xff0c;對MySQL一定不會陌生&#xff0c;尤其是互聯網行業&#xff0c;對MySQL的使用是比較多的。MySQL 作為主流的數據庫&#xff0c;是各大廠面試官百問不厭的知識點&#xff0c;但是需要了解到什么程度呢&#xff1f;僅僅停留在 建庫、創表、增刪查改…

teechart mysql_TeeChart 的應用

TeeChart 是一個很棒的繪圖控件&#xff0c;不過由于里面沒有注釋&#xff0c;網上相關的資料也很少&#xff0c;所以在應用的時候只能是一點點的試。為了防止以后用到的時候忘記&#xff0c;我就把自己用到的東西都記錄下來&#xff0c;以便以后使用的時候查詢。1、進制縮放圖…

NLP新寵——淺談Prompt的前世今生

NLP新寵——淺談Prompt的前世今生 轉自&#xff1a;NLP新寵——淺談Prompt的前世今生 作者&#xff1a;閔映乾&#xff0c;中國人民大學信息學院碩士&#xff0c;目前研究方向為自然語言處理。 《Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in…

mysql key_len_淺談mysql explain中key_len的計算方法

mysql的explain命令可以分析sql的性能&#xff0c;其中有一項是key_len(索引的長度)的統計。本文將分析mysql explain中key_len的計算方法。1、創建測試表及數據CREATE TABLE member (id int(10) unsigned NOT NULL AUTO_INCREMENT,name varchar(20) DEFAULT NULL,age tinyint(…

requestfacade 這個是什么類?_Java 的大 Class 到底是什么?

作者在之前工作中&#xff0c;面試過很多求職者&#xff0c;發現有很多面試者對Java的 Class 搞不明白&#xff0c;理解的不到位&#xff0c;一知半解&#xff0c;一到用的時候&#xff0c;就不太會用。想寫一篇關于Java Class 的文章&#xff0c;沒有那么多專業名詞&#xff0…

初學機器學習:直觀解讀KL散度的數學概念

初學機器學習&#xff1a;直觀解讀KL散度的數學概念 轉自&#xff1a;初學機器學習&#xff1a;直觀解讀KL散度的數學概念 譯自&#xff1a;https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-kl-divergence-2b382ca2b2a8 解讀…

php mysql讀取數據查詢_PHP MySQL 讀取數據

PHP MySQL 讀取數據從 MySQL 數據庫讀取數據SELECT 語句用于從數據表中讀取數據:SELECT column_name(s) FROM table_name我們可以使用 * 號來讀取所有數據表中的字段&#xff1a;SELECT * FROM table_name如需學習更多關于 SQL 的知識&#xff0c;請訪問我們的 SQL 教程。使用 …

MySQL應用安裝_mysql安裝和應用

1.下載mysql安裝包2.安裝mysql&#xff0c;自定義->修改路徑3.配置mysql&#xff0c;選擇自定義->server模式->500訪問量->勾選控制臺->設置gbk->設置密碼和允許root用戶遠程登錄等等。以管理員權限&#xff0c;在控制臺輸入&#xff1a;net start MySQL, 啟…

mysql 商品規格表_商品規格分析

產品表每次更新商品都會變動的&#xff0c;ID不能用&#xff0c;可是購物車還是用了&#xff0c;這就導致每次保存商品&#xff0c;哪怕什么都沒有改動&#xff0c;也會導致用戶的購物車失效。~~~其實可以考慮不是每次更新商品就除所有的SKU&#xff0c;畢竟有時什么都沒修改呢…

mysql維表的代理鍵字段_mysql多維數據倉庫指南--第三篇第12章(2)

賓夕法尼亞州地區客戶維在本節我將用賓夕法尼亞州地區客戶的子集維度來解釋第二種維度子集的類型。我也將向你說明如何測試該子集維度。相對的&#xff0c;一個向上鉆取的維包含了它基礎維的所有更高級別的數據。而一個特定子集維度則選擇了它基礎維的某個特定的數據集合。列表…

huggingface NLP工具包教程1:Transformers模型

huggingface NLP工具包教程1&#xff1a;Transformers模型 原文&#xff1a;TRANSFORMER MODELS 本課程會通過 Hugging Face 生態系統中的一些工具包&#xff0c;包括 Transformers&#xff0c; Datasets&#xff0c; Tokenizers&#xff0c; Accelerate 和 Hugging Face Hub。…

mysql日期比較timestamp_Mysql中的Datetime和Timestamp比較(轉載)

mysql中用于表示時間的三種類型date, datetime, timestamp (如果算上int的話&#xff0c;四種) 比較容易混淆&#xff0c;下面就比較一下這三種類型的異同相同點都可以用于表示時間都呈字符串顯示不同點1.顧名思義&#xff0c;date只表示YYYY-MM-DD形式的日期&#xff0c;datet…

隱馬爾可夫模型HMM推導

隱馬爾可夫模型HMM推導 機器學習-白板推導系列(十四)-隱馬爾可夫模型HMM&#xff08;Hidden Markov Model&#xff09; 課程筆記 背景介紹 介紹一下頻率派和貝葉斯派兩大流派發展出的建模方式。 頻率派 頻率派逐漸發展成了統計機器學習&#xff0c;該流派通常將任務建模為一…

ef mysql 的坑_C# EF 與 MySql 的那些坑

之前一直想用 mysql 和 ef 。然后多次嘗試也只能感嘆 還是 sqlsever 是親兒子。今天在單位又嘗試了一次&#xff0c;然后就成功了&#xff0c;記錄一下遇到的問題。首先是安裝包和驅動&#xff1f;。請保證 MySql.Data / MySql.Data.Entity.EF6 / mysql Connector/NET 版本對應…

使用randomaccessfile類將一個文本文件中的內容逆序輸出_Java 中比較常用的知識點:I/O 總結...

Java中I/O操作主要是指使用Java進行輸入&#xff0c;輸出操作. Java所有的I/O機制都是基于數據流進行輸入輸出&#xff0c;這些數據流表示了字符或者字節數據的流動序列。數據流是一串連續不斷的數據的集合&#xff0c;就象水管里的水流&#xff0c;在水管的一端一點一點地供水…

huggingface NLP工具包教程2:使用Transformers

huggingface NLP工具包教程2&#xff1a;使用Transformers 引言 Transformer 模型通常非常大&#xff0c;由于有數百萬到數百億個參數&#xff0c;訓練和部署這些模型是一項復雜的任務。此外&#xff0c;由于幾乎每天都有新模型發布&#xff0c;而且每個模型都有自己的實現&a…