如何使用带有词嵌入的 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 进行单词生成