赞
踩
大家好,我是Xueliang,又和大家见面了。
我最近在打机器翻译的一个比赛,主要使用基于BERT的模型。在这其中,一个小的知识点引起了我的好奇,就是在将英语训练语料输入到BERT模型之前,需要对其进行BPE(Byte Pair Encoding)的操作。作为一名合格的算法工程师,当然是要搞清楚其中的原理啦~本篇文章就带大家一起快速搞懂BPE分词算法。
本文主要分成两个部分,内容1500字,阅读耗时大约8分钟:
BPE算法[1],其目的是使用一些子词来编码数据。该方法已经成为了BERT等模型标准的数据预处理处理方式。
在机器翻译领域,模型训练之前一个很重要的步骤就是构建词表。对于英文语料,一个很自然的想法就是用训练语料中出现过的所有英语单词来构建词表,但是这样的方法存在两个问题:
另外一种方式是使用单个字符来构建词表。英文字符的个数是有限的,基于字符的方式可以有效缓解词表数目过大以及OOV的问题,但由于其粒度太细,丢失了很多单词本身所具有的语意信息。
为了解决上述问题,基于Subword(子词)的算法被提出,其中的代表就是BPE算法,BPE算法的分词粒度处于单词级别和字符级别之间。比如说单词"looked"和"looking"会被划分为"look","ed”,“ing”,这样在降低词表大小的同时也能学到词的语意信息。
BPE算法的核心主要分成三个部分:
词表构建是BPE算法的核心,其是根据训练语料来构建BPE算法的词表。算法的整体步骤如下所示:
下面我们通过一个例子来搞懂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算法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。