在 Keras 和 LSTM/GRU 单元格中使用 Dropout
Using Dropout with Keras and LSTM/GRU cell
在 Keras 中,您可以像这样指定一个 dropout 层:
model.add(Dropout(0.5))
但是对于 GRU 单元,您可以将 dropout 指定为构造函数中的参数:
model.add(GRU(units=512,
return_sequences=True,
dropout=0.5,
input_shape=(None, features_size,)))
有什么区别?一个比另一个更可取吗?
在 Keras' documentation 中,它将其添加为单独的丢弃层(参见 "Sequence classification with LSTM")
循环层一遍又一遍地执行相同的重复操作。
在每个时间步中,它需要两个输入:
- 您的输入(序列的一个步骤)
- 内部输入(例如,可以是状态和上一步的输出)
请注意,输入和输出的维度可能不匹配,这意味着 "your input" 个维度将不匹配 "the recurrent input (previous step/states)" 个维度。
然后在每个循环时间步中有两个具有两个不同内核的操作:
- 将一个内核应用于"your inputs"以在兼容维度中对其进行处理和转换
- 另一个(keras 称为递归内核)应用于上一步的输入。
正因为如此,keras在循环层中也使用了两个dropout操作。 (将应用于每一步的 Dropout)
- 首次转换输入时出现丢失
- 循环内核应用的dropout
所以,实际上RNN层中有两个dropout参数:
dropout
,应用于输入的第一个操作
recurrent_dropout
,应用于循环输入的其他操作(先前的输出 and/or 状态)
您可以在 GRUCell
和 LSTMCell
中看到此描述编码,例如在 source code.
中
什么是正确的?
这是对创造力的开放。
你可以使用Dropout(...)
层,它不是"wrong",但它也可能会掉落"timesteps"! (除非您正确设置 noise_shape
或使用 SpatialDropout1D
,目前尚未记录)
也许你想要,也许你不想要。如果您在循环层中使用参数,您将只对其他维度应用 dropout,而不会丢弃任何一步。这对于循环层来说似乎是健康的,除非你想让你的网络学习如何处理包含间隙的序列(最后一句话是一个假设)。
此外,使用 dropout 参数,当操作被丢弃时,您将真正丢弃内核的一部分 "in every step",而使用单独的层将使您的 RNN 在内部执行非丢弃操作,因为您dropout 只会影响最终的输出。
在 Keras 中,您可以像这样指定一个 dropout 层:
model.add(Dropout(0.5))
但是对于 GRU 单元,您可以将 dropout 指定为构造函数中的参数:
model.add(GRU(units=512,
return_sequences=True,
dropout=0.5,
input_shape=(None, features_size,)))
有什么区别?一个比另一个更可取吗?
在 Keras' documentation 中,它将其添加为单独的丢弃层(参见 "Sequence classification with LSTM")
循环层一遍又一遍地执行相同的重复操作。
在每个时间步中,它需要两个输入:
- 您的输入(序列的一个步骤)
- 内部输入(例如,可以是状态和上一步的输出)
请注意,输入和输出的维度可能不匹配,这意味着 "your input" 个维度将不匹配 "the recurrent input (previous step/states)" 个维度。
然后在每个循环时间步中有两个具有两个不同内核的操作:
- 将一个内核应用于"your inputs"以在兼容维度中对其进行处理和转换
- 另一个(keras 称为递归内核)应用于上一步的输入。
正因为如此,keras在循环层中也使用了两个dropout操作。 (将应用于每一步的 Dropout)
- 首次转换输入时出现丢失
- 循环内核应用的dropout
所以,实际上RNN层中有两个dropout参数:
dropout
,应用于输入的第一个操作recurrent_dropout
,应用于循环输入的其他操作(先前的输出 and/or 状态)
您可以在 GRUCell
和 LSTMCell
中看到此描述编码,例如在 source code.
什么是正确的?
这是对创造力的开放。
你可以使用Dropout(...)
层,它不是"wrong",但它也可能会掉落"timesteps"! (除非您正确设置 noise_shape
或使用 SpatialDropout1D
,目前尚未记录)
也许你想要,也许你不想要。如果您在循环层中使用参数,您将只对其他维度应用 dropout,而不会丢弃任何一步。这对于循环层来说似乎是健康的,除非你想让你的网络学习如何处理包含间隙的序列(最后一句话是一个假设)。
此外,使用 dropout 参数,当操作被丢弃时,您将真正丢弃内核的一部分 "in every step",而使用单独的层将使您的 RNN 在内部执行非丢弃操作,因为您dropout 只会影响最终的输出。