我正在遵循keras团队的这段github
代码,以了解如何使用预训练的单词嵌入。我能够理解其中的大部分内容,但对向量大小有疑问。我希望有人能帮助我。
首先我们定义Tokenizer(num_words=MAX_NUM_WORDS)
根据Tokenizer()
的keras文档编码,仅考虑MAX_NUM_WORDS - 1
来考虑MAX_NUM_WORDS=20000
,所以如果19999
我会在{{ 1}}个单词。
num_words :基于单词的最大保留单词数 频率。仅保留最常见的num_words-1个单词。
接下来,在代码中,我们基于手套矢量准备一个Embedding Matrix
。这样做时,我们考虑的是大小为(20001,100)np.zeros((MAX_NUM_WORDS+1, 100))
的矩阵。如果我们的词汇表中只有20001
个单词,我不明白为什么我们考虑19999
的矩阵。
然后我们将num_words
传递给嵌入层。根据input_dim参数的嵌入层文档,它说,
input_dim :整数>0。词汇量,即最大整数索引 + 1。
embedding_layer = Embedding(input_dim=num_words,
output_dim=EMBEDDING_DIM,
embeddings_initializer=Constant(embedding_matrix),
input_length=MAX_SEQUENCE_LENGTH,
trainable=False)
根据19999
函数,我们的词汇量是Tokenizer()
吗?那么为什么我们将20001
传递为input_dim
这是从该github链接获取的代码的一小段。
MAX_NUM_WORDS = 20000
MAX_SEQUENCE_LENGTH = 1000
EMBEDDING_DIR = 100
tokenizer = Tokenizer(num_words=MAX_NUM_WORDS)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)
# prepare embedding matrix
num_words = MAX_NUM_WORDS + 1
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word_index.items():
if i > MAX_NUM_WORDS:
continue
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
embedding_matrix[i] = embedding_vector
embedding_layer = Embedding(num_words,
EMBEDDING_DIM,
embeddings_initializer=Constant(embedding_matrix),
input_length=MAX_SEQUENCE_LENGTH,
trainable=False)
答案 0 :(得分:1)
对于嵌入,输入dim(以下代码中的num_words个)是词汇量。例如,如果您的数据是整数编码为0-10之间的值,则词汇表的大小将为11个单词。这就是将1加到len(word_index)和MAX_NUM_WORDS的最小值中的原因。
嵌入矩阵将具有词汇量和向量长度的维数
embedding_layer = Embedding(num_words,
EMBEDDING_DIM,
embeddings_initializer=Constant(embedding_matrix),
input_length=MAX_SEQUENCE_LENGTH,
trainable=False)
num_words = min(MAX_NUM_WORDS, len(word_index)) + 1
已经创建了一个简单的令牌生成器来解释这一点。
t = Tokenizer(num_words=5)
fit_text = ["The earth is an awesome place live"]
t.fit_on_texts(fit_text)
word_index = t.word_index
print('word_index : ',word_index)
print('len word_index : ',len(t.word_index))
word_index : {'the': 1, 'earth': 2, 'is': 3, 'an': 4, 'awesome': 5, 'place': 6, 'live': 7}
len word_index : 7
在以下情况下,您仅覆盖了大小为4的词汇表,因为令牌生成器索引从1开始。
embedding_matrix = np.zeros((5, 10))
embedding_matrix
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
for word, i in word_index.items():
if i < 5:
embedding_matrix[i] = [0,1,0,0,0,0,0,0,0,0]
print (embedding_matrix)
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]
在以下情况下,您需要添加1(5 + 1)来覆盖大小5的词汇表以覆盖索引0
embedding_matrix = np.zeros((6, 10))
for word, i in word_index.items():
if i < 6:
embedding_matrix[i] = [0,1,0,0,0,0,0,0,0,0]
print (embedding_matrix)
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]
答案 1 :(得分:1)
我认为您的怀疑是正确的。在代码的this commit中进行了更改,以使单词与index = MAX_NUM_WORDS
保持一致。在此之前,Tokenizer
上有一个commit,以使其保留num_words
个单词而不是num_words - 1
个单词。但是此后Tokenizer
的更改是reverted。因此,我猜想示例更新的作者可能已经假设Tokenizer
在提交更新时保留了num_words
个字。