如何使用带有词嵌入的 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的主要内容,如果未能解决你的问题,请参考以下文章