我正在构建一个 LSTM 自动编码器来对信号进行降噪,并将采用超过 1 个特征作为输入。
我已经设置了模型编码器部分,如下所示,它适用于单一特征输入(即只有一个特征的序列):
class Encoder(nn.Module):
def __init__(self, seq_len, n_features, num_layers=1, embedding_dim=64):
super(Encoder, self).__init__()
self.seq_len = seq_len
self.n_features = n_features
self.num_layers = num_layers
self.embedding_dim = embedding_dim
self.hidden_dim = 2 * embedding_dim
# input: batch_size, seq_len, features
self.lstm1 = nn.LSTM(
input_size=self.n_features,
hidden_size=self.hidden_dim,
num_layers=self.num_layers,
batch_first=True
) # output: batch size, seq_len, hidden_dim
# input: batch_size, seq_len, hidden_dim
self.lstm2 = nn.LSTM(
input_size=self.hidden_dim,
hidden_size = self.embedding_dim,
num_layers = self.num_layers,
batch_first=True
) # output: batch_size, seq_len, embedding_dim
def forward(self, x):
print(x)
x = x.reshape((1, self.seq_len, self.n_features))
print(x.shape)
x, (_, _) = self.lstm1(x)
print(x.shape)
x, (hidden_n, _) = self.lstm2(x)
print(x.shape, hidden_n.shape)
print(hidden_n)
return hidden_n.reshape((self.n_features, self.embedding_dim))
当我按如下方式测试此设置时:
model = Encoder(1024, 1)
model.forward(torch.randn(1024, 1))
1 代表单个特征,一切都很好。但是,当我执行以下操作时(其中 2 表示 2 个特征的序列):
model = Encoder(1024, 2)
model.forward(torch.randn(1024, 2))
我收到以下错误:
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Input In [296], in <cell line: 1>()
----> 1 model.forward(torch.randn(1024, 2))
Input In [294], in Encoder.forward(self, x)
36 print(hidden_n)
37 # print(hidden_n.reshape((self.n_features, self.embedding_dim)).shape)
---> 39 return hidden_n.reshape((self.n_features, self.embedding_dim))
RuntimeError: shape '[2, 64]' is invalid for input of size 64
hidden_n
形状显示为 torch.Size([1, 1, 64])
。我想了解,如果我们有超过 1 个功能,例如2,我们是否想要将该形状转换为 1, 2, 64
的格式,以便隐藏状态对两个特征都具有权重?
有人可以解释一下为什么 reshape 不喜欢我尝试重构编码器输出的方式,以及我应该如何做到这一点,以便模型能够考虑任何特征大小。
我在这里错过了什么/也许误解了什么?
这段代码的问题(我在几个地方看到它正在研究你想要做的事情),在于编码器的最后一个重塑操作应该使用
(batch_size, embedding_dim)
。
在互联网电话游戏中的某个时刻,
1
被硬编码为batch_size
,然后其他人用1
替换了n_features
。
另外,回答您的问题之一:
我们是否希望将该形状转换为 1, 2, 64 的格式,以便隐藏状态具有两个特征的权重?
无论输入的特征数量有多少,LSTM 的隐藏状态都是单个向量乘以batch_size。这就是为什么你想重塑为
(batch_size, hidden_size)
。