当前位置:   article > 正文

WordPiece 和 BPE 的区别

wordpiece

总结

传统词表示方法没有办法很好地处理未知或罕见的词汇。
WordPiece 和 BPE 是两种子词切分算法,两者非常相似。
WordPiece用于BERT,DistilBERT。
BPE使用RoBERTa。

BPE和WordPiece的区别在于如何选择两个子词进行合并

BPE的词表创建过程:

  1. 首先初始化词表,词表中包含了训练数据中出现的所有字符。
  2. 然后两两拼接字符,统计字符对在训练数据中出现的频率。
  3. 选择出现频率最高的一组字符对加入词表中。

反复2和3,直到词表大小达到指定大小。

WordPiece是贪心的最长匹配搜索算法。基本流程:
首先初始化词表,词表包含了训练数据中出现的所有字符。
2. 然后两两拼接字符,统计字符对加入词表后对语言模型的似然值的提升程度。
3. 选择提升语言模型似然值最大的一组字符对加入词表中。

反复2和3,直到词表大小达到指定大小。

概率: 一件事发生的可能性
似然性:与概率相反,一件事已经发生,反推在什么情况下,这件事发生的概率最大
似然函数可以表示为:
在这里插入图片描述
互信息:可以看做一个随机变量中包含的关于另一个随机变量的信息量,或者说,一个随机变量由于已知另一个随机变量而减少的不确定性。
在这里插入图片描述

在这里插入图片描述

官网阐述BPE和WordPiece的区别于联系:

链接
在这里插入图片描述

WordPiece实现源码

    def tokenize(self, text):
        """Tokenizes a piece of text into its word pieces.

        This uses a greedy longest-match-first algorithm to perform tokenization
        using the given vocabulary.

        For example:
          input = "unaffable"
          output = ["un", "##aff", "##able"]

        Args:
          text: A single token or whitespace separated tokens. This should have
            already been passed through `BasicTokenizer`.

        Returns:
          A list of wordpiece tokens.
        """
        def whitespace_tokenize(text):
		    """Runs basic whitespace cleaning and splitting on a peice of text."""
		    text = text.strip()
		    if not text:
		        return []
		    tokens = text.split()
		    return tokens

        output_tokens = []
        for token in whitespace_tokenize(text):
            chars = list(token)
            if len(chars) > self.max_input_chars_per_word:  #max_input_chars_per_word 默认为 100
                output_tokens.append(self.unk_token) # 单词长度大于最大长度,用[UNK]表示单词
                continue

            is_bad = False
            start = 0
            sub_tokens = []
            while start < len(chars):
                end = len(chars)
                cur_substr = None
                while start < end: # 贪心的最长匹配搜索 end从最后一位往前遍历,每移动一位,判断start:end是否存在于词表中
                    substr = "".join(chars[start:end])
                    if start > 0: # 若子词不是从位置0开始,前面要加“##”
                        substr = "##" + substr
                    if substr in self.vocab:
                        cur_substr = substr
                        break
                    end -= 1
                if cur_substr is None: #没有在词表中出现的子词,break
                    is_bad = True
                    break
                sub_tokens.append(cur_substr)
                start = end # 从上一子词的后一位开始下一轮遍历

            if is_bad: #没有在词表中出现的子词(单词中的任何区域),用[unk]表示该词:比如“wordfi”,首先确定“word”为子词,后发现“fi”不存在在词表中,则最终用[UNK]表示“wordfi”
                output_tokens.append(self.unk_token)
            else:
                output_tokens.extend(sub_tokens)
        return output_tokens
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/828550
推荐阅读
相关标签
  

闽ICP备14008679号

        
cppcmd=keepalive&