如何使用带有词嵌入的 Keras LSTM 来预测词 id

Posted

技术标签:

【中文标题】如何使用带有词嵌入的 Keras LSTM 来预测词 id【英文标题】:How to use Keras LSTM with word embeddings to predict word id's 【发布时间】:2018-03-16 20:12:45 【问题描述】:

在 Keras 中使用词嵌入时,我无法理解如何获得正确的输出。我的设置如下:

我的输入是形状(batch_size, sequence_length) 的批次。每一行 在一个batch中代表一个句子,单词都是用单词id的来表示的。这 句子用零填充,以使所有句子的长度相同。 例如,(3,6) 输入批处理可能如下所示:np.array([[135600],[174580],[138272]])

我的目标是由向右移动一步的输入批次给出的。 因此,对于每个输入单词,我想预测下一个单词:np.array([[356000],[745800],[382720]])

我将这样的输入批次输入 Keras 嵌入层。我的嵌入 大小为 100,因此输出将是形状为 (batch_size, sequence_length, embedding_size) 的 3D 张量。所以在这个小例子中它的(3,6,100)

这个 3D 批次被送入 LSTM 层

LSTM 层的输出被馈送到 Dense 层 (sequence_length) 具有 softmax 激活的输出神经元 功能。所以输出的形状会像输入的形状,即(batch_size, sequence_length)

作为损失,我使用输入和目标批次之间的分类交叉熵

我的问题:

输出批次将包含概率,因为 softmax 激活函数。但我想要的是网络来预测 整数,使得输出适合目标批次的整数。 如何“解码”输出,以便我知道网络预测的是哪个单词?还是我必须以不同的方式构建网络?

编辑 1:

我已将输出和目标批次从 2D 数组更改为 3D 张量。因此,我现在使用单热编码的 3D 目标张量 (batch_size, sequence_length, vocab_size),而不是使用大小为 (batch_size, sequence_length) 和整数 id 的目标批次。为了获得与网络输出相同的格式,我将网络更改为输出序列(通过在 LSTM 层中设置return_sequences=True)。此外,输出神经元的数量被更改为vocab_size,这样输出层现在会产生一批大小为(batch_size, sequence_length, vocab_size)。 通过这种 3D 编码,我可以使用tf.argmax(outputs, 2) 获得预测的单词 id。这种方法目前似乎有效,但我仍然对是否可以保留 2D 目标/输出感兴趣

【问题讨论】:

【参考方案1】:

一个,也许不是最好的解决方案是输出字典大小的 one-hot 向量(包括虚拟词)。

你的最后一层必须输出(sequence_length, dictionary_size+1)

如果你之前没有添加任何Flatten()Reshape(),你的密集层已经输出sequence_length,所以它应该是Dense(dictionary_size+1)

您可以使用函数 keras.utils.to_categorical() 将整数转换为 one-hot 向量,并使用 keras.backend.argmax() 将 one=hot 向量转换为整数。

不幸的是,这有点像解包你的嵌入。如果可以进行反向嵌入或类似的东西,那就太好了。

【讨论】:

是的,我已经做过类似的事情(见编辑过的问题)。我希望有一种方法可以使用 2D 目标和输出

以上是关于如何使用带有词嵌入的 Keras LSTM 来预测词 id的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 LSTM 的预训练 word2vec 进行单词生成

如何在 keras LSTM 中使用自定义嵌入?

带有嵌入层的 Keras LSTM 自动编码器

如何在 Keras 中使用附加功能和词嵌入?

用于 Keras 中句子相似性的具有 LSTM 的连体网络定期给出相同的结果

如何使用 LSTM Keras 预测未来库存