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

Keras构建气象预测LSTM模型时输入维度不兼容问题求助

气象预测多输入LSTM模型维度错误修复

问题概述

目标是构建神经网络,输入过去30天数据预测一周后气温变化百分比的正负分类,模型包含两个输入:

  • 数值输入:形状为(30,3),对应每日的[温度, 湿度, 气压]数据
  • 文本输入:30天嵌套列表,对应每日的气象观测文本序列

用户编写的Keras模型代码如下:

embedding_dim = 128  
vocab_size = len(words_to_int)  # number of unique words

num_input = keras.Input(shape= (30,3), name="nums")
nmlstm = layers.LSTM(64)(num_input) #num input goes to num lstm
nmdense = layers.Dense(64)(nmlstm) #num lstm goes to num dense

text_input = keras.Input(shape= (30, max_sequence_length), name="text") #basically length of the longest string observation sequence 
text_vec = layers.Embedding(vocab_size, embedding_dim, mask_zero=True)(text_input) #text input goes to text embedding
txlstm = layers.LSTM(64)(text_vec) #text embedding goes to text lstm


united = layers.concatenate([nmdense, txlstm]) #concatenating text lstm and num dense
almostlast = layers.Dense(64)(united) #computing united input 
last = layers.Dense(2, name='prediction')(almostlast) #output dense layer

model = keras.Model(inputs=[num_input, text_input], outputs=last)
model.compile(optimizer='adam', loss=keras.losses.CategoricalCrossentropy)
model.fit({"nums": X1_train, "text": X2_train}, {"prediction": y_train}, epochs=8, batch_size=10)

运行时出现维度不兼容错误:

ValueError: Input 0 of layer "lstm_1" is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: (None, 30, 2, 128)

错误原因

文本输入经过Embedding层后,输出张量为4维:(batch_size, 30, max_sequence_length, embedding_dim),而LSTM层仅接受3维输入((batch_size, timesteps, features))。这里的30是天数(外层时间步),每个天数下包含max_sequence_length个词的序列,需要先对单日文本序列提取特征,将4维张量压缩为3维后,再送入处理30天序列的LSTM。

修复方案

在Embedding层之后添加TimeDistributed层,对每天的文本序列单独提取特征,将4维张量转换为3维,再送入后续LSTM。以下是两种可行的修改方式:

方式1:用LSTM提取单日文本特征

embedding_dim = 128  
vocab_size = len(words_to_int)  # 唯一词数量

# 数值输入分支
num_input = keras.Input(shape=(30,3), name="nums")
nmlstm = layers.LSTM(64)(num_input)
nmdense = layers.Dense(64)(nmlstm)

# 文本输入分支
text_input = keras.Input(shape=(30, max_sequence_length), name="text") 
text_vec = layers.Embedding(vocab_size, embedding_dim, mask_zero=True)(text_input)
# 对每天的文本序列单独应用LSTM,提取单日特征
daily_text_feature = layers.TimeDistributed(layers.LSTM(32))(text_vec)
# 此时daily_text_feature形状为(None, 30, 32),符合LSTM输入要求
txlstm = layers.LSTM(64)(daily_text_feature)

# 拼接与输出层
united = layers.concatenate([nmdense, txlstm])
almostlast = layers.Dense(64)(united)
last = layers.Dense(2, name='prediction')(almostlast)

model = keras.Model(inputs=[num_input, text_input], outputs=last)
model.compile(optimizer='adam', loss=keras.losses.CategoricalCrossentropy)
model.fit({"nums": X1_train, "text": X2_train}, {"prediction": y_train}, epochs=8, batch_size=10)

方式2:用池化提取单日文本特征(计算量更小)

若觉得LSTM计算量过大,可替换为GlobalAveragePooling1D做平均池化:

embedding_dim = 128  
vocab_size = len(words_to_int)  # 唯一词数量

# 数值输入分支
num_input = keras.Input(shape=(30,3), name="nums")
nmlstm = layers.LSTM(64)(num_input)
nmdense = layers.Dense(64)(nmlstm)

# 文本输入分支
text_input = keras.Input(shape=(30, max_sequence_length), name="text") 
text_vec = layers.Embedding(vocab_size, embedding_dim, mask_zero=True)(text_input)
# 对每天的文本序列做平均池化,提取单日特征
daily_text_feature = layers.TimeDistributed(layers.GlobalAveragePooling1D())(text_vec)
# 此时daily_text_feature形状为(None, 30, 128),符合LSTM输入要求
txlstm = layers.LSTM(64)(daily_text_feature)

# 拼接与输出层
united = layers.concatenate([nmdense, txlstm])
almostlast = layers.Dense(64)(united)
last = layers.Dense(2, name='prediction')(almostlast)

model = keras.Model(inputs=[num_input, text_input], outputs=last)
model.compile(optimizer='adam', loss=keras.losses.CategoricalCrossentropy)
model.fit({"nums": X1_train, "text": X2_train}, {"prediction": y_train}, epochs=8, batch_size=10)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:06:04