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

时间序列数据下LSTM输入形状不匹配问题求助

问题分析与解决方案

核心错误原因

LSTM层要求输入数据为三维张量,形状是(样本数, 时间步长, 特征数),但你的输入数据目前是二维的(样本数, 8),缺少时间步维度;同时你错误地将input_shape设置为(样本数, 特征数),而Keras中input_shape不需要包含样本数(样本数属于batch维度,框架自动处理),正确的input_shape格式是(时间步长, 特征数)。

另外你的数据划分逻辑有问题:第二次划分时直接用了原始的X和y,导致训练集、验证集、测试集存在数据重叠,应该基于第一次划分后的训练集再拆分验证集。

具体修正步骤

1. 修正数据划分逻辑

将第二次划分的数据源改为第一次拆分后的训练集:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, shuffle=True)
# 基于训练集拆分验证集,而非原始数据
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.1, shuffle=True)

2. 调整输入数据形状为LSTM要求的三维格式

假设你是单步预测(每个样本是一个时间点的8个特征,对应一个扭矩值),则时间步长设为1,将所有输入数据reshape:

# 转换为三维形状:(样本数, 时间步长, 特征数)
X_train = X_train.values.reshape((X_train.shape[0], 1, X_train.shape[1]))
X_val = X_val.values.reshape((X_val.shape[0], 1, X_val.shape[1]))
X_test = X_test.values.reshape((X_test.shape[0], 1, X_test.shape[1]))

3. 修正LSTM层的input_shape参数

将input_shape改为(时间步长, 特征数),这里时间步长是1,特征数是8:

input_shape = (1, X_train.shape[2])  # X_train.shape[2]是特征数8
model.add(LSTM(64, input_shape=input_shape, return_sequences=True))

4. 调整后续层的适配(可选)

因为你设置了return_sequences=True,LSTM层输出的是三维张量(样本数, 时间步长, 64),后续的Dense层会自动处理,但如果不需要返回序列,也可以将return_sequences设为False(更适合单步预测场景),这样LSTM输出二维张量,后续层更简洁:

model.add(LSTM(64, input_shape=input_shape, return_sequences=False))

修正后的完整代码

import pandas as pd
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping
import tensorflow as tf

file = r'/content/drive/MyDrive/only_force_pt1.csv'

df = pd.read_csv(file)

X = df.iloc[:, 1:9]
y = df.iloc[:,9]

# 修正数据划分:先分训练+测试,再从训练集分验证集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, shuffle=True)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.1, shuffle=True)

# 将输入数据reshape为LSTM要求的三维格式:(样本数, 时间步长, 特征数)
time_steps = 1
X_train = X_train.values.reshape((X_train.shape[0], time_steps, X_train.shape[1]))
X_val = X_val.values.reshape((X_val.shape[0], time_steps, X_val.shape[1]))
X_test = X_test.values.reshape((X_test.shape[0], time_steps, X_test.shape[1]))

verbose, epochs, batch_size = 1, 200, 32
input_shape = (time_steps, X_train.shape[2])  # 正确的input_shape:(时间步长, 特征数)

model = Sequential()

# LSTM层:如果是单步预测,return_sequences设为False更合适
model.add(LSTM(64, input_shape=input_shape, return_sequences=False))
model.add(Dense(32, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(0.001)))
model.add(Dense(1, activation='relu'))

earlystopper = EarlyStopping(monitor='val_loss', min_delta=0, patience=20, verbose=1, mode='auto')

model.summary()

model.compile(loss='mse', optimizer=Adam(learning_rate=0.001), metrics=[tf.keras.metrics.RootMeanSquaredError()])

history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, verbose=verbose, validation_data=(X_val,y_val), callbacks=[earlystopper])

额外说明

如果你的数据是序列数据(比如用前N个时间步的8个特征预测下一个时间步的扭矩),则需要调整time_steps为N,并重新构造输入序列(比如滑动窗口生成样本),这时候输入形状会是(样本数, N, 8)。如果是单步预测,上面的修正即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:15:37