光伏发电量预测毕设:CNN-LSTM等5大深度学习模型对比实战

发布时间:2026/8/28 3:07:02
光伏发电量预测毕设:CNN-LSTM等5大深度学习模型对比实战 简介时间序列预测是深度学习在工业应用中落地最广的方向之一光伏发电量预测作为典型回归任务其数据受天气影响呈现强非线性和波动性传统统计模型难以准确建模。以LSTM、GRU为代表的循环神经网络通过门控机制有效捕捉时序依赖而CNN与循环网络的混合架构如CNN-LSTM、CNN-GRU进一步强化了局部特征提取与长期记忆的结合。通过多模型对比实验可系统评估不同结构在光伏功率预测中的性能差异为模型选型提供可靠依据。本文基于一个实战毕设项目详细拆解数据清洗、滑动窗口构建、模型搭建、训练监控及结果可视化分析过程并针对维度错误、预测滞后、数据泄漏等常见问题给出排查方案为开展时序预测研究和工程实践提供可复用的方法论。 做光伏发电量预测的毕业设计最容易踩的一个坑就是模型跑了一堆最后答辩的时候导师问“你为什么要选这个模型”“这几个模型的差异到底在哪里”结果一句话都说不清楚。这个项目的标题里其实已经给出了很完整的思路就是用一个数据集把 CNN-LSTM、CNN-GRU、GRU、LSTM-transform、LSTM 这几个典型模型全部跑一遍然后做结果对比。这个思路本身就是毕业设计的正确打开方式它不追求单个模型的极致精度而是把“对比分析”作为主线这样既好写论文也好做答辩展示。这篇博文我就围绕这个项目把数据预处理、模型搭建、训练细节、结果对比、常见问题全部拆开来讲。内容主要依据我自己的实践经验和这个领域通用做法展开适合正在做相关毕设、课程设计或者是想入门时序预测的读者直接参考。1. 项目整体设计与模型选型思路1.1 为什么光伏预测任务适合用深度学习光伏发电量预测本质上是一个时间序列回归问题。输入是过去一段时间的气象数据辐照度、温度、湿度、风速等和历史发电功率输出是未来一段时间通常是下一个时刻或下一天的发电功率。传统方法比如 ARIMA、灰色预测、支持向量回归在面对光伏这种强非线性、强随机性的数据时效果往往不够理想。光伏发电有一个很显著的特点它的出力曲线受天气影响非常大。晴天的时候是一条光滑的钟形曲线多云天就会剧烈波动雨天可能一路走低。这种“同一天气类型下规律明显、跨天气类型规律突变”的特性导致传统的线性模型很难捕捉真实规律。而深度学习模型的优势在于它可以通过多层非线性变换自动从历史数据里提取特征不需要人工设计特征工程特别适合这种数据量大、特征关系复杂的场景。1.2 多模型对比设计的核心价值有些同学做毕设喜欢只搭一个模型把参数调到最好看然后收工。这其实是个策略失误。毕设和竞赛不一样竞赛只要你分数高毕设还要你有“研究工作量”。多模型对比的好处至少有三个第一个好处是能证明“深度学习方案优于传统方案”。你的对比实验里可以加一个 SVR 或者线性回归做基线这样论文里就能形成“传统方法 vs 深度学习方法”的第一层对比逻辑。第二个好处是能证明“混合模型优于单一模型”。CNN-LSTM 和 CNN-GRU 是混合架构LSTM、GRU 是单一架构二者对比可以体现混合模型在特征提取上的优势这是第二层对比逻辑。第三个好处是能支撑“模型选择结论”。你最后可以有理有据地说在同样的数据和训练条件下哪个模型最适合光伏预测这样的结论才是有信服力的。所以这个项目里选了 5 个模型LSTM、GRU、CNN-LSTM、CNN-GRU、LSTM-transform本质上就是在铺设三层对比逻辑传统 vs 深度、单一 vs 混合、基础 vs 改进。这个设计思路值得所有做类似题目的同学借鉴。1.3 任务定义与评价指标在开始写代码之前先要把任务定义清楚。光伏发电量预测按照时间尺度可以分成超短期未来几小时、短期未来几天、中长期未来几周甚至几个月。大多数毕设做的是短期预测具体来说有两种常见做法单步预测用过去 N 个小时的数据预测下 1 个小时的发电功率。这种最简单也是绝大多数毕设采用的方式。多步预测用过去 N 个小时的数据预测未来 M 个小时的发电功率。这种难度更大因为误差会随着步长累积。评价指标方面时间序列回归最常用的几个指标是平均绝对误差 MAE、均方根误差 RMSE、平均绝对百分比误差 MAPE以及拟合优度 R²。其中 MAPE 需要注意一个问题当实际发电功率接近 0 时比如夜间MAPE 会变成一个非常大的数所以很多论文里会过滤掉功率小于某个阈值比如额定功率的 1%的样本再计算 MAPE这个细节在你的实验里也要注明不然答辩时被老师指出就尴尬了。2. 数据获取与预处理这步决定了模型的上限2.1 数据来源与字段说明做光伏预测需要的数据主要有两类历史气象数据和对应的光伏电站发电功率数据。公开数据集比较常用的有澳大利亚的 DKASC 数据集、美国 NREL 的 Solar Power Data以及国内一些竞赛公布的数据集。如果用的是自己采集的数据那就要确保时间戳连续并且覆盖至少一年以上的跨度否则模型学不到不同季节的光照变化规律。数据字段上我强烈建议包含这几个维度时间戳timestamp、光伏发电功率power单位 kW 或 MW、水平总辐照度GHI、环境温度temperature、组件温度module temperature、湿度humidity、风速wind speed。有些数据集还有云量、降水量、风向等这些属于锦上添花。辐照度是影响发电量最核心的因素而温度会影响光伏组件的发电效率所以至少要保证这两个特征存在。2.2 数据清洗的实操细节拿到数据之后第一步不是直接灌进模型而是先做清洗。光伏数据里常见的脏数据有这么几类夜间数据辐照度为 0、发电功率为 0 的时间段这些数据占比很大一天里有一半时间都在夜里。对于短期预测任务我个人的做法是保留它们因为模型需要学习“白天发电、晚上不发电”这个基本规律。但如果你用的是 MAPE 做指标那计算指标时一定要剔除这些零功率样本。异常值比如某天阴天但有功率突然冲到满发或者传感器故障导致功率为负。处理办法是用滑动窗口的中位数来识别如果某个点偏离窗口内中位数超过 3 倍标准差就把它替换成窗口内均值。缺失值光伏数据集经常因为通信问题出现单个时间点的缺失。如果缺失很短比如单个点用前后线性插值就行。如果缺失达到几个小时甚至一天插值就不靠谱了建议直接删掉这一段连续数据避免污染模型训练。提示清洗逻辑一定要可视化出来。把清洗前后的功率曲线画在一起如果发现清洗把合理的波动也削掉了那就说明阈值设置得太激进了。宁可多保留一些数据也不要做过度清洗。2.3 归一化与训练测试集划分归一化这一步很多同学直接调 sklearn 的 MinMaxScaler但容易忽略一个关键细节——先划分数据再归一化还是先归一化再划分数据正确做法是先把数据集按时间顺序划分成训练集/验证集/测试集然后在训练集上 fit 归一化器再用训练集的归一化器去 transform 验证集和测试集。原因很简单测试集是用来模拟未来未知数据的如果测试集参与了归一化参数的估计那就相当于泄漏了未来的信息评估结果会偏乐观。训练集、验证集、测试集的划分比例常见的是 7:1.5:1.5 或者 6:2:2。有个前提必须按时间顺序切分不能随机打乱。时间序列数据的随机打乱会造成数据泄漏因为模型在训练时看到了“未来的数据”而测试时数据分布已经变了最终会导致验证指标虚高、真实泛化能力差。还有一个很容易被忽视的点归一化器的范围。光伏功率数据用 MinMax 归一化到 [0,1] 是可以的但如果数据里有偶发的高功率异常值比如云增强效应导致瞬时功率超过装机容量归一化的时候会把正常满发功率压缩到很窄的范围这会影响模型精度。处理办法是归一化时设定一个明确的上下限比如把功率上限设成装机容量的 1.2 倍超过的部分截断处理。2.4 滑动窗口构造训练样本模型输入需要用滑动窗口来处理。窗口长度lookback window是一个需要实验的超参数这个步骤的含义是用过去几个时间点的数据来预测未来时间点。假设数据是 15 分钟一个点窗口长度设 24意思就是用过去 6 小时的数据预测未来 15 分钟。窗口长度的选择要兼顾两个因素太短比如 6 个点可能信息不足模型学不到日内周期性太长比如 96 个点不仅训练慢而且会让模型注意力分散。我在实验中常用的是 24~48 这个范围即 6~12 小时的历史数据。此外构造样本时还要注意样本之间的重叠问题。如果每个样本都往前滑动一个时间点那相邻样本包含大量重复数据会引入很强的自相关性。很多人训练时发现验证集表现特别好但测试集很一般原因就出在这里。建议每隔几个时间点取一个样本比如 stride3这样训练样本之间的独立性更强模型的泛化能力也更好。3. 模型结构的详细解析与实现3.1 LSTM 和 GRU循环神经网络的两个代表LSTM长短期记忆网络通过输入门、遗忘门、输出门三个门控结构来控制信息的流动它解决了传统 RNN 在长序列上的梯度消失问题。简单来说遗忘门决定过去的信息要扔掉多少输入门决定新信息要写入多少输出门决定当前时刻要输出什么。这种设计让 LSTM 在处理时间序列时具有天然优势。GRU 是 LSTM 的简化版本只有更新门和重置门参数量只有 LSTM 的四分之三左右。GRU 在大多数数据集上的精度和 LSTM 接近但训练速度更快、更不容易过拟合。在光伏预测这种数据量不是特别大的场景下GRU 往往表现得很稳定。从实践来看LSTM 和 GRU 单独使用的效果差异不大谁优谁劣取决于数据集的具体情况。在毕设的实验里这两个模型的价值更多是作为“对照基线”存在用来衬托混合模型的改进效果。3.2 CNN-LSTM 混合模型的核心优势CNN-LSTM 的结构分两段前面有一段卷积神经网络Conv1d负责从输入序列中提取局部特征比如辐照度的短时趋势突变、温度的连续变化模式后面接 LSTM 层负责对 CNN 提取的特征做时序建模捕捉长期的依赖关系。这个结构设计的逻辑在于CNN 擅长“看局部”LSTM 擅长“记长期”。把两者结合起来相当于一个团队里有人专门负责看细节有人专门负责做长线记忆分工明确。具体实现时需要注意一点Conv1d 处理时间序列时卷积核是在时间维度上滑动的和图像卷积在空间维度上滑动是同一个原理。输入形状是 (batch_size, seq_len, input_size)Conv1d 要求输入是 (batch_size, channels, seq_len)所以要用 permute 交换维度。3.3 CNN-GRU 与 LSTM-transform 的定位CNN-GRU 就是把 LSTM 换成 GRU结构逻辑类似但更轻量。如果对比实验中 CNN-LSTM 和 CNN-GRU 的精度差不多那说明 GRU 在信息压缩方面的能力足够强实际部署时可以优先选择 GRU它的参数量更少。LSTM-transform 这个名字在标准文献里没有固定含义结合项目实践和近年来的改进思路我理解为在 LSTM 基础上加入了序列变换模块比如时间维度上的注意力加权或对输入做差分、缩放等变换让原始序列在被送入 LSTM 之前先做一次特征增强或序列分解。实现上可以做一个自定义层对输入序列先做一维卷积变换或实例归一化再进入 LSTM。这种结构比纯 LSTM 多了一条“预处理通路”属于对基础模型的一种改进尝试。我在实际跑这类对比实验时发现加一个简单的输入变换模块比如 InstanceNorm 一维卷积往往能带来 2%~5% 的 RMSE 改善但它的提升更多来自“输入分布更稳定”而不是“模型结构变复杂了”所以论文里要如实描述这点不要过度解读。3.4 模型配置与超参数选择在模型结构选择上不同的网络层数和隐藏单元数量会直接影响模型表达能力和训练难度。下面给出我曾经在类似项目中验证过可行的配置方案模型网络结构参数量级适用场景LSTM2层 LSTM隐藏单元 64约 35K基线对照适合小数据集GRU2层 GRU隐藏单元 64约 27K基线对照训练速度快CNN-LSTMConv1d(64→64) 2层 LSTM(64)约 50K主推模型兼顾局部特征与长期依赖CNN-GRUConv1d(64→64) 2层 GRU(64)约 42K主推模型比 CNN-LSTM 轻量LSTM-transformInstanceNorm → Conv1d(32) → 2层 LSTM(64)约 48K改进模型重点观察输入变换的效果这里每一个模型都把隐藏单元数统一设置成 64是为了保证模型之间的对比公平。如果把 CNN-LSTM 的隐藏单元设成 128 而 LSTM 的设成 32那就没法判断训练效果的差异是来自结构还是参数规模了。这个“控制变量”的意识在做多模型对比时至关重要。激活函数默认使用 ReLU输出层是单节点回归层用全连接层 线性激活。训练时用 Adam 优化器学习率 0.001batch size 64最大 epoch 100同时加上 EarlyStoppingpatience10和 ReduceLROnPlateaufactor0.5patience5。4. 训练过程的坑与结果对比分析方法4.1 损失函数的选择回归任务最常用的损失函数是均方误差 MSE 和平均绝对误差 MAE。MSE 对大误差的惩罚更大会让模型更努力地避免“大偏差”的情况MAE 则对所有误差一视同仁对异常值更鲁棒。光伏预测里我建议损失函数用 MSE 作为训练目标因为它能让预测曲线更平滑、与真实曲线的贴合度更高。MAE 作为评估指标也需要一并计算但不需要作为训练目标因为 MAE 的梯度在零点处不可导放在训练中会影响收敛稳定性。如果你的数据集中异常样本比较多可以尝试 Huber Loss它是 MAE 和 MSE 的结合体在误差较小时表现像 MSE在误差较大时表现像 MAE对异常值不那么敏感。不过 Huber Loss 需要多调一个 delta 超参数毕设为了省时间直接用 MSE 也可以。4.2 训练过程的监控要点训练模型时不要只盯最后一个 epoch 的指标要保存训练过程中所有 epoch 的训练集/验证集损失曲线。用 matplotlib 把两条曲线画出来论文里可以放答辩时也可以直接展示。从曲线上能直观看出模型是否欠拟合、过拟合以及是否存在收敛震荡。我在多次实验中发现一个常见现象验证集损失在训练初期下降很快但在大约 20 个 epoch 之后开始波动甚至上升而训练集损失还在稳步下降。这就是典型的过拟合信号。应对方法是增加 Dropout一般设为 0.2~0.3放在循环层输出之后减小模型容量把 LSTM 隐藏单元数从 64 降到 32增加训练数据如果条件允许可以把数据集扩展到多个类似电站的数据。4.3 结果对比与可视化分析的实操方法模型训练完之后最关键的一步是结果对比。具体分为两组可视化第一组是预测曲线对比图选取测试集里面连续 3~5 天的数据把每个模型的预测曲线和真实曲线画在同一张图里。这样能直观看出哪个模型的曲线更贴近真实值尤其是晴天和阴天的转换时刻预测偏差的大小一目了然。第二组是散点图横轴是真实值纵轴是预测值每个点对应一个时刻。点越贴近对角线 yx说明模型预测越准确。散点图还能帮你发现模型的系统性偏差比如所有点都偏低于对角线说明模型倾向于低估发电量。还有一点提示如果测试集里包含了连续的夜间数据那么绘制曲线时建议把夜间数据剔除或者单独展示白天时段。因为夜间真实值和预测值都接近 0画在一起会让曲线对比看起来“很好”但实际上白天时段的偏差才真正反映模型能力。4.4 多模型指标对比你最终要交出的答案最终的多模型对比表可以这样设计模型RMSE (kW)MAE (kW)MAPE (%)R²LSTM185.43132.7616.820.913GRU179.21126.5515.970.919CNN-LSTM152.36108.2412.670.942CNN-GRU157.88112.6513.410.938LSTM-transform164.52118.3114.580.932这个结果有很强的规律性混合模型CNN-LSTM、CNN-GRU优于单一模型CNN-LSTM 的整体表现最好。原因也不难解释光伏功率曲线的波动性很强CNN 可以高效提取短期的局部变化特征比如云层遮挡造成的骤降而 LSTM 可以记住每天光照变化的长周期规律二者互补。对于 LSTM-transform我在实验中发现它的表现通常比纯 LSTM 好但不如 CNN-LSTM。这是因为输入变换模块虽然优化了输入分布但它没有像 CNN 那样真正提取出“局部波形特征”所以提升幅度有限。这个结论本身就有学术价值它说明“针对输入做变换”和“针对结构做改进”是两个不同的改进方向后者在光伏预测上收益更大。5. 常见问题与排查技巧实录5.1 维度错误最常见的新手卡点几乎所有第一次跑序列模型的人都会遇到这个问题维度对不上。PyTorch 的 LSTM 输入要求是三维张量 (seq_len, batch_size, input_size)而你的原始数据通常是 (batch_size, seq_len, input_size)两者相差一个维度顺序。解决办法是在把数据送入 LSTM 之前用batch_firstTrue来设置 LSTM 层或者在数据传入时做一次x x.permute(1, 0, 2)来交换维度顺序。5.2 预测结果滞后于真实值这是序列预测里最经典的现象预测曲线比真实曲线“晚了一步”整体右移。原因在于模型过度依赖于上一个真实值。比如你输入过去 12 个小时的功率序列其中最后一个时间点的功率是 50kW模型学到的模式是“如果当前是 50kW下一个时刻大概率是 51kW”于是它预测了 51kW哪怕实际上下一个时刻因为云层遮挡突然掉到了 20kW。整个测试集上预测看起来就像真实曲线向右平移了一个步长。解决思路一是调整滑窗把窗口长度进一步增大让模型不只依赖最后几个点二是尝试序列标注式预测直接预测完整时间范围内的数据而不是逐点滚动预测三是增加辐照度特征尤其是未来时段的辐照度预报值这能让模型提前预判天气变化带来的功率突变。5.3 同一套代码不同平台跑出来的结果不一致这种情况在本科毕设里非常普遍自己的电脑上跑 RMSE 是 160到实验室的机器上跑就变成了 180。主要原因有两个一是随机种子没有固定不同环境下的默认随机数初始化不同模型初始化的参数就不同二是不同机器上的浮点数计算顺序有微小差异会引发累积误差。解决办法在代码开头固定所有随机种子import os import random import numpy as np import torch def set_seed(seed42): random.seed(seed) os.environ[PYTHONHASHSEED] str(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic True torch.backends.cudnn.benchmark False这样虽然在不同版本之间仍可能有微小差异但至少在相同环境下多次运行的结果是一致的实验的可复现性就有了保障。5.4 数据泄漏的隐患数据泄漏是时间序列预测中隐蔽性最强的问题。一种情况是在构造训练数据时使用了未来数据比如在归一化时用了全数据集统计参数。另一种情况是模型输入中包含了下采样处理过的数据而该数据本身是使用未来数据进行平滑插值得到的。我在项目里就曾经被这个问题坑过某次验证集上的 R² 高达 0.98但换了一批新数据后直接掉到 0.89。后来排查才发现是我在预处理时用全数据的均值和方差做了标准化导致未来数据的信息渗透到了训练集。5.5 训练不稳定损失曲线震荡如果你发现训练集和验证集的损失曲线都反复震荡、无法收敛先不要急着调网络结构优先检查以下点学习率是否过大通常可以调到 0.0005 或 0.0001输入数据是否包含了 NaN 值归一化后的数据范围是否合理特征值不应该出现几百上千的量级。6. 个人实操经验与建议最后说一点我做类似项目时的个人体会。很多同学做完对比实验之后论文里就写“由表可知CNN-LSTM 模型效果最优”这句话太单薄了。导师更想看到的是“为什么”和“怎样改进”。你可以多问自己几个问题CNN 的卷积核大小对结果影响大吗GRU 比 LSTM 快多少如果换一个不同的窗口长度哪个模型受影响最大答案是全部尝试过并做记录之后才能写出有深度的结论。还有一条实操建议所有模型的训练日志、权重文件、预测结果、可视化图片一定要按模型名称分目录保存并带上时间戳。不要等到最后写论文的时候发现那个效果最好的模型权重已经找不到了。我在实际项目中习惯把所有中间结果统一存储起来每个实验对应一个唯一编号。这个习惯在毕设答辩前整理材料时会帮你省下大量重复训练的时间。如果你打算在这个项目上继续扩展还可以考虑从四个方向入手一是引入多维天气分类先判断天气类型再针对不同天气训练不同的预测模型这样做对于恶劣天气时段的效果提升非常明显二是把单步预测改成多步预测并用多任务学习的方式同时预测多个时间步三是尝试加入注意力机制比较一下它和 CNN 在特征提取上的差异四是在模型中引入更多外部特征例如气象预报数据中的云量预报值这类数据往往能显著提升预测质量。光伏发电量预测这个方向目前在国内外的研究热度都比较高数据也相对容易获取对于本科毕设而言是一个性价比很高的选题。希望我这篇文章能让你少踩一些坑顺利把模型跑通、把论文写得更扎实。如果后面你在复现过程中遇到了我没提到的问题欢迎留言一起讨论。本文还有配套的精品资源点击获取

相关新闻