bpe分词算法的原理

概述:

bpe(byte pair encoding),是一种根据字节对进行编码的算法。主要目的是为了数据压缩,算法描述为字符串里频率最常见的一对字符被一个没有在这个字符中出现的字符代替的层层迭代过程。该算法在论文:https://arxiv.org/abs/1508.07909 Neural Machine Translation of Rare Words with Subword Units详细介绍

训练过程:

对于使用子词作为基本单位进行训练的神经机器翻译模型,训练的第一步就是根据语料生成bpe的code资源,以英文为例,该资源会将训练语料以字符为单位进行拆分,按照字符对进行组合,并对所有组合的结果根据出现的频率进行排序,出现频次越高的排名越靠前,排在第一位的是出现频率最高的子词。如图所示:e </w>为出现频率最高的子词,其中</w>表示这个e是作为单词结尾的字符。训练过程结束,会生成codec文件。如下图所示: 

                                                           

解码过程:

以单词“where”为例,首先按照字符拆分开,然后查找codec文件,逐对合并,优先合并频率靠前的字符对。85 319 9 15 表示在该字符对在codec文件中的评率排名。

最终where</w>可以在codec文件中被找到,因此where的bpe分词结果为where</w>,对于其他并不能像where一样能在codec文件中找到整个词的词来说,bpe分词结果以最终查询结束时的分词结果为准。

BPE(Byte Pair Encoding)算法是一种强大的子词分词算法,在自然语言处理领域广泛应用[^1]。其原理主要包含以下步骤: ### 初始化 将语料库中所有单词拆分为字符序列,并在每个单词末尾添加词尾标记(如 </w>)。例如,对于输入单词 “lowest”,会先将其拆分为字符序列并添加词尾标记:l o w e s t </w> [^2]。 ### 统计字符对频率 对语料库中所有相邻的字符对(bigrams)出现的频率进行统计。例如,在语料中 “l” 和 “o” 相邻出现的次数,“o” 和 “w” 相邻出现的次数等。 ### 合并最频繁的字符对 选择出现频率最高的字符对,将它们合并成一个新的子词。例如,如果 “l” 和 “o” 是出现频率最高的字符对,就将它们合并为 “lo”。然后更新语料库,把所有 “l” 和 “o” 相邻的地方都替换成 “lo”,并重新统计相邻子词对的频率。 ### 迭代合并 重复上述合并最频繁子词对的步骤,直到达到预设的合并次数或者词汇表大小。每一次合并都会产生新的子词,随着迭代的进行,语料库中的单词会逐渐被拆分为更有意义的子词组合。 ### 分词 使用训练好的词汇表将新输入的文本进行分词。对于新的单词,按照训练得到的子词进行拆分,如果遇到词汇表中没有的子词,则将其拆分为更小的子词,直到所有部分都能在词汇表中找到或者拆分为单个字符 [^2]。 ### 代码示例 以下是一个简单的 Python 代码示例,用于演示 BPE 算法的基本原理: ```python import re from collections import defaultdict def get_stats(vocab): pairs = defaultdict(int) for word, freq in vocab.items(): symbols = word.split() for i in range(len(symbols) - 1): pairs[symbols[i], symbols[i + 1]] += freq return pairs def 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_out # 示例语料库 corpus = {'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 = 3 for i in range(num_merges): pairs = get_stats(corpus) if not pairs: break best = max(pairs, key=pairs.get) corpus = merge_vocab(best, corpus) print(corpus) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值