如何子类化Keras.Model实现多输入列的自回归LSTM预测模型?
多输入自回归负荷预测模型实现详解
核心逻辑梳理
你的场景核心是结合历史负荷+未来气象做24小时自回归预测,和教程的单输入场景不同,必须在每一步预测中加入对应时刻的已知气象数据。下面从模型子类化、数据构造、训练关联三个部分拆解:
1. 子类化Keras.Model适配多输入
针对你的11列气象+1列负荷数据,模型需要接收两个输入:历史窗口(2小时的气象+负荷)、未来24小时气象序列。以下是完整实现:
import tensorflow as tf class LoadForecastFeedback(tf.keras.Model): def __init__(self, out_steps, history_features=12, meteor_features=11): super().__init__() self.out_steps = out_steps # 暖身层:处理历史窗口,输出初始预测和LSTM状态 self.warmup = tf.keras.Sequential([ tf.keras.layers.LSTM(64, return_state=True), tf.keras.layers.Dense(1) # 输出初始负荷预测 ]) # 循环预测用的LSTM单元和输出层 self.lstm_cell = tf.keras.layers.LSTMCell(64) self.dense = tf.keras.layers.Dense(1) def call(self, inputs, training=None): # inputs是元组:(历史窗口, 未来气象序列) history_window, future_meteor = inputs # 暖身阶段:用历史窗口初始化LSTM状态和第一个预测值 initial_pred, state_h, state_c = self.warmup(history_window) state = [state_h, state_c] predictions = [initial_pred] # 循环生成剩余23个预测值(总步数24) for n in range(1, self.out_steps): # 取当前时刻的未来气象数据 current_meteor = future_meteor[:, n:n+1, :] # 把上一步预测的负荷扩展维度,和气象数据拼接 prev_pred = tf.expand_dims(predictions[-1], axis=1) x = tf.concat([current_meteor, prev_pred], axis=-1) # 用LSTM单元计算下一步状态和输出 lstm_output, state = self.lstm_cell(x, states=state, training=training) # 生成当前时刻的负荷预测 current_pred = self.dense(lstm_output) predictions.append(current_pred) # 整理预测结果维度:(batch_size, 24, 1),和目标序列对齐 predictions = tf.stack(predictions) predictions = tf.transpose(predictions, [1, 0, 2]) return predictions
2. 训练数据集构造
用timeseries_dataset_from_array或手动构造数据集时,必须让每个样本的输入和目标严格对应:
- 输入:(2小时历史[气象+负荷], 24小时未来气象)
- 目标:24小时未来负荷
示例代码:
import pandas as pd # 假设你的数据是DataFrame,列顺序为['load', 'meteor1', ..., 'meteor11'] df = pd.read_csv('your_data.csv') data = df.values history_len = 2 out_steps = 24 # 构造训练样本 input_history = [] input_future_meteor = [] targets = [] for i in range(len(data) - history_len - out_steps + 1): # 历史窗口:i到i+history_len-1的所有特征(负荷+气象) history = data[i:i+history_len, :] # 未来气象:i+history_len到i+history_len+out_steps-1的气象特征 future_meteor = data[i+history_len:i+history_len+out_steps, 1:] # 目标:未来24小时的负荷 target = data[i+history_len:i+history_len+out_steps, 0:1] input_history.append(history) input_future_meteor.append(future_meteor) targets.append(target) # 转成TensorFlow数据集 dataset_train = tf.data.Dataset.from_tensor_slices( ((tf.convert_to_tensor(input_history, tf.float32), tf.convert_to_tensor(input_future_meteor, tf.float32)), tf.convert_to_tensor(targets, tf.float32)) ) dataset_train = dataset_train.batch(32).shuffle(1000)
3. 训练与call方法的关联逻辑
你之前的困惑点在于训练时数据集如何和call方法交互:
model.fit会自动遍历数据集,把每个batch的输入传给call的inputs参数- 暖身阶段用历史窗口学习历史数据的特征模式,输出第一个预测值和LSTM初始状态
- 循环预测时,每一步都结合已知的未来气象和上一步的负荷预测作为输入,让模型学习两者的关联关系
- 模型输出的24小时预测序列会和目标序列计算损失(如MSE),反向传播更新所有层的参数
关键注意事项
- 必须对所有特征做标准化处理(如
StandardScaler),避免气象和负荷数值差异导致模型收敛困难 - 暖身层和LSTM单元的神经元数量可根据数据规模调整,建议从64/128开始测试
- 预测阶段只需传入最新2小时的[负荷+气象]和未来24小时气象,模型会自动完成自回归预测
内容的提问来源于stack exchange,提问作者hcollins
相关产品推荐
相关产品推荐

