深入理解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.mzph.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…