单变量时间序列场景下如何设置keras.layers.SimpleRNN的input_shape
报错根因
Keras中所有循环层(包括SimpleRNN、LSTM、GRU等)的输入都要求是3维张量,维度对应规则为 (样本数, 时间步长, 特征数),你当前的报错来自两个问题:
- 输入数据
X_train的维度是(58118,),仅包含样本数维度,缺少时间步长、特征数两个维度,送入模型时自动补全为2维(None,1),不符合RNN层要求的3维输入 - 你没有将原始单变量时间序列转换为符合RNN训练要求的「输入序列-输出标签」监督学习样本对
解决步骤
1. 构造时间序列监督样本
首先通过滑动窗口将原始序列转换为RNN可训练的样本格式,示例代码如下:
import numpy as np def create_seq_samples(series, time_steps=10): X, y = [], [] for i in range(len(series) - time_steps): # 取过去time_steps个值作为输入序列 X.append(series[i:i+time_steps]) # 取当前时刻值作为预测标签 y.append(series[i+time_steps]) return np.array(X), np.array(y) # 可根据需求调整时间步长参数time_steps time_steps = 10 # 替换x为你的原始单变量序列 X, y = create_seq_samples(x, time_steps=time_steps)
2. 调整数据维度
构造完成的X当前维度是(样本数, 时间步长),需要补充特征数维度(单变量特征数为1),再进行数据集拆分:
# 升为3维:(样本数, 时间步长) -> (样本数, 时间步长, 1) X = np.expand_dims(X, axis=-1) # 后续拆分逻辑不变 X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,shuffle=False,random_state=1004) X_train,X_val,y_train,y_val = train_test_split(X_train,y_train,test_size=0.125,shuffle=False,random_state=1004)
3. 调整input_shape和输出层
此时SimpleRNN的input_shape直接设置为(时间步长, 特征数)即可,如果你使用固定时间步长直接填入对应值即可;如果需要支持可变时间步长可以保留(None,1)。
另外如果你的需求是单步预测单个数值,最后一层可以去掉TimeDistributed,调整为输出1个值的Dense层,示例模型结构如下:
with tf.device('/gpu:0'): model = keras.models.Sequential([ # 固定时间步长的话input_shape=(time_steps,1)即可 keras.layers.SimpleRNN(20, return_sequences=True, input_shape=(time_steps,1)), keras.layers.SimpleRNN(20), keras.layers.Dense(1) ]) model.compile(loss="mse", optimizer="adam") history = model.fit(X_train, y_train, epochs=20,validation_data=(X_val, y_val)) model.save('rnn.h5')
内容的提问来源于stack exchange,提问作者Daniel Park
相关产品推荐
相关产品推荐

