如何使用 Keras 在堆叠式 LSTM 中设置密集瓶颈?
How can I setup a Dense bottleneck in a stacked LSTM with Keras?
我有:
self.model.add(Bidirectional(LSTM(lstm1_size, input_shape=(
seq_length, feature_dim), return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
self.model.add(Bidirectional(
LSTM(lstm2_size, return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
# BOTTLENECK HERE
self.model.add(Bidirectional(
LSTM(lstm3_size, return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
self.model.add(Bidirectional(
LSTM(lstm4_size, return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
self.model.add(Dense(feature_dim, activation='linear'))
但是,我想设置一个类似于 autoencoder
的设置,而不必有 2 个单独的模型。在我有评论 BOTTLENECK HERE
的地方,我想要一个某个维度的向量,比如 bottleneck_dim
。
之后,应该是一些 LSTM 层,然后重建一个与初始输入具有相同维度的序列。但是,我相信添加 Dense
层不会 return 一个向量,而是每个序列长度的 return 个向量?
Dense
已更新为自动充当 TimeDistributed
包装 - 即您将获得 (batch_size, seq_length, lstm2_size)
.
- 解决方法是在它之前放置一个
Flatten()
,这样 Dense
的输出形状将是 (batch_size, seq_length * lstm2_size)
。但是,我不推荐它,因为它可能会破坏时间信息(您正在混合通道和时间步长)。此外,它将网络限制为 seq_length
,因此您不能再对任何其他 seq_length
. 进行训练或推理
一个首选的替代方案是 Bidirectional(LSTM(..., return_sequences=False))
,它 returns 只有最后一个时间步长的输出,形状为 (batch_size, lstm_bottleneck_size)
。要将其输出提供给下一个 LSTM,您需要 RepeatVector(seq_length)
在 =False
层之后。
尽管如此,请注意 "bottleneck" 的范围;例如如果 (seq_length, feature_dim) = (200, 64)
和 lstm_bottleneck_size = 400
,那就是 (1 * 400) / (200 * 64)
= x32 减少,这是相当大的,并且可能使网络不堪重负。我建议以 x8 为目标。
我有:
self.model.add(Bidirectional(LSTM(lstm1_size, input_shape=(
seq_length, feature_dim), return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
self.model.add(Bidirectional(
LSTM(lstm2_size, return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
# BOTTLENECK HERE
self.model.add(Bidirectional(
LSTM(lstm3_size, return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
self.model.add(Bidirectional(
LSTM(lstm4_size, return_sequences=True)))
self.model.add(BatchNormalization())
self.model.add(Dropout(0.2))
self.model.add(Dense(feature_dim, activation='linear'))
但是,我想设置一个类似于 autoencoder
的设置,而不必有 2 个单独的模型。在我有评论 BOTTLENECK HERE
的地方,我想要一个某个维度的向量,比如 bottleneck_dim
。
之后,应该是一些 LSTM 层,然后重建一个与初始输入具有相同维度的序列。但是,我相信添加 Dense
层不会 return 一个向量,而是每个序列长度的 return 个向量?
Dense
已更新为自动充当TimeDistributed
包装 - 即您将获得(batch_size, seq_length, lstm2_size)
.- 解决方法是在它之前放置一个
Flatten()
,这样Dense
的输出形状将是(batch_size, seq_length * lstm2_size)
。但是,我不推荐它,因为它可能会破坏时间信息(您正在混合通道和时间步长)。此外,它将网络限制为seq_length
,因此您不能再对任何其他seq_length
. 进行训练或推理
一个首选的替代方案是 Bidirectional(LSTM(..., return_sequences=False))
,它 returns 只有最后一个时间步长的输出,形状为 (batch_size, lstm_bottleneck_size)
。要将其输出提供给下一个 LSTM,您需要 RepeatVector(seq_length)
在 =False
层之后。
尽管如此,请注意 "bottleneck" 的范围;例如如果 (seq_length, feature_dim) = (200, 64)
和 lstm_bottleneck_size = 400
,那就是 (1 * 400) / (200 * 64)
= x32 减少,这是相当大的,并且可能使网络不堪重负。我建议以 x8 为目标。