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

LSTM多变量预测模型输入维度不兼容错误排查求助

问题

编写了一个LSTM多属性预测模型,目标是在同一模型中预测rain、humidity、pressure三个指标,但训练时出现以下错误:

ValueError: Exception encountered when calling layer 'sequential' (type Sequential)
具体提示:Input 0 of layer "lstm_2" is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: (32, 10)

已知输入张量形状为(32, 30, 3),明确是LSTM输入维度冲突问题(应为3维而非2维),但不清楚错误来源,请求排查。完整代码如下:

import logging
logging.getLogger("tensorflow").setLevel(logging.ERROR)

import numpy as np
import matplotlib.pyplot as mplt
import pandas as pd
import tensorflow as tf

df = pd.read_csv('D:/ĐỒ ÁN TRÍ TUỆ NHÂN TẠO/HCM_weather.csv')
#print(df.head(10))

dataset = df[['rain' , 'humidi', 'pressure' ,'date']]
dataset.set_index('date', inplace=True)
dataset = dataset.reset_index(drop=True)
training_set = dataset.iloc[:, [0,1,2]].values
#print(training_set[:10])

from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)
#print(training_set_scaled[:10])

x_train = []
y_train = []
n_future = 4  # Dự báo độ ẩm 4 ngày tới
n_past = 30  # 30 ngày trước

for i in range(n_past, len(training_set_scaled) - n_future +1):
    x_train.append(training_set_scaled[i - n_past:i, :])
    y_train.append(training_set_scaled[i:i + n_future, :])

x_train, y_train = np.array(x_train), np.array(y_train)

from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout, Bidirectional

regressor = Sequential()
regressor.add(Bidirectional(LSTM(units=64, return_sequences=True, input_shape=(n_past, dataset.shape[1]))))
regressor.add(Dropout(0.25))
regressor.add(LSTM(units=10, return_sequences=False))
regressor.add(Dropout(0.25))
regressor.add(LSTM(units=10, return_sequences=False))
regressor.add(Dropout(0.25))
regressor.add(LSTM(units=10))
regressor.add(Dropout(0.25))
regressor.add(Dense(units=n_future * 3, activation='relu'))
regressor.compile(optimizer='adam', loss='mean_squared_error', metrics=['mean_absolute_error'])

# Train the model
regressor.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.1, verbose=1)

testdataset = pd.read_csv('D:/ĐỒ ÁN TRÍ TUỆ NHÂN TẠO/HCM_weather.csv')
testdataset = testdataset.iloc[:30, [5,6,7]].values
real_humidity = pd.read_csv('D:/ĐỒ ÁN TRÍ TUỆ NHÂN TẠO/HCM_weather.csv')
real_humidity = real_humidity.iloc[30:, [5,6,7]].values

# Assuming 'testdataset' contains the data for the test set
testing = sc.transform(testdataset)
testing = np.array(testing)
testing = np.reshape(testing, (1, n_past, 3))

predicted_values = []  # List to store the predictions

for i in range(30):
    # Predict the next 'n_future' time steps
    prediction = regressor.predict(testing)

    # Store the prediction
    predicted_values.append(prediction[0])

    # Convert the prediction to a 3D array to update 'testing'
    prediction_3d = prediction.reshape(1, -1, 3)

    # Remove the oldest time step from 'testing' and add the prediction
    testing = np.concatenate((testing[:, n_future:, :], prediction_3d), axis=1)
    testing = testing.reshape(1, n_past, 3)  # Reshape to 3D




predicted_values = np.array(predicted_values)
predicted_values = sc.inverse_transform(predicted_values)
predicted_values = np.reshape(predicted_values, (predicted_values.shape[0], predicted_values.shape[1] // 3 , 3))

print(predicted_values)
print()
print(predicted_values.size)
print()
print(predicted_values.shape)

#real_humidity = real_humidity[:120]

#predicted_values = predicted_values.reshape(120,1)
#mplt.plot(predicted_values , label = 'predicted')
#mplt.plot(real_humidity , label = 'real value')

#mplt.legend()
#mplt.show()
问题分析与解决方案

错误原因

LSTM层要求输入必须是3维张量,形状为(batch_size, time_steps, features)。你的错误出现在模型堆叠的LSTM层上:

  • 第二个LSTM层设置了return_sequences=False,输出是2维张量(batch_size, units)(即(32,10))
  • 第三个LSTM层需要3维输入,但接收到的是第二个LSTM输出的2维张量,因此维度不匹配。

修正方案

如果要堆叠LSTM层,除了最后一层LSTM外,前面的所有LSTM层都需要设置return_sequences=True,这样才能输出3维张量供下一层LSTM使用。

另外需要补充两点:

  1. 输出层的形状要和y_train的形状匹配:当前y_train的形状是(samples, n_future, 3),Dense层输出是n_future*3的一维向量,因此需要将y_train展平后再训练。
  2. 测试部分的列索引要和训练集对应,避免因列不匹配导致的数据错误。

修正后的模型核心代码

# 展平y_train,匹配Dense层输出形状
y_train = y_train.reshape(y_train.shape[0], n_future*3)

regressor = Sequential()
# 第一层双向LSTM,返回3维序列
regressor.add(Bidirectional(LSTM(units=64, return_sequences=True, input_shape=(n_past, 3))))
regressor.add(Dropout(0.25))
# 第二层LSTM,返回3维序列
regressor.add(LSTM(units=10, return_sequences=True))
regressor.add(Dropout(0.25))
# 第三层LSTM,返回3维序列
regressor.add(LSTM(units=10, return_sequences=True))
regressor.add(Dropout(0.25))
# 第四层LSTM,返回2维结果(供Dense层使用)
regressor.add(LSTM(units=10, return_sequences=False))
regressor.add(Dropout(0.25))
# Dense层输出n_future*3个节点,对应展平后的y_train
regressor.add(Dense(units=n_future * 3, activation='relu'))
regressor.compile(optimizer='adam', loss='mean_squared_error', metrics=['mean_absolute_error'])

完整修正代码

import logging
logging.getLogger("tensorflow").setLevel(logging.ERROR)

import numpy as np
import matplotlib.pyplot as mplt
import pandas as pd
import tensorflow as tf

df = pd.read_csv('D:/ĐỒ ÁN TRÍ TUỆ NHÂN TẠO/HCM_weather.csv')

dataset = df[['rain' , 'humidi', 'pressure' ,'date']]
dataset.set_index('date', inplace=True)
dataset = dataset.reset_index(drop=True)
training_set = dataset.iloc[:, [0,1,2]].values

from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range=(0, 1))
training_set_scaled = sc.fit_transform(training_set)

x_train = []
y_train = []
n_future = 4  # 预测未来4天
n_past = 30  # 使用过去30天的数据

for i in range(n_past, len(training_set_scaled) - n_future +1):
    x_train.append(training_set_scaled[i - n_past:i, :])
    y_train.append(training_set_scaled[i:i + n_future, :])

x_train, y_train = np.array(x_train), np.array(y_train)
# 展平y_train,匹配Dense层输出
y_train = y_train.reshape(y_train.shape[0], n_future*3)

from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout, Bidirectional

regressor = Sequential()
regressor.add(Bidirectional(LSTM(units=64, return_sequences=True, input_shape=(n_past, 3))))
regressor.add(Dropout(0.25))
regressor.add(LSTM(units=10, return_sequences=True))
regressor.add(Dropout(0.25))
regressor.add(LSTM(units=10, return_sequences=True))
regressor.add(Dropout(0.25))
regressor.add(LSTM(units=10, return_sequences=False))
regressor.add(Dropout(0.25))
regressor.add(Dense(units=n_future * 3, activation='relu'))
regressor.compile(optimizer='adam', loss='mean_squared_error', metrics=['mean_absolute_error'])

# 训练模型
regressor.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.1, verbose=1)

testdataset = pd.read_csv('D:/ĐỒ ÁN TRÍ TUỆ NHÂN TẠO/HCM_weather.csv')
# 匹配训练集列索引,确保是rain、humidi、pressure三列
testdataset = testdataset.iloc[:30, [0,1,2]].values
real_humidity = pd.read_csv('D:/ĐỒ ÁN TRÍ TUỆ NHÂN TẠO/HCM_weather.csv')
# 截取对应长度的真实数据
real_humidity = real_humidity.iloc[30:30+30*n_future, [0,1,2]].values

# 预处理测试数据
testing = sc.transform(testdataset)
testing = np.array(testing)
testing = np.reshape(testing, (1, n_past, 3))

predicted_values = []

for i in range(30):
    prediction = regressor.predict(testing, verbose=0)
    predicted_values.append(prediction[0])
    
    # 将预测结果转为3维,用于更新测试窗口
    prediction_3d = prediction.reshape(1, n_future, 3)
    # 滑动窗口:移除最旧的n_future个时间步,加入新预测的结果
    testing = np.concatenate((testing[:, n_future:, :], prediction_3d), axis=1)
    testing = testing.reshape(1, n_past, 3)

# 逆标准化并调整形状为(总预测天数, 3)
predicted_values = np.array(predicted_values)
predicted_values = sc.inverse_transform(predicted_values)
predicted_values = predicted_values.reshape(predicted_values.shape[0]*n_future, 3)

print(predicted_values)
print(f"预测结果形状: {predicted_values.shape}")
print(f"真实数据形状: {real_humidity.shape}")

# 可视化湿度预测结果
mplt.figure(figsize=(12,6))
mplt.plot(predicted_values[:,1], label='预测湿度')
mplt.plot(real_humidity[:,1], label='真实湿度')
mplt.legend()
mplt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:25:08