【发布时间】:2021-12-20 04:42:42
【问题描述】:
我正在为我的硕士论文创建一个用于特征提取的 LSTM 自动编码器。但是,我在将 dropout 与 LSTM 层相结合时遇到了很多麻烦。
由于它是一个自动编码器,我遇到了一个瓶颈,这是通过两个独立的 LSTM 层实现的,每个层的 num_layers=1,中间有一个 dropout。我有长度非常不同的时间序列,因此我发现打包序列是一个好主意。
但是,根据我的实验,我必须在第一个 LSTM 之前打包数据,在 dropout 之前解包,然后在第二个 LSTM 之前再次打包。这似乎非常低效。有没有更好的办法?我在下面提供了一些示例代码和另一种实现方式。
当前可行但可能不是最佳的解决方案:
class Encoder(nn.Module):
def __init__(self, seq_len, n_features, embedding_dim, hidden_dim, dropout):
super(Encoder, self).__init__()
self.seq_len = seq_len
self.n_features = n_features
self.embedding_dim = embedding_dim
self.hidden_dim = hidden_dim
self.lstm1 = nn.LSTM(
input_size=n_features,
hidden_size=self.hidden_dim,
num_layers=1,
batch_first=True,
)
self.lstm2 = nn.LSTM(
input_size=self.hidden_dim,
hidden_size=embedding_dim,
num_layers=1,
batch_first=True,
)
self.drop1 = nn.Dropout(p=dropout, inplace=False)
def forward(self, x):
x, (_, _) = self.lstm1(x)
x, lens = pad_packed_sequence(x, batch_first=True, total_length=self.seq_len)
x = self.drop1(x)
x = pack_padded_sequence(x, lens, batch_first=True, enforce_sorted=False)
x, (hidden_n, _) = self.lstm2(x)
return hidden_n.reshape((-1, self.n_features, self.embedding_dim)), lens
替代方案,可能更好,但目前无法解决;
class Encoder2(nn.Module):
def __init__(self, seq_len, n_features, embedding_dim, hidden_dim, dropout):
super(Encoder2, self).__init__()
self.seq_len = seq_len
self.n_features = n_features
self.embedding_dim = embedding_dim
self.hidden_dim = hidden_dim
self.lstm1 = nn.LSTM(
input_size=n_features,
hidden_size=self.hidden_dim,
num_layers=2,
batch_first=True,
dropout=dropout,
proj_size=self.embedding_dim,
)
def forward(self, x):
_, (h_n, _) = self.lstm1(x)
return h_n[-1].unsqueeze(1), lens
非常感谢有关使用时间序列、打包序列、lstm 单元和 dropout 的任何帮助和提示,因为我在 Internet 上的其他地方没有找到太多文档/指导。谢谢!
最好的,拉斯安基尔
【问题讨论】:
-
您的“替代”解决方案是正确的方法。你的意思是“不工作的解决方案”?什么不工作?
-
感谢@ayandas 的评论!好的,所以根据您的理解,这些实现将是等效的,但第二个更好?无法正常工作,因为它仍然会引发有关某些尺寸等的错误。正在调试硬 atm。
标签: pytorch time-series lstm autoencoder dropout