You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复输入维度不匹配错误:预期2维但获(32,168,5)数组

解决LSTM-DNN混合模型的输入维度不匹配问题

我一眼就看出问题出在输入层定义和数据维度的不匹配上,还有你对序列数据的处理逻辑有点混乱,咱们一步步来修正:

错误核心原因

你定义的input_1 = Input(shape=(5, ))期望的是2D输入(形状为(batch_size, 5)),但你的实际输入x_batch_1是3D序列数据(形状为(32,168,5))——这里32是批量大小,168是序列长度,5是每个时间步的特征数。LSTM分支的input_2也存在同样的定义错误,而且你用tf.expand_dims的操作完全搞反了方向,反而让维度更混乱。


具体修正步骤

1. 修正输入层的形状定义

你的输入是带序列长度的3D数据,所以输入层的shape应该定义为(序列长度, 特征数),如果想兼容可变序列长度,可以用(None, 特征数):

# first input model: 对应输入形状(batch_size, 168, 5)
input_1 = Input(shape=(168, 5))  # 换成(None,5)可支持任意长度的序列
# second input model: 对应输入形状(batch_size, 168,7)
input_2 = Input(shape=(168,7))   # 换成(None,7)可支持任意长度的序列

2. 调整DNN分支的处理逻辑

因为input_1是序列数据,你需要让全连接层处理每个时间步的特征,这里要用TimeDistributed包裹Dense,这样每个时间步的5维特征都会经过64维的全连接,输出保持序列维度:

# DNN分支:处理序列数据,每个时间步独立过Dense
dense_1 = TimeDistributed(Dense(units=64))(input_1)
# 此时dense_1的形状是(batch_size, 168, 64)

3. 简化LSTM分支的输入处理

你的LSTM层已经设置了return_sequences=True,输出形状是(batch_size,168,64),和DNN分支的输出维度匹配。这里可以去掉冗余的input_shape参数(输入层已经定义了形状),也不需要tf.expand_dims——因为你的输入已经是LSTM需要的3D格式(batch, seq_len, features):

# LSTM分支:直接处理3D输入,return_sequences=True保留序列维度
lstm_1 = LSTM(units=64, return_sequences=True)(input_2)
# 此时lstm_1的形状是(batch_size,168,64)

4. 修正拼接轴并调整输出层

现在两个分支的输出都是(batch_size,168,64),我们需要在**特征轴(axis=-1)**拼接,得到(batch_size,168,128),然后用TimeDistributed(Dense)输出每个时间步的预测结果(因为你的y_batch是(32,168,1),每个时间步都有一个标签):

# 在特征轴拼接两个分支的输出
merge = concatenate([dense_1, lstm_1], axis=-1)
# 输出层:每个时间步输出1个结果
output = TimeDistributed(Dense(num_y_signals, activation='sigmoid'))(merge)
model = Model(inputs=[input_1, input_2], outputs=output)

5. 调整验证数据的维度

你的验证数据不需要额外expand_dims(axis=0),如果x_test1_scaled的原始形状是(样本数, 168,5),直接传入即可。如果你的验证集是一个长序列(5808,5),那你需要把它分割成和训练数据一样的序列长度(168),或者让模型支持可变序列长度(输入层用(None,5)),否则模型会因为序列长度不匹配报错。


修正后的完整模型代码

from tensorflow.keras.layers import Input, Dense, LSTM, concatenate, TimeDistributed
from tensorflow.keras.models import Model

# first input model
input_1 = Input(shape=(168, 5))  # 或者(None,5)支持可变序列长度
dense_1 = TimeDistributed(Dense(units=64))(input_1)

# second input model
input_2 = Input(shape=(168, 7))  # 或者(None,7)
lstm_1 = LSTM(units=64, return_sequences=True)(input_2)

# merge input models
merge = concatenate([dense_1, lstm_1], axis=-1)
output = TimeDistributed(Dense(num_y_signals, activation='sigmoid'))(merge)

model = Model(inputs=[input_1, input_2], outputs=output)
model.summary()

补充说明

你之前考虑的flatten思路不适用这里:如果直接flatten序列维度,会把(32,168,5)变成(32,840),这样和LSTM输出的(32,168,64)无法拼接——因为维度数量和长度都不匹配。只有保持序列维度一致,才能在特征轴拼接,这也是处理序列到序列任务的正确方式。

内容的提问来源于stack exchange,提问作者Joichiro Nishi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:23:46