LSTM-Autoencoder处理13特征时间序列时形状不匹配报错求助
问题分析与解决方案
报错RuntimeError: shape '[1, 13, 13]' is invalid for input of size 13源于模型中两处形状处理的硬编码错误,原代码仅适配单特征输入,多特征场景下形状逻辑完全混乱。以下是具体修正步骤:
1. 核心错误点
- Encoder返回形状错误:原代码将LSTM最后一层的隐藏状态
hidden_n强制reshape为(self.n_features, self.embedding_dim),但hidden_n实际形状为(num_layers, batch_size, embedding_dim),总元素数与目标形状不匹配。 - Decoder输入处理错误:原代码用
x.repeat(self.seq_len, self.n_features)放大张量,是单特征场景下的不合理逻辑,多特征时会导致后续reshape的元素数严重失衡。
2. 修正后的模型代码
Encoder类修正
class Encoder(nn.Module): def __init__(self, seq_len, n_features, embedding_dim=64): super(Encoder, self).__init__() self.seq_len, self.n_features = seq_len, n_features self.embedding_dim, self.hidden_dim = embedding_dim, 2 * embedding_dim self.rnn1 = nn.LSTM( input_size=n_features, hidden_size=self.hidden_dim, num_layers=1, batch_first=True ) self.rnn2 = nn.LSTM( input_size=self.hidden_dim, hidden_size=embedding_dim, num_layers=1, batch_first=True ) def forward(self, x): # 自动适配单样本/批量样本输入:将(seq_len, n_features)转为(1, seq_len, n_features) if len(x.shape) == 2: x = x.unsqueeze(0) x, (_, _) = self.rnn1(x) x, (hidden_n, _) = self.rnn2(x) # 移除LSTM的num_layers维度,返回(batch_size, embedding_dim) return hidden_n.squeeze(0)
Decoder类修正
class Decoder(nn.Module): def __init__(self, seq_len, input_dim=64, n_features=1): super(Decoder, self).__init__() self.seq_len, self.input_dim = seq_len, input_dim self.hidden_dim, self.n_features = 2 * input_dim, n_features self.rnn1 = nn.LSTM( input_size=input_dim, hidden_size=input_dim, num_layers=1, batch_first=True ) self.rnn2 = nn.LSTM( input_size=input_dim, hidden_size=self.hidden_dim, num_layers=1, batch_first=True ) self.output_layer = nn.Linear(self.hidden_dim, n_features) def forward(self, x): # 将(batch_size, embedding_dim)转为LSTM输入格式:(batch_size, seq_len, embedding_dim) x = x.unsqueeze(1).repeat(1, self.seq_len, 1) x, (_, _) = self.rnn1(x) x, (_, _) = self.rnn2(x) # 对每个时间步的输出做特征映射,最终输出(batch_size, seq_len, n_features) return self.output_layer(x)
RecurrentAutoencoder类无需修改
保持原类结构即可,它会自动调用修正后的Encoder和Decoder。
3. 输入数据适配
确保训练数据集的样本形状为(seq_len, n_features):
- 若你的单样本是
(13,)(对应seq_len=1),需在Dataset的__getitem__中reshape:def __getitem__(self, idx): x = self.data[idx] return x.reshape(1, self.n_features) # 转为(1,13)
内容的提问来源于stack exchange,提问作者Bogdan Minko
相关产品推荐
相关产品推荐

