基于CNN-LSTM的欧盟两国太阳能发电量多输出时序预测模型改造咨询
针对双国家太阳能发电量预测的CNN-LSTM模型改造方案
方案1:特征拆分+共享主干分支(推荐,适合数据分布相似的国家)
将输入的8维特征拆分为两个国家各自的4维特征,共享同一个CNN-LSTM特征提取主干,最后分别输出每个国家的24步预测并拼接结果。这种方式既复用通用特征提取能力,又能明确区分不同国家的预测任务。
代码实现
import tensorflow as tf def get_joint_model(window_size, n_features_per_country=4): # 定义输入层 inputs = tf.keras.layers.Input(shape=(window_size, n_features_per_country*2)) # 拆分输入为两个国家的特征组 x1 = tf.keras.layers.Lambda(lambda x: x[:, :, :n_features_per_country])(inputs) x2 = tf.keras.layers.Lambda(lambda x: x[:, :, n_features_per_country:])(inputs) # 定义共享的CNN-LSTM主干网络 shared_backbone = tf.keras.models.Sequential([ tf.keras.layers.Conv1D(filters=64, kernel_size=6, strides=1, padding="causal", activation="relu"), tf.keras.layers.LSTM(128, return_sequences=True, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2, l2=1e-2)), tf.keras.layers.Dropout(0.3), tf.keras.layers.LSTM(128, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2, l2=1e-2)), tf.keras.layers.Dropout(0.3), tf.keras.layers.Dense(64, activation="relu") ]) # 两个国家共享主干提取特征 features1 = shared_backbone(x1) features2 = shared_backbone(x2) # 每个国家的24步预测头 pred1 = tf.keras.layers.Dense(window_size, activation="relu")(features1) pred2 = tf.keras.layers.Dense(window_size, activation="relu")(features2) # 拼接结果,输出形状为(batch, 24, 2) outputs = tf.keras.layers.Concatenate(axis=-1)([pred1, pred2]) model = tf.keras.models.Model(inputs=inputs, outputs=outputs) model.summary() model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4), metrics=["mae"]) return model # 调用模型:窗口大小24,每个国家4个特征 model = get_joint_model(24)
说明
- 拆分输入避免不同国家的特征互相干扰,让模型明确区分任务
- 共享主干减少参数量,同时学习太阳能预测的通用规律(如天气与发电量的关联)
方案2:独立分支+特征融合(适合数据差异大的国家)
如果两个国家的气象条件、发电设施差异明显,让各自的分支独立学习特征会更有效,可选在中间层融合两个分支的信息,挖掘国家间的潜在关联。
代码实现
import tensorflow as tf def get_joint_model(window_size, n_features_per_country=4): inputs = tf.keras.layers.Input(shape=(window_size, n_features_per_country*2)) # 拆分输入 x1 = tf.keras.layers.Lambda(lambda x: x[:, :, :n_features_per_country])(inputs) x2 = tf.keras.layers.Lambda(lambda x: x[:, :, n_features_per_country:])(inputs) # 国家1的独立特征提取分支 branch1 = tf.keras.models.Sequential([ tf.keras.layers.Conv1D(filters=64, kernel_size=6, strides=1, padding="causal", activation="relu"), tf.keras.layers.LSTM(128, return_sequences=True, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2, l2=1e-2)), tf.keras.layers.Dropout(0.3), tf.keras.layers.LSTM(128, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2, l2=1e-2)), tf.keras.layers.Dropout(0.3), tf.keras.layers.Dense(64, activation="relu") ]) # 国家2的独立特征提取分支(可根据需求调整参数) branch2 = tf.keras.models.Sequential([ tf.keras.layers.Conv1D(filters=64, kernel_size=6, strides=1, padding="causal", activation="relu"), tf.keras.layers.LSTM(128, return_sequences=True, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2, l2=1e-2)), tf.keras.layers.Dropout(0.3), tf.keras.layers.LSTM(128, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2, l2=1e-2)), tf.keras.layers.Dropout(0.3), tf.keras.layers.Dense(64, activation="relu") ]) features1 = branch1(x1) features2 = branch2(x2) # 可选:融合两个分支的特征,挖掘国家间关联 # fused_features = tf.keras.layers.Concatenate(axis=-1)([features1, features2]) # fused_features = tf.keras.layers.Dense(64, activation="relu")(fused_features) # 生成预测结果 pred1 = tf.keras.layers.Dense(window_size, activation="relu")(features1) pred2 = tf.keras.layers.Dense(window_size, activation="relu")(features2) outputs = tf.keras.layers.Concatenate(axis=-1)([pred1, pred2]) model = tf.keras.models.Model(inputs=inputs, outputs=outputs) model.summary() model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4), metrics=["mae"]) return model
说明
- 独立分支让模型针对每个国家的特性学习专属特征,避免通用模式干扰
- 可选的融合层可捕捉区域气象联动等跨国家关联信息
方案3:最小改动适配(快速验证)
如果不想大幅修改原有结构,可通过分组卷积让模型自动区分两个国家的特征,同时调整输出层适配目标形状。
代码实现
import tensorflow as tf def get_model(window_size, n_features): model = tf.keras.models.Sequential([ # 分组卷积:将8维特征分为2组,每组对应一个国家的4个特征 tf.keras.layers.Conv1D(filters=64, kernel_size=6, strides=1, padding="causal", activation="relu", groups=2, input_shape=[window_size, n_features]), tf.keras.layers.LSTM(128, return_sequences=True, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2,l2=1e-2)), tf.keras.layers.Dropout(.3), tf.keras.layers.LSTM(128, recurrent_regularizer=tf.keras.regularizers.l1_l2(l1=1e-2,l2=1e-2)), tf.keras.layers.Dropout(.3), tf.keras.layers.Dense(64, activation="relu"), # 先输出48维(24*2),再reshape为(24,2)适配目标形状 tf.keras.layers.Dense(window_size*2, activation="relu"), tf.keras.layers.Reshape((window_size, 2)) ]) model.summary() model.compile(loss="mse", optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4), metrics=["mae"]) return model # 调用模型:窗口大小24,总特征数8 model = get_model(24, 8)
说明
- 分组卷积强制模型按国家分组处理特征,避免交叉干扰
- 改动最小,适合快速验证双国家预测的可行性
关键注意事项
- 数据对齐:确保两个国家的时序数据在时间步上严格对齐,避免时间错位导致预测偏差
- 自定义损失:若需给不同国家的预测分配权重,可自定义损失函数,例如:
def weighted_mse(y_true, y_pred): return 0.6*tf.keras.losses.mse(y_true[:,:,0], y_pred[:,:,0]) + 0.4*tf.keras.losses.mse(y_true[:,:,1], y_pred[:,:,1]) - 正则化调整:模型参数量可能增加,保持或适当调整L1/L2正则化强度,防止过拟合
内容的提问来源于stack exchange,提问作者Mikołaj Jędrzejewski
相关产品推荐
相关产品推荐

