基于TF2的堆叠双向LSTM模型输入不兼容错误原因排查
问题原因分析
错误的核心原因是堆叠LSTM层时,前一层没有返回序列输出,导致后续LSTM层输入维度不匹配:
- 默认情况下,
tf.keras.layers.LSTM的return_sequences参数为False,此时Bidirectional LSTM输出的是2D张量,形状为(batch_size, 2*filter_len)(双向结构会把正反方向的输出拼接,所以单元数是设置值的2倍)。 - 后续的
Bidirectional(LSTM)层要求输入是3D张量((batch_size, sequence_length, features)),用来处理时序序列。当把2D张量传入第二个LSTM层时,就会触发expected ndim=3, found ndim=2的维度不兼容错误。
看你的代码,第一个LSTM层self.lstm1 = Bidirectional(LSTM(filter_len, input_shape = (-1, -1, numchannels)))没有设置return_sequences=True,所以输出是2D的(8,256)(这里256对应2*filter_len),传入lstm2时完全不符合输入要求。
修复方案
给除最后一层外的堆叠LSTM层添加return_sequences=True参数,让它们返回完整的序列输出,供下一层LSTM处理:
class ForexPredictionModel(tf.keras.Model): def __init__(self, seg_len, **kwargs): super(ForexPredictionModel, self).__init__(**kwargs) # 第一个LSTM层,返回序列供下一层处理 self.lstm1 = Bidirectional(LSTM(filter_len, return_sequences=True, input_shape = (-1, -1, numchannels))) # 第二个LSTM层,同样返回序列 self.lstm2 = Bidirectional(LSTM(filter_len, return_sequences=True)) # 第三个LSTM层,不需要返回序列,直接输出特征供全连接层使用 self.lstm3 = Bidirectional(LSTM(filter_len)) self.dense = Dense(256, activation="relu") self.out = Dense(num_classes, activation="sigmoid") def call(self, x): x = self.lstm1(x) x = self.lstm2(x) x = self.lstm3(x) x = self.dense(x) x = self.out(x) return x
调整后:
lstm1和lstm2输出3D张量(batch_size, seq_len, 2*filter_len),完全符合下一层LSTM的输入格式lstm3输出2D张量,正好适配后续的全连接Dense层
内容的提问来源于stack exchange,提问作者batuman
相关产品推荐
相关产品推荐

