0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

理解什么是NLP Subword算法

jf_78858299 来源:天宏NLP 作者:Luke 2023-02-22 14:16 次阅读

前言

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)

BPE(字节对)编码或二元编码是一种简单的数据压缩形式,其中最常见的一对连续字节数据被替换为该数据中不存在的字节。后期使用时需要一个替换表来重建原始数据。OpenAI GPT-2 与Facebook RoBERTa均采用此方法构建subword vector.

  • 优点
    • 可以有效地平衡词汇表大小和步数(编码句子所需的token数量)。
  • 缺点
    • 基于贪婪和确定的符号替换,不能提供带概率的多个分片结果。

2.1 算法

  1. 准备足够大的训练语料
  2. 确定期望的subword词表大小
  3. 将单词拆分为字符序列并在末尾添加后缀“ ”,统计单词频率。本阶段的subword的粒度是字符。例如,“ low”的频率为5,那么我们将其改写为“ l o w ”:5
  4. 统计每一个连续字节对的出现频率,选择最高频者合并成新的subword
  5. 重复第4步直到达到第2步设定的subword词表大小或下一个最高频的字节对出现频率为1

停止符""的意义在于表示subword是词后缀。举例来说:"st"字词不加""可以出现在词首如"st ar",加了""表明改字词位于词尾,如"wide st",二者意义截然不同。

每次合并后词表可能出现3种变化:

  • +1,表明加入合并后的新字词,同时原来的2个子词还保留(2个字词不是完全同时连续出现)
  • +0,表明加入合并后的新字词,同时原来的2个子词中一个保留,一个被消解(一个字词完全随着另一个字词的出现而紧跟着出现)
  • -1,表明加入合并后的新字词,同时原来的2个子词都被消解(2个字词同时连续出现)

实际上,随着合并的次数增加,词表大小通常先增加后减小。

例子

输入:

{'l o w ': 5, 'l o w e r ': 2, 'n e w e s t ': 6, 'w i d e s t ': 3}

Iter 1, 最高频连续字节对"e"和"s"出现了6+3=9次,合并成"es"。输出:

{'l o w ': 5, 'l o w e r ': 2, 'n e w es t ': 6, 'w i d es t ': 3}

Iter 2, 最高频连续字节对"es"和"t"出现了6+3=9次, 合并成"est"。输出:

{'l o w ': 5, 'l o w e r ': 2, 'n e w est ': 6, 'w i d est ': 3}

Iter 3, 以此类推,最高频连续字节对为"est"和"" 输出:

{'l o w ': 5, 'l o w e r ': 2, 'n e w est': 6, 'w i d est': 3}

……

Iter n, 继续迭代直到达到预设的subword词表大小或下一个最高频的字节对出现频率为1。

2.2 BPE实现

import re, collections

def 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]] += freq
    return pairs

def merge_vocab(pair, v_in):
    v_out = {}
    bigram = re.escape(' '.join(pair))
    p = re.compile(r'(?\\S)''(?!\\S)')
    for word in v_in:
        w_out = p.sub(''.join(pair), word)
        v_out[w_out] = v_in[word]
    return v_out

vocab = {'l o w ': 5, 'l o w e r ': 2, 'n e w e s t ': 6, 'w i d e s t ': 3}
num_merges = 1000
for i in range(num_merges):
    pairs = get_stats(vocab)
    ifnot pairs:
        break
    best = max(pairs, key=pairs.get)
    vocab = merge_vocab(best, vocab)
    print(best)

# print output
# ('e', 's')
# ('es', 't')
# ('est', '')
# ('l', 'o')
# ('lo', 'w')
# ('n', 'e')
# ('ne', 'w')
# ('new', 'est')
# ('low', '')
# ('w', 'i')
# ('wi', 'd')
# ('wid', 'est')
# ('low', 'e')
# ('lowe', 'r')
# ('lower', '')

2.3 编码和解码

  • 编码

在之前的算法中,我们已经得到了subword的词表,对该词表按照子词长度由大到小排序。编码时,对于每个单词,遍历排好序的子词词表寻找是否有token是当前单词的子字符串,如果有,则该token是表示单词的tokens之一。

我们从最长的token迭代到最短的token,尝试将每个单词中的子字符串替换为token。最终,我们将迭代所有tokens,并将所有子字符串替换为tokens。如果仍然有子字符串没被替换但所有token都已迭代完毕,则将剩余的子词替换为特殊token,如。

例子

# 给定单词序列
[“the</w>”, “highestspanw>”, “mountain”]

# 假设已有排好序的subword词表
[“errrr</w>”, “tainspanw>”, “moun”, “est</w>”, “high”, “thespanw>”, “a”]

# 迭代结果
"the" -> ["the"]
"highest" -> ["high", "est"]
"mountain" -> ["moun", "tain"]

编码的计算量很大。在实践中,我们可以pre-tokenize所有单词,并在词典中保存单词tokenize的结果。如果我们看到字典中不存在的未知单词。我们应用上述编码方法对单词进行tokenize,然后将新单词的tokenization添加到字典中备用。

  • 解码

将所有的tokens拼在一起。

例子:

# 编码序列
[“theclass="hljs-name"w>”, “high”, “estclass="hljs-name"w>”, “moun”, “tainclass="hljs-name"w>”]

# 解码序列
“theclass="hljs-name"w> highestclass="hljs-name"w> mountainclass="hljs-name"w>”

3. WordPiece (Schuster et al., 2012)

WordPiece算法可以看作是BPE的变种。不同点在于,WordPiece基于概率生成新的subword而不是下一最高频字节对。

3.1 算法

  1. 准备足够大的训练语料
  2. 确定期望的subword词表大小
  3. 将单词拆分成字符序列
  4. 基于第3步数据训练语言模型
  5. 从所有可能的subword单元中选择加入语言模型后能最大程度地增加训练数据概率的单元作为新的单元
  6. 重复第5步直到达到第2步设定的subword词表大小或概率增量低于某一阈值

4. Unigram Language Model (Kudo, 2012)

ULM是另外一种subword分隔算法,它能够输出带概率的多个子词分段。它引入了一个假设:所有subword的出现都是独立的,并且subword序列由subword出现概率的乘积产生。WordPiece和ULM都利用语言模型建立subword词表。

4.1 算法

  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. 对于包括中文在内的许多亚洲语言,单词不能用空格分隔。因此,初始词汇量需要比英语大很多。

参考资料

https://en.wikipedia.org/wiki/Byte_pair_encoding

https://leimao.github.io/blog/Byte-Pair-Encoding/https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1804.10959)

https://medium.com/@makcedward/how-subword-helps-on-your-nlp-model-83dd1b836f46

https://arxiv.org/abs/1804.10959

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 语言模型
    +关注

    关注

    0

    文章

    434

    浏览量

    10044
  • nlp
    nlp
    +关注

    关注

    1

    文章

    463

    浏览量

    21821
收藏 人收藏

    评论

    相关推荐

    ChatGPT爆火背后,NLP呈爆发式增长!

    自然语言处理技术,用于计算机中模拟人类的对话和文本理解。主要源于AI大模型化的NLP技术突破是将深度学习技术与传统的NLP方法结合在一起,从而更好地提高NLP技术的准确性和效率。大模型
    的头像 发表于 02-13 09:47 2833次阅读

    MaxMatch文本匹配算法的实现

    NLP文本匹配算法
    发表于 03-13 11:12

    对朴素贝叶斯算法理解

    我对朴素贝叶斯算法理解
    发表于 05-15 14:13

    NLP的面试题目

    NLP面试题目6-10
    发表于 05-21 15:02

    NLP的tfidf作词向量

    NLP之tfidf作词向量
    发表于 06-01 17:28

    对于PID控制/算法理解

    补充一下,他们的视频真的把我看哭了以下是对于PID控制/算法理解、总结:1.PID算法有什么好?首先说为什么要用PID算法,咱们使用单片机直接电平控制多简单,它不香吗?在这里咱们可以
    发表于 01-14 08:46

    PID算法理解

    PID算法理解
    发表于 11-17 18:35 2次下载

    NLP的介绍和如何利用机器学习进行NLP以及三种NLP技术的详细介绍

    本文用简洁易懂的语言,讲述了自然语言处理(NLP)的前世今生。从什么是NLP到为什么要学习NLP,再到如何利用机器学习进行NLP,值得一读。这是该系列的第一部分,介绍了三种
    的头像 发表于 06-10 10:26 7.7w次阅读
    <b class='flag-5'>NLP</b>的介绍和如何利用机器学习进行<b class='flag-5'>NLP</b>以及三种<b class='flag-5'>NLP</b>技术的详细介绍

    仔细讨论NLP模型的泛化问题

    前段时间的文章《顶会见闻系列:ACL 2018,在更具挑战的环境下理解数据表征及方法评价》中,我们介绍了 ACL 大会上展现出的 NLP 领域的最新研究风向和值得关注的新进展。
    的头像 发表于 09-10 10:45 4212次阅读

    一位NLP算法工程师对NLP的看法

    最近的项目就是NLP相关,说一些个人对NLP的看法。直观地看,NLP算法工程师的经验和算法工程师的经验没有太大差别。
    的头像 发表于 04-24 09:37 4989次阅读

    NLP不仅可以做到帮助计算机学习并理解我们的语言

    这个时候,机器学习的分支——自然语言处理(NLP)应运而生,NLP不仅仅可以做到帮助计算机学习并理解我们的语言,更会帮助计算机进行“情感分析”,理解人类的感情以及人类每天的交流方式。
    的头像 发表于 08-27 15:11 1876次阅读

    NLP 2019 Highlights 给NLP从业者的一个参考

    自然语言处理专家elvis在medium博客上发表了关于NLP在2019年的亮点总结。对于自然语言处理(NLP)领域而言,2019年是令人印象深刻的一年。在这篇博客文章中,我想重点介绍一些
    的头像 发表于 09-25 16:56 1501次阅读

    PID控制算法通俗理解.pdf

    PID控制算法通俗理解.pdf
    发表于 12-21 09:12 5次下载

    人工智能nlp是什么方向

    的方向之一。NLP 是关于将人类语言转化为计算机语言的过程,使计算机能够理解和生成人类语言。 NLP 技术有多种应用,从智能语音助手到文本分析和机器翻译。随着人们对这种技术的认识加深,NLP
    的头像 发表于 08-22 16:45 1314次阅读

    理解STM32控制中常见的PID算法

    理解STM32控制中常见的PID算法
    的头像 发表于 10-17 17:28 1711次阅读
    <b class='flag-5'>理解</b>STM32控制中常见的PID<b class='flag-5'>算法</b>