从我看到的许多示例中,当我们使用来自keras的text_tokenizer
时,在指定输入层的输入大小时,我们使用vocab大小+1。这自然会产生具有+1个“行”的嵌入空间。
例如,我适合一个简单的模型来估计大小为3 = I like turtles
的唱词的嵌入向量。在我们的词汇表中,嵌入空间的长度为每个单词5。
嵌入权重为:
0.01209533 0.034303080 -0.04666784 0.02803965 -0.03691160
-0.01302978 -0.030584216 -0.02506201 0.04771456 0.01906699
0.02800793 0.042204402 0.05223191 -0.01184921 0.02000498
0.02692273 -0.008792922 0.01560913 -0.02783649 0.02692282
我的问题:我假设矩阵中的第一个“行”是基于0的向量,因此第2、3和4行将分别与“ I”,“ like”和“ turtles”相关联。
是这种情况吗?我想确保我的词汇正确对齐,但是我无法确定任何文档来确认这一假设。
答案 0 :(得分:2)
我了解您要提取每个单词的嵌入,但是我认为真正的问题是:分词器产生的输出是什么。
此外,该令牌生成器有点混乱。您将在下面看到我的意思。
因为令牌生成器将过滤单词(假设使用不重要的词汇),所以我不想假设单词以它们被发现的顺序存储。因此,这里我使用word_index
以编程方式确定词汇表。然后,我会在过滤最常用的单词后,明确检查哪些单词被标记化了。 (Word_index会记住所有个单词;即预先过滤的值。)
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
corpus = 'I like turtles'
num_words = len(corpus.split())
oov = 'OOV'
tokenizer = Tokenizer(num_words=num_words + 2, oov_token=oov)
tokenizer.fit_on_texts(corpus.split())
print(f'word_index: {tokenizer.word_index}')
print(f'vocabulary: {tokenizer.word_index.keys()}')
text = [key for key in tokenizer.word_index.keys()]
print(f'keys: {text}: {tokenizer.texts_to_sequences(text)}')
text = 'I like turtles'.split()
print(f'{text}: {tokenizer.texts_to_sequences(text)}')
text = 'I like marshmallows'.split()
print(f'{text}: {tokenizer.texts_to_sequences(text)}')
这将产生以下输出:
word_index: {'OOV': 1, 'i': 2, 'like': 3, 'turtles': 4}
vocabulary: dict_keys(['OOV', 'i', 'like', 'turtles'])
keys: ['OOV', 'i', 'like', 'turtles']: [[1], [2], [3], [4]]
['I', 'like', 'turtles']: [[2], [3], [4]]
['I', 'like', 'marshmallows']: [[2], [3], [1]]
但是,如果指定oov_token,则输出如下所示:
{'OOV': 1, 'i': 2, 'like': 3, 'turtles': 4}
请注意,我必须如何指定num_words=num_words + 2
而不是预期的“ +1”。
那是因为我们在显式定义一个OOV令牌,该令牌已添加到词汇表中,这有点讨厌imo。
如果您指定了OOV令牌并设置了num_words=num_words + 1
(如文档所述),则“我喜欢乌龟”的编码与“我喜欢棉花糖”的编码相同。也是坚果。
希望,您现在必须拥有一些工具来了解令牌生成器将为编码层提供什么功能。然后希望,将令牌与它们的嵌入关联起来将很简单。
请让我们知道您的发现。 :)
(有关疯狂的更多信息,请查看this StackOverflow帖子。)