使用Dropout与Keras和LSTM/GRU单元

Big*_*dMe 10 lstm keras dropout

在Keras中,您可以像这样指定一个dropout图层:

model.add(Dropout(0.5))
Run Code Online (Sandbox Code Playgroud)

但是使用GRU单元格,您可以将dropout指定为构造函数中的参数:

model.add(GRU(units=512,
        return_sequences=True,
        dropout=0.5,
        input_shape=(None, features_size,)))
Run Code Online (Sandbox Code Playgroud)

有什么不同?一个比另一个好吗?

Keras的文档中, 它将其添加为单独的丢失层(请参阅"使用LSTM进行序列分类")

Dan*_*ler 13

重复层一遍又一遍地执行相同的重复操作.

在每个时间步中,它需要两个输入:

  • 您的输入(序列的一步)
  • 内部输入(例如,可以是状态和上一步的输出)

请注意,输入和输出的尺寸可能不匹配,这意味着"您的输入"尺寸将与"循环输入(上一步/状态)"尺寸不匹配.

然后在每个重复的时间步骤中,有两个操作具有两个不同的内核:

  • 一个内核应用于"您的输入"以在兼容维度中处理和转换它
  • 另一个(由keras称为recurrent kernel)应用于上一步的输入.

因此,keras还在循环层中使用两个丢失操作.(将应用于每个步骤的辍学)

  • 第一次转换输入的丢失
  • 应用复制内核的丢失

因此,实际上RNN层中有两个丢失参数:

  • dropout,适用于输入的第一次操作
  • recurrent_dropout,应用于循环输入的其他操作(先前的输出和/或状态)

你可以看到这说明无论是在编码GRUCellLSTMCell在例如源代码.


什么是正确的?

这对创造力是开放的.

你可以使用一个Dropout(...)图层,它不是"错误的",但它也可能会掉落"时间步长"!(除非您noise_shape正确设置或使用SpatialDropout1D,目前尚未记录)

也许你想要它,也许你不想.如果使用循环图层中的参数,则只会将丢失应用于其他维度,而不会丢弃任何一个步骤.这对于复发层来说似乎是健康的,除非您希望您的网络学习如何处理包含间隙的序列(这最后一句话是一个支持).

此外,使用dropout参数,您将真正删除部分内核,因为操作将"在每个步骤中"删除,而使用单独的层将让您的RNN在内部执行非删除操作,因为您的丢失将仅影响最终输出.