如何将 MC dropout 应用于 LSTM 网络 keras

数据挖掘 深度学习 lstm rnn 辍学
2021-10-06 14:26:18

我有一个使用 keras 开发的简单 LSTM 网络:

model = Sequential()
model.add(LSTM(rnn_size,input_shape=(2,w),dropout = 0.25 , recurrent_dropout=0.25))
model.add(Dense(2))

我想应用 MC dropout 方法。如何在测试阶段启用 dropout 以计算不确定性?

谢谢。

2个回答

Monte-Carlo Dropout 是在推理时使用 dropout 来为网络添加随机性,该网络可用于生成一组预测变量/预测,您可以对其执行统计分析。这通常用于引导置信区间。

因此,在顺序模型中执行 dropout 的位置很重要。如果您将辍学添加到:

  • 输入层 - 您正在模拟模型如何响应输入数据的不确定性
  • LSTM 层本身(经常) - 您正在模拟 LSTM 本身权重的变化如何影响您的预测
  • 最后的密集层 - 您正在模拟修改 LSTM 预测到原始问题空间的投影

所以Marat 的回答是正确的,但它只告诉您如何添加一个额外的 dropout 层,如果您希望在 LSTM 中递归地应用 dropout,这将不起作用。

正如您所确定的,您不能只将 LSTM 层配置为使用 dropout,因为它不会应用于推理,因此我们可以子类化内置 LSTM 层并强制它始终在训练模式下运行:

class MonteCarloLSTM(tf.keras.layers.LSTM):
   def call(self, inputs):
      return super().call(inputs, training=True)

然后,我们在定义 Sequential 模型时使用新MonteCarloLSTM层代替:LSTM

model.add(MonteCarloLSTM(..., recurrent_dropout=0.2))

请注意,这不仅会在推理时为您提供 Monte-Carlo dropout,而且还会在训练时使用 dropout 正则化。如果你想避免后者,那么你需要:

  1. LSTM使用 vanilla层训练模型
  2. 保存序列模型中所有层的权重
  3. 用完全相同的结构重建一个新的 Sequential 模型,除了用LSTM您的自定义MonteCarloLSTM层替换该层
  4. 将训练好的权重加载到模型中
  5. 运行推理

好吧,为了在测试阶段启用 dropout,您可以执行以下操作:

keras.layers.Dropout(0.5)(x, training=True)

然后你可能想要多次运行它。如果您不关心推理时间,只需多次向前传递,最后计算输出的均值和方差。