一文搞懂BPE分词算法
大家好,我是Xueliang,又和大家见面了。
我最近在打机器翻译的一个比赛,主要使用基于BERT的模型。在这其中,一个小的知识点引起了我的好奇,就是在将英语训练语料输入到BERT模型之前,需要对其进行BPE(Byte Pair Encoding)的操作。作为一名合格的算法工程师,当然是要搞清楚其中的原理啦~本篇文章就带大家一起快速搞懂BPE分词算法。
本文主要分成两个部分,内容1500字,阅读耗时大约8分钟:
- BPE分词算法的由来
- BPE分词算法的流程
- 词表构建
- 语料编码
- 语料解码
BPE分词算法的由来
BPE算法[1],其目的是使用一些子词来编码数据。该方法已经成为了BERT等模型标准的数据预处理处理方式。
在机器翻译领域,模型训练之前一个很重要的步骤就是构建词表。对于英文语料,一个很自然的想法就是用训练语料中出现过的所有英语单词来构建词表,但是这样的方法存在两个问题:
- 训练语料中出现过的单词数目很多,这样的构造方式会使得词表变得很大,从而降低训练速度;
- 在模型测试中,很难处理罕见词或者训练过程中没有见过的词(OOV问题)。
另外一种方式是使用单个字符来构建词表。英文字符的个数是有限的,基于字符的方式可以有效缓解词表数目过大以及OOV的问题,但由于其粒度太细,丢失了很多单词本身所具有的语意信息。
为了解决上述问题,基于Subword(子词)的算法被提出,其中的代表就是BPE算法,BPE算法的分词粒度处于单词级别和字符级别之间。比如说单词"looked"和"looking"会被划分为"look","ed”,“ing”,这样在降低词表大小的同时也能学到词的语意信息。
BPE分词算法的流程
BPE算法的核心主要分成三个部分:
- 词表构建
- 语料编码
- 语料解码
词表构建
词表构建是BPE算法的核心,其是根据训练语料来构建BPE算法的词表。算法的整体步骤如下所示:
- 准备模型的训练语料
- 确定期望的词表大小
- 将训练语料中的所有单词拆分为字符序列,利用这些字符序列构建初始的词表
- 统计训练语料中每一个连续字节对出现的频率,选择出现频率最高的字节对合并成新的subword,并更新词表
- 重复第4步,直到词表大小达到我们设定的期望或者剩下的字节对出现频率最高为1
下面我们通过一个例子来搞懂BPE词表构建的过程。假设我们目前的训练语料中出现过的单词如下,我们构建初始词表:
值得注意的是,我们在每一个单词的后面都加入了一个新的字符<\w>
来表示这个单词的结束。初始的词表大小为7,其为训练语料中所有出现过的字符。
我们之后发现lo
这个字节对在训练语料中出现频率最高,为3次。我们更新词表,将lo
作为新的子词加入词表,并删除在当前训练语料中不单独出现的字符l
和o
。
之后我们发现low
这个字节对在训练语料中出现频率最高,为3次。我们继续组合,将low
加入词表中,并删去lo
。需要注意的是,由于字符w
在单词newer
中仍然存在,因此不予删除。
之后我们继续这个循环过程,在词表中加入er
,并删去字符r
我们一直循环这个过程,直到词表大小达到我们设定的期望或者剩下的字节对出现频率最高为1。
最终我们就得到了基于训练样本构建好的词表。
语料编码
词表构建好后,我们需要给训练语料中的单词进行编码。编码方式如下:
- 我们首先将词表中所有的子词按照长度从大到小进行排序
- 对于每一个给定的单词,我们遍历排序好的词表,寻找词表中的子词是否是该单词的子字符串。如果正好匹配,则输出当前子词,并对单词剩下的字符串继续匹配
- 如果遍历完词表,单词中仍然有子字符串没有被匹配,那我们将其替换为一个特殊的子词,比如
<unk>
。
具个例子,假设我们现在构建好的词表为
(“errrr</w>”,
“tain</w>”,
“moun”,
“est</w>”,
“high”,
“the</w>”,
“a</w>”)
对于给定的单词mountain</w>
,其分词结果为:[moun
, tain</w>
]
语料解码
语料解码就是将所有的输出子词拼在一起,直到碰到结尾为<\w>
。举个例子,假设模型输出为:
["moun", "tain</w>", "high", "the</w>"]
那么其解码的结果为
["mountain</w>", "highthe</w>"]
总结
在本文中,我们一起学习了BPE的分词算法,该算法是利用子词来编码数据,已经成为目前机器翻译领域标准的预处理方式。
参考文献
[1]Sennrich, Rico, Barry Haddow, and Alexandra Birch. “Neural machine translation of rare words with subword units.” ACL 2016.
[2]https://zhuanlan.zhihu.com/p/198964217
[3]https://zhuanlan.zhihu.com/p/86965595
[4]https://www.cnblogs.com/huangyc/p/10223075.html
更多算法基础知识介绍,前沿论文解读,欢迎关注微信公众号:口袋AI算法
一文搞懂BPE分词算法相关推荐
- 【JVM】一文搞懂常见GC算法
文章内容 1.概述 2.如何确定垃圾对象? 3.GC算法 4.GC算法总结 5.常见的垃圾收集器 1.概述 GC目的:程序运行过程中可能会产生许多垃圾对象,持续占用内存会造成内存泄漏,最终可能导致内存 ...
- 一文搞懂K-means聚类算法
一步步教你轻松学K-means聚类算法 阅读目录 目录 聚类 K-means(k均值)聚类算法 案例描述 从文件加载数据集 计算两个向量的欧氏距离 构建一个包含 K 个随机质心的集合 K-Means ...
- 一文搞懂Vue Diff算法
为什么需要diff算法? 对于一个容器(比如我们常用的#app)而言,它的内容一般有三种情况: 1.字符串类型,即是文本. 2.子节点数组,即含有一个或者多个子节点 3.null,即没有子节点 在vu ...
- 一文搞懂K近邻算法(KNN),附带多个实现案例
简介:本文作者为 CSDN 博客作者董安勇,江苏泰州人,现就读于昆明理工大学电子与通信工程专业硕士,目前主要学习机器学习,深度学习以及大数据,主要使用python.Java编程语言.平时喜欢看书,打篮 ...
- 一文搞懂模型量化算法
1,模型量化概述 1.1,模型量化优点 1.2,模型量化的方案 1.2.1,PTQ 理解 1.3,量化的分类 1.3.1,线性量化概述 2,量化算术 2.1,定点和浮点 2.2,量化浮点 2.2,量化 ...
- 一文搞懂k近邻(k-NN)算法(一)
原文链接 一文搞懂k近邻(k-NN)算法(一) 前几天和德川一起在学习会上讲解了k-NN算法,这里进行总结一下,力争用最 通俗的语言讲解以便更多同学的理解. 本文目录如下: 1.k近邻算法的基本概念, ...
- 一文搞懂 Raft 算法
一文搞懂Raft算法 正文 raft是工程上使用较为广泛的强一致性.去中心化.高可用的分布式协议.在这里强调了是在工程上,因为在学术理论界,最耀眼的还是大名鼎鼎的Paxos.但Paxos是:少数真正理 ...
- 一文搞懂HMM(隐马尔可夫模型)-Viterbi algorithm
***一文搞懂HMM(隐马尔可夫模型)*** 简单来说,熵是表示物质系统状态的一种度量,用它老表征系统的无序程度.熵越大,系统越无序,意味着系统结构和运动的不确定和无规则:反之,,熵越小,系统越有序, ...
- 一文搞懂Elasticsearch索引的mapping与setting
目录 Elasticsearch索引结构 Mapping Setting Elasticsearch索引结构 一个Elasticsearch索引的主要结构如下: {"test_index&q ...
最新文章
- 干货丨一份不可多得的深度学习技巧指南
- 全球无人车头部三强格局明确,百度自动驾驶估值400亿美金
- 智能合约重构社会契约(8)以太坊分片
- Combinations leetcode java
- 【译】 Web Components 的高级工具
- 直播预告 | 基于多智能体交流游戏的零资源机器翻译
- 非常详细的Exchange 功能路线图
- ulli*3 实现翻书动画效果
- Win7的市场份额终于超过XP了,以后可以逐渐考虑放弃ie6/7了!
- 程序员的职业选择,你应该知道的,持续更新ing
- asynchronous vs non-blocking
- python中类的参数怎么传_如何将整个类作为参数传递给另一个类的方法
- 【转】 Oracle中分区表的使用
- python名词解释数据仓库_python实现数据仓库ETL
- div常用效果方法-transform
- 编写程序,用户输入一个位以上的整数,输出其百位以上的数字。例如用户输入1234.则程序输出12.
- idea启动 tomcat 原理解析
- PMP课程笔记:第11章 项目风险管理
- 微信小程序获取点击事件的值
- php laravel日志报错,Laravel 文档阅读:错误 日志记录