关于正确使用RNN中的丢失(Keras)

时间:2018-05-22 01:08:18

标签: machine-learning keras deep-learning recurrent-neural-network dropout

我对如何在keras中正确使用dropout与RNN,特别是GRU单元感到困惑。 keras文档引用了本文(https://arxiv.org/abs/1512.05287),我理解同一个丢失掩码应该用于所有时间步骤。这是通过dropout参数实现的,同时指定GRU层本身。我不明白的是:

  1. 为什么互联网上有几个例子,包括keras自己的例子(https://github.com/keras-team/keras/blob/master/examples/imdb_bidirectional_lstm.py)和"触发词检测"在Andrew Ng的Coursera Seq中任职。模型过程中,他们明确地添加了一个dropout层" model.add(Dropout(0.5))"根据我的理解,这将为每个时间步添加一个不同的掩码。

  2. 上面提到的论文表明,这样做是不合适的,并且由于在所有时间步骤中积累了这种丢失噪声,我们可能会丢失信号以及长期记忆。 但是,这些模型(在每个时间步使用不同的辍学面具)如何能够学习并表现良好。

  3. 我自己已经训练了一个模型,该模型在每个时间步使用不同的辍学面具,虽然我没有得到我想要的结果,但模型能够过度拟合训练数据。根据我的理解,这会使噪音的积累无效"并且"信号丢失"在所有时间步骤(我有1000个时间步骤系列输入到GRU图层)。

    任何有关情况的见解,解释或经验都会有所帮助。感谢。

    更新:

    为了更清楚,我提到了Dropout Layer的keras文档中的摘录(" noise_shape:1D整数张量,表示将与输入相乘的二进制丢失掩码的形状。例如,如果您的输入具有形状(batch_size,timesteps,features),并且您希望所有时间步长的dropout掩码相同,则可以使用noise_shape =(batch_size,1,features")。 所以,我相信,可以看出,当明确使用Dropout层并且在每个时间步骤需要相同的掩码时(如本文所述),我们需要编辑这个noise_shape参数,这在我之前链接的示例中没有完成

1 个答案:

答案 0 :(得分:1)

正如Asterisk在他的评论中解释的那样,循环单元内的退出与单元输出后的退出之间存在根本差异。这是您在问题中链接的keras tutorial的体系结构:

model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(Bidirectional(LSTM(64)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

您要在LSTM完成计算后添加一个退出层,这意味着该单元中将不再有任何循环遍历。想象一下,该退出层是在教导网络不要依赖于特定时间步长的特定特征的输出,而是要概括不同特征和时间步长的信息。这里的辍学与前馈体系结构没有什么不同。

Gal & Ghahramani在他们的论文中提出的建议(您在问题中进行了链接)是单元内。在那里,您要在序列的时间步之间放置输入信息。我发现this blogpost对理解本文及其与keras实现的关系很有帮助。