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

如何向Keras模型输入滑动窗口式多列序列数据?

滑动窗口时序输入的实现方案

问题背景

手里有个形状为(128, 47088)的NumPy数组,需要用滑动窗口的方式喂给模型:比如先取第0-4列(总共640条数据)作为一个输入样本,下一次取第1-5列,以此类推。之前试了GRU、LSTM和Flatten层都没成功,想知道是要提前预处理数据,还是能在模型内部完成这种数据重塑?

原训练代码参考:

# np_input 是形状为(128, 47088)的NumPy数组
model = keras.Sequential([
    keras.Input(shape=(128,)),
    keras.layers.Dense(1024, activation='relu', kernel_regularizer='l2'),
    keras.layers.Dense(1024, activation='relu', kernel_regularizer='l2'),
    keras.layers.Dense(1024, activation='relu', kernel_regularizer='l2'),
    keras.layers.Dense(np_output.shape[0], activation='sigmoid'),
])
model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.0001), loss='mean_squared_error', metrics=['acc', 'mse'], run_eagerly=True)
model.summary()

# 按轴1划分训练测试集,所以先转置输入数据
X_train, X_test, y_train, y_test = train_test_split(np_input.T, np_output.T, test_size=0.2, shuffle=False, random_state=None)

hist = model.fit(X_train, y_train, epochs=100, verbose=2, batch_size=2048, use_multiprocessing=True, validation_data=(X_test, y_test), callbacks=callbacks )

两种可行方案

方案一:提前预处理数据(更推荐)

滑动窗口逻辑在预处理阶段实现更直观,调试起来也简单,不会和模型层的逻辑混在一起。具体步骤如下:

  1. 确定窗口参数:比如你需要的窗口大小是5(每次取5列),滑动步长是1(每次移动1列)。
  2. 将原始数组转换成(样本数, 窗口大小, 特征数)的格式——这是LSTM/GRU要求的输入形状(batch_size, timesteps, features)。

代码示例:

import numpy as np
from sklearn.model_selection import train_test_split
import keras

# 模拟原始输入和标签
np_input = np.random.rand(128, 47088)  # (特征数, 时序步数)
np_output = np.random.rand(1, 47088)    # 假设标签和每一步输入对应

window_size = 5
step = 1

# 计算能生成的样本总数
num_samples = np_input.shape[1] - window_size + 1

# 生成滑动窗口样本
X_windowed = np.zeros((num_samples, window_size, 128))
for i in range(num_samples):
    # 截取i到i+window_size的列,转置后变成(window_size, 128)的形状
    X_windowed[i] = np_input[:, i:i+window_size].T

# 处理标签:通常标签对应窗口最后一个时间步的输出,所以取从第window_size-1列开始的所有标签
y_windowed = np_output[:, window_size-1:].T

# 划分训练测试集(时序数据别打乱)
X_train, X_test, y_train, y_test = train_test_split(X_windowed, y_windowed, test_size=0.2, shuffle=False)

# 构建带GRU的模型
model = keras.Sequential([
    keras.Input(shape=(window_size, 128)),  # 输入形状(窗口大小, 特征数)
    keras.layers.GRU(256, kernel_regularizer='l2'),
    keras.layers.Dense(1024, activation='relu', kernel_regularizer='l2'),
    keras.layers.Dense(np_output.shape[0], activation='sigmoid'),
])
model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.0001), loss='mean_squared_error', metrics=['acc', 'mse'])
model.summary()

# 启动训练
hist = model.fit(X_train, y_train, epochs=100, verbose=2, batch_size=2048, validation_data=(X_test, y_test))

方案二:在模型内部实现滑动窗口(用Lambda层)

如果一定要在模型里处理,可以用TensorFlow的tf.sliding_window_view结合Lambda层实现,但这种方式会增加模型复杂度,调试难度更高,只适合特定场景。

代码示例:

import tensorflow as tf
import keras

window_size = 5

model = keras.Sequential([
    # 输入完整的时序序列,形状(特征数, 时序长度)
    keras.Input(shape=(128, None)),
    # 转置成(批量, 时序长度, 特征数),适配滑动窗口函数
    keras.layers.Lambda(lambda x: tf.transpose(x, perm=[0, 2, 1])),
    # 生成滑动窗口,输出形状(批量, 样本数, 窗口大小, 特征数)
    keras.layers.Lambda(lambda x: tf.sliding_window_view(x, window_size, axis=1)),
    # 把窗口内的特征展平,或者直接喂给GRU(根据需求调整)
    keras.layers.Reshape((-1, window_size * 128)),
    keras.layers.GRU(256, kernel_regularizer='l2'),
    keras.layers.Dense(1024, activation='relu', kernel_regularizer='l2'),
    keras.layers.Dense(np_output.shape[0], activation='sigmoid'),
])

注意:这种方式需要喂入完整的时序序列,而不是单个样本,所以数据加载逻辑要对应调整,灵活性不如预处理方案。

之前失败的原因

你之前的模型输入形状是(128,),这只是单个样本的特征数,没有包含时序维度。而GRU/LSTM要求输入必须带有时间步维度(即形状为(timesteps, features)),所以直接用原数据格式喂入肯定会失败。不管用哪种方案,核心都是要把数据转换成包含窗口时间步的形状。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:37:01