`tfds.features.text.SubwordTextEncoder` 是如何创建字编码的?

How does the `tfds.features.text.SubwordTextEncoder` create word encoding?

我目前正在做一个 tensorflow 转换器 tutorial for sequence to sequence translation. At the beginning of the tutorial the class tfds.features.text.SubwordTextEncoder 被调用。 class 可用于将字符串转换为整数列表,每个整数代表一个单词。

使用 class SubwordTextEncoder 训练英语分词器后如下:

tokenizer_en = tfds.features.text.SubwordTextEncoder.build_from_corpus(
(en.numpy() for pt, en in train_examples), target_vocab_size=2**13)

本教程展示了现在如何使用此分词器将字符串转换为整数列表。此代码片段

sample_string = 'Transformer is awesome.'

tokenized_string = tokenizer_en.encode(sample_string)
print ('Tokenized string is {}'.format(tokenized_string))

给出以下结果:

[7915, 1248, 7946, 7194, 13, 2799]

其中整数到单词的映射可以如下所示:

for ts in tokenized_string:
  print ('{} ----> {}'.format(ts, tokenizer_en.decode([ts])))

returns

7915 ----> T
1248 ----> ran
7946 ----> s
7194 ----> former 
13 ----> is 
2799 ----> awesome

这一切对我来说都很有意义。标记器从其训练集中识别单词 'is' 和 'awesome' 并分配相应的整数。不在其训练集中的单词 'Transformer' 正在按照文档中的说明拆分成多个部分。

然而,在对分词器进行了一些试验之后,我感到很困惑。请考虑以下代码片段

sample_string2 = 'the best there is'
tokenized_string2 = tokenizer_en.encode(sample_string2)
print(tokenized_string2)

哪个return

[3, 332, 64, 156]

for ts in tokenized_string2:
  print ('{} ----> {}'.format(ts, tokenizer_en.decode([ts])))

哪个return

3 ----> the 
332 ----> best 
64 ----> there 
156 ----> is

问题:为什么分词器 return 同一个词在句子的不同部分有不同的整数?在第二个示例中,单词 'is' 映射到 156,而在第一个示例中,它使用相同的分词器映射到整数 13。

我在 print 语句中添加了一个语句 len(tokenizer_en.decode([ts]) 以查看长度,我尝试了下面的示例 -

示例:

sample_string2 = 'is is is is is is'
tokenized_string2 = tokenizer_en.encode(sample_string2)
print(tokenized_string2)

for ts in tokenized_string2:
  print ('{} ----> {} ----> {}'.format(ts, tokenizer_en.decode([ts]),len(tokenizer_en.decode([ts]))))

输出-

13 ----> is  ----> 3
13 ----> is  ----> 3
13 ----> is  ----> 3
13 ----> is  ----> 3
13 ----> is  ----> 3
156 ----> is ----> 2

根据参数的 documentation,它声明 -

vocab_list - list<str>, list of subwords for the vocabulary. Note that an underscore at the end of a subword indicates the end of the word (i.e. a space will be inserted afterwards when decoding). Underscores in the interior of subwords are disallowed and should use the underscore escape sequence.