我在理解如何从Keras模型中检索预测时遇到一些问题。
我想构建一个预测下一个单词的简单系统,但我不知道如何输出每个单词的完整概率列表。
这是我现在的代码:
model = Sequential()
model.add(Embedding(vocab_size, embedding_size, input_length=55, weights=[pretrained_weights]))
model.add(Bidirectional(LSTM(units=embedding_size)))
model.add(Dense(23690, activation='softmax')) # 23690 is the total number of classes
model.compile(loss='categorical_crossentropy',
optimizer = RMSprop(lr=0.0005),
metrics=['accuracy'])
# fit network
model.fit(np.array(X_train), np.array(y_train), epochs=10)
score = model.evaluate(x=np.array(X_test), y=np.array(y_test), batch_size=32)
prediction = model.predict(np.array(X_test), batch_size=32)
第一个问题: 训练集:句子列表(矢量化并转换为索引)。 我在网上看到一些例子,人们将X_train和y_train划分为:
X, y = sequences[:,:-1], sequences[:,-1]
y = to_categorical(y, num_classes=vocab_size)
我应该改为转换X_train和y_train以便有滑动序列,例如我有
X = [[10, 9, 4, 5]]
X_train = [[10, 9], [9, 4], [4, 5]]
y_train = [[9], [4], [5]]
第二个问题: 现在,模型只为每个输入返回一个元素。如何返回每个单词的预测?我希望每个单词都能有一个输出字数组,而不是单个输出。 我读到我可以使用TimeDistributed层,但是输入有问题,因为嵌入层采用2D输入,而TimeDistributed采用3D输入。
感谢您的帮助!
答案 0 :(得分:0)
对于你所问的问题,我认为双向网络并不好。 (相反的方向是试图预测最终没有出现的东西,但是在开始之前,我相信你会想要获取输出并使其成为输入并继续进一步预测,对吗?)< / p>
首先,从模型中移除Bidirectional
,仅保留LSTM
。
Keras重复图层可能只输出最后一步,或者,如果设置return_sequences=True
,则输出所有步骤。
所以,诀窍是调整数据和模型如下:
LSTM
图层中,添加return_sequences=True
。 (你的输出将是整个句子)X,y = sequences[:,:-1], sequences[:,1:]
请注意,这将使您的输出3D。如果您只对最后一个单词感兴趣,可以从输出中手动获取它:lastWord = outputs[:,-1]
关于推拉窗:不要使用它们。它们完全打败了学习长序列的LSTM的目的。
关于TimeDistributed图层:仅在您希望添加额外时间维时使用它们。由于LSTM已经使用了时间维度,因此没有TimeDistributed就可以了。如果您想要,例如处理整个文本,并且您决定逐句逐句地逐句逐句地在每个句子中,您可以尝试使用两个时间维度的东西。
关于无限期地预测未来:为此,您必须使用stateful=True
LSTM图层,并创建手动循环以获取最后一个输出步骤并将其作为输入提供再采取一步。