将Dropout层应用于嵌入层后是否与通过LSTM dropout参数应用dropout具有相同的效果?

9

我对在Keras中应用dropout的不同方式感到有些困惑。

我的模型如下:

model = Sequential()
model.add(Embedding(input_dim=64,output_dim=64, input_length=498))
model.add(LSTM(units=100,dropout=0.5, recurrent_dropout=0.5))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

假设我在以下方式中在嵌入层后添加了一个额外的Dropout层:
model = Sequential()
model.add(Embedding(input_dim=64,output_dim=64, input_length=498))
model.add(Dropout(0.25))
model.add(LSTM(units=100,dropout=0.5, recurrent_dropout=0.5))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

既然我已经在LSTM参数中明确指定了辍学率为0.5,那么这会有任何影响吗?还是我完全搞错了?

1个回答

24
当你添加一个dropout层时,你只是在前一层的输出上添加了dropout,在你的情况下,你正在对嵌入层添加dropout。
LSTM单元比单层神经网络更复杂,当你在LSTM单元中指定dropout时,实际上是将dropout应用于LSTM单元中的4个不同子神经网络操作。
以下是来自Colah关于LSTMs的博客中LSMT单元的可视化图表(这是最好的LSTM / RNN可视化之一,http://colah.github.io/posts/2015-08-Understanding-LSTMs/)。黄色框表示4个完全连接的网络操作(每个操作都有自己的权重),这些操作在LSTM的内部发生 - 这被整洁地包装在LSTM单元包装器中,尽管手动编码并不难。

enter image description here

当您在LSTM单元中指定dropout=0.5时,实际上是对这4个神经网络操作中的每一个应用了dropout。这相当于在LSTM单元内部,在您看到的4个黄色块之后,每次添加model.add(Dropout(0.25)) 4次。
我希望这个简短的讨论能够更清楚地解释在LSTM包装器中应用的dropout与您在嵌入层之后一次应用的dropout不同。直接回答您的问题,是的,这两个dropout定义非常不同。
请注意,进一步举例以帮助阐明这一点:如果您要定义一个简单的5层全连接神经网络,则需要在每个层之后定义dropout,而不是只定义一次。 model.add(Dropout(0.25))不是某种全局设置,它是将dropout操作添加到操作流程中。如果您有5层,则需要添加5个dropout操作。

1
感谢您提供详细且富有信息量的答案。它完整地解释了我的问题,并以最简单的形式进行了澄清。 - Danny
1
为了让事情更加复杂,@Danny 还指定了 recurrent_dropout=0.5,因此在每个 X_t 和 X_t+1 之间的激活值有50%会被丢弃。因此,在 LSTM 层中有三种不同的方法来丢弃激活值。一种是通过指定 dropoutrecurrent_dropout 在层内部丢弃它们,另一种是添加一个 Dropout 层在 LSTM 层之后丢弃它们。 - Björn Lindqvist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接