我对在Keras中将Dropout应用到Sequential模型的不同方法感到有些困惑。
我的模型如下:
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,或者我是否认为这一切都错了?
答案 0 :(得分:13)
当你添加一个dropout图层时,你只需要将dropout添加到前一层的输出中,在你的情况下你要将dropout添加到你的嵌入层。
LSTM单元比单层神经网络更复杂,当您在LSTM单元中指定丢失时,实际上将丢失应用于LSTM单元中的4个不同的子神经网络操作。
下面是Colah博客关于LSTMs的LSMT细胞的可视化(LSTM / RNNs的最佳可视化,http://colah.github.io/posts/2015-08-Understanding-LSTMs/)。黄色框表示4个完全连接的网络操作(每个都有自己的权重),这些操作发生在LSTM的引擎盖下 - 这整齐地包裹在LSTM单元包装器中,尽管手动编码并不是很难。
当您在LSTM单元格中指定dropout=0.5
时,您正在做的工作是将dropout应用于这4个神经网络操作中的每一个。这有效地在图中看到的4个黄色块中的每一个之后,在LSTM单元的内部中添加model.add(Dropout(0.25))
4次。
我希望简短的讨论能够更清楚地了解LSTM包装器中应用的丢失(LSTM中有效应用于4个子网络)与嵌入层之后在序列中应用一次的丢失有何不同。直接回答你的问题,是的,这两个辍学定义非常不同。
请注意,作为帮助阐明这一点的另一个例子:如果要定义一个简单的5层完全连接的神经网络,则需要在每个层之后定义丢失,而不是一次。 model.add(Dropout(0.25))
不某种全局设置,它将dropout操作添加到操作管道中。如果您有5层,则需要添加5个退出操作。