【问题标题】:Predicting the next word with Keras: how to retrieve prediction for each input word用 Keras 预测下一个词:如何检索每个输入词的预测
【发布时间】:2018-10-23 22:31:53
【问题描述】:

我在理解如何从 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 层,但输入有问题,因为 Embedding 层采用 2D 输入,而 TimeDistributed 采用 3D 输入。

感谢您的帮助!

【问题讨论】:

    标签: python neural-network nlp keras


    【解决方案1】:

    就您的问题而言,我认为双向网络并不好。 (相反的方向是试图预测一些没有出现在最后,但在开始之前的东西,我相信你会想要获取输出并将其作为输入并继续进一步预测,对吧?)

    因此,首先,从模型中删除 Bidirectional,只保留 LSTM

    Keras 循环层可能只输出最后一步,或者,如果您设置return_sequences=True,则输出所有步骤。

    所以,诀窍是像这样调整数据和模型:

    • LSTM 层中,添加return_sequences=True。 (您的输出将是整个句子)
    • 让 Y 的整个句子比 X 领先一步:X,y = sequences[:,:-1], sequences[:,1:]

    请注意,这将使您的输出变为 3D。如果您只对最后一个单词感兴趣,可以手动从输出中获取:lastWord = outputs[:,-1]


    关于滑动窗口:不要使用它们。它们完全违背了 LSTM 学习长序列的目的。 (好吧,这个说法可能有点夸张,如果你的序列太长,你可能会想要使用滑动窗口来加快训练速度,但是对于句子,你可能需要拥有句子的所有单词,否则上下文会丢失)

    关于 TimeDistributed 层:仅在您想要添加额外的时间维度时使用它们。由于 LSTM 已经使用时间维度,因此没有 TimeDistributed 也可以。例如,如果您想处理整个文本,并且您决定逐句进行,并且在每个句子中逐字逐句,您可以尝试具有两个时间维度的东西。

    关于无限期地预测未来:为此,您必须使用 stateful=True LSTM 层,并创建手动循环以获取最后一个输出步骤并将其作为输入以获取再上一步。

    【讨论】:

    • 感谢您的精彩回答。如果我有序列(大约 200 万个),每个序列都有不同的时间步长,比如有些只有 5 个,有些是 50/60/100/200 到 500。为了预测序列中的下一个项目,是否可以将序列修剪为 60 max lengthpost/pre padding 并只取最后一项seq_1[:-1] as target (目标将是每个不同的时间步长,例如对于少数人来说是第6、7、8 个,对于其他人来说是第58、59、60 个时间步长)。学习最后一个项目是否足以学习下一个项目?还是我应该制作每个序列 n-gram/滑动窗口?谢谢。
    • @A.B,我认为在这种情况下你应该使用滑动窗口。警告:滑动窗口与stateful 不兼容,无法持续预测下一个元素。
    • 谢谢你的回复@Daniel,我想我不知道有状态的工作原理和决定它,你能参考lstm的部门指南吗?这超出了基础
    • 感谢您分享链接,精彩的回答。我很困惑你在这个答案中说They totally defeat the purpose of LSTMs which is learning long sequences.,所以我不明白的是,我的情况不同吗?
    猜你喜欢
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2016-04-05
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多