基于LSTM+CNN的光伏发电功率预测系统实战解析 简介本资源是一套面向高校毕业设计与新能源方向科研实践的光伏发电功率预测系统完整实现基于CNN-BiLSTM-Attention混合深度学习架构解决光伏出力波动性强、短期预测精度低等实际工程问题适用于电力系统、智能微网及AI能源交叉领域的本科生与研究生项目开发。压缩包共106个文件含30个实测CSV数据集含多电站气象与功率序列、25个预训练pkl模型与特征处理器、9个h5模型权重、7个核心Python训练与Web服务脚本以及HTML/CSS/JS构成的可视化前端和SQL数据库脚本整体大小为90.64MB。目前已有45人学习下载。用户可直接部署运行获得带用户管理、异常报警、日历视图与收益分析的全功能Web预测平台配套文档详述数据预处理逻辑、注意力机制实现细节及孤立森林异常检测集成方法并提供.bat与.sh双环境启动脚本显著降低复现门槛。1. 项目拆解这套光伏发电功率预测系统到底解决了什么问题1.1 为什么光伏功率预测这么难做光伏发电的核心痛点就是看天吃饭。云飘过来发电曲线立刻往下掉云散了又瞬间拉满。电网调度最怕的就是这种波动所以功率预测是光伏电站并网、储能调度、电力交易的基础设施级需求。这套系统本质上解决的是一个时间序列回归问题给定过去一段时间的功率、气象等观测数据预测未来某个时间段的光伏发电功率。但难点在于光伏功率不仅受时间规律影响白天有电、晚上为零、中午峰值还受气象因素强烈干扰而气象过程又是非线性、非平稳的。单靠传统线性模型比如ARIMA或者单一神经网络很难同时吃下这两类特征。这套项目里给到的LSTMCNN混合架构属于目前深度学习做时序预测的主流思路之一。它的逻辑很直接让CNN负责提取气象特征和功率数据之间的局部关联模式让LSTM负责捕捉时间维度上的长短期依赖。我用下来最大的感受是相比单一LSTM模型混合架构在突变天气下的预测稳定性会好很多比如多云转晴、阵雨前后这种功率剧烈变化的时段混合架构的误差明显更小。1.2 这套源码包里的东西值不值得折腾先说结论如果你正在做新能源方向的课题、毕业设计或者公司里刚好需要一个可落地的光伏功率预测基线baseline系统这套资料能省你大半个月时间。它包含完整源码、文档说明、历史发电数据和一套已经调通的训练流程不是一个只有demo的半成品。我拿到资料后的第一反应是看目录结构大致分成了这几个核心模块数据预处理原始数据整理、缺失值填充、归一化逻辑模型定义CNN特征提取层 LSTM时序层的完整代码训练脚本模型训练、验证、早停、学习率调度预测与评估基于测试集的功率预测和误差指标计算文档说明环境配置、参数说明、复现步骤这里要特别夸一下数据处理部分。很多开源项目坏就坏在数据是不可复现的但这份资料里给的数据集已经做了初步清洗像是夜间零值时段、传感器故障导致的毛刺都被处理过。对于新手来说你不需要先从爬数据、洗数据开始学起可以直接跑通模型再回头逐步深入每个环节学习曲线友好很多。如果你已经有深度学习基础这套项目的价值在于它的工程完整性——环境怎么配、数据怎么喂给模型、训练时怎么保存最优权重、预测结果怎么反归一化这些细节都做了交代。老实说我见过不少同学模型调得很好结果在部署时发现数据预处理和预测流程之间没有做好同步导致线上结果完全不对。这套项目在这些细节上做得还算规范。2. 数据是预测的地基数据集构成与预处理经验2.1 光伏数据都有哪些关键字段做光伏功率预测数据质量决定模型上限。这套项目提供的数据集虽然已经清洗过但要想真正用好它你得先搞清楚每一个字段是干什么的。从常见的光伏电站采集系统来看核心字段一般包括这几类功率字段逆变器有功功率单位通常是kW或MW这是我们要预测的目标变量辐照度字段水平面总辐射GHI、斜面辐射POA这是影响发电量的第一要素气象字段环境温度、组件温度、湿度、风速、风向、气压时间字段记录间隔这套项目里用的是15分钟一个点有一点需要特别留意辐照度和功率之间的相关系数通常能到0.9以上但如果数据集里没有辐照度字段模型就只能退化成纯时间序列模型预测精度会大幅下降。这套项目里是包含辐照度数据的所以我建议你在跑通之后可以试着把辐照度字段从特征里去掉看看模型跌了多少这个对比实验能帮你直观理解特征的重要性。2.2 数据清洗是看不见但最重要的步骤我在跑这套源码的时候专门去看了一下它的数据预处理脚本发现几个处理逻辑做得很下功夫也刚好是很多新人最容易踩坑的地方。**第一夜间零值时段的处理。**光伏电站夜里功率恒为零白天才有波动。如果直接把全天24小时的数据喂给模型模型会花大量精力去学习晚上等于零反而削弱对白天功率峰值的预测能力。之前的做法是把夜间数据过滤掉只保留日出到日落时段。这么做还有额外的好处训练数据里正负样本的分布更均衡损失函数的梯度更新方向更集中在有效区间。**第二缺失值和异常值的填充。**光伏电站的传感器经常出故障比如辐照度计被鸟粪遮住产生持续偏低值、通信中断导致整段数据缺失。项目脚本里用的是前向填充滑动窗口平均值修复的组合方式。具体来说对于小于一定阈值的缺失片段用前值填充对明显偏离正常范围的野值用前后有效窗口的均值替代。这种做法在工程上是稳妥的因为你用插值模型去填充大段缺失反而可能引入虚假模式。**第三归一化是必须的。**光伏功率的量纲、辐照度的量纲、温度的量纲完全不同如果不做归一化数值范围大的特征会主导梯度更新。这套项目采用的是Min-Max归一化把所有特征缩放到[0,1]区间。我试过换成Z-Score标准化整体效果差异不大但Min-Max的好处是反归一化时更方便——预测结果直接乘回max - min min就行不用额外保存均值和方差。注意做归一化时必须在训练集上拟合scaler再用同一套scaler参数去转换验证集和测试集。如果你直接把全量数据一起做归一化会发生数据泄露data leakage模型评估指标会虚高真实场景表现打折扣。3. 模型核心拆解LSTM和CNN到底在各自做什么3.1 用CNN提取局部特征为什么不用RNN一条路走到黑很多第一次接触这个项目的人会问预测功率直接用LSTM不就行了吗为什么还要额外加CNN这个问题的答案要从训练效率说起。LSTM本质上是串行处理时序数据每一步的输出都依赖上一步的隐状态计算效率偏低。而CNN是卷积操作可以并行计算运算速度比LSTM快得多。更重要的是CNN擅长捕捉输入数据中的局部模式——比如辐照度在连续几个时间点内快速上升往往对应着云层正在散去、功率即将拉升。这种短时间内多变量联合变化的局部特征用卷积核一滑就提取出来了。这套项目里CNN部分采用的是1D-CNN也就是一维卷积。它不是在图像上做二维卷积而是把时间步当作图像的宽度每个特征列当作图像的通道沿着时间方向滑窗提取特征。一个直观的理解方式假设输入是过去24个时间点对应6小时的8个特征1D-CNN用若干个卷积核在这24个时间步上滑动每个卷积核学会识别一种局部形态比如辐照度跳变功率上升配合模式输出的特征图再交给LSTM。这就相当于先让CNN做一次特征筛选LSTM只需要在更高层次的特征上建模时间依赖学起来轻松很多。我在实际项目里试过把CNN部分去掉、只用纯LSTM训练收敛速度明显变慢而且在晴天转多云这种模式下预测曲线会滞后真实曲线一到两个时间步。CNN可以理解成给LSTM加了一个特征预览能力让模型提前感知到输入序列中的突变信号。3.2 LSTM在光伏预测里负责记规律和记教训LSTM的核心结构有三个门遗忘门、输入门、输出门。它的记忆机制很适合光伏功率这类数据——既需要记住长期规律比如夏季晴天中午功率通常会达到峰值又需要根据最新的输入动态调整判断比如刚刚检测到云层增厚就要把预测值调低。在这套项目的具体实现里LSTM层的输入是CNN提取出的特征序列经过两层堆叠的LSTMhidden size设为64后把最后一个时间步的隐状态接一个全连接层输出未来一个或多个时间点的预测功率。这里有个细节值得注意项目默认的预测任务是单步预测也就是用过去6小时数据预测未来15分钟的功率。如果你想预测未来1小时或者更长时间有两种常见的扩展方式递归预测recursive把上一步的预测结果当作下一步的输入逐步推出多步缺点是有误差累积多输出策略multi-output直接把全连接层的输出维度设为待预测步数一步到位输出整段预测曲线我在项目源码里看到它用了第二种方式直接定义fc nn.Linear(hidden_size, pre_len)其中pre_len是预测步长。这样在训练时能同时优化多个时间点的损失比递归预测稳定得多。你拿到代码后可以尝试把pre_len从1改成4看看预测未来1小时4个15分钟点的效果这个实验做起来非常直观。3.3 混合架构的核心代码逐行拆解项目的模型定义部分在model.py文件里我把它的大致结构整理成伪代码来讲解import torch.nn as nn class CNNLSTMModel(nn.Module): def __init__(self, input_dim, hidden_dim64, num_layers2, pre_len1): super().__init__() # CNN特征提取层 self.conv1 nn.Conv1d(in_channelsinput_dim, out_channels32, kernel_size3, padding1) self.relu nn.ReLU() self.conv2 nn.Conv1d(in_channels32, out_channels64, kernel_size3, padding1) self.pool nn.MaxPool1d(kernel_size2) # LSTM时序建模层 self.lstm nn.LSTM(input_size64, hidden_sizehidden_dim, num_layersnum_layers, batch_firstTrue) # 回归输出层 self.fc nn.Linear(hidden_dim, pre_len) def forward(self, x): # x shape: (batch, seq_len, input_dim) x x.permute(0, 2, 1) # 转为(batch, input_dim, seq_len)适配Conv1d x self.relu(self.conv1(x)) x self.relu(self.conv2(x)) x self.pool(x) # 时间维度减半 x x.permute(0, 2, 1) # 转回(batch, seq_len, channels) lstm_out, _ self.lstm(x) out self.fc(lstm_out[:, -1, :]) # 取最后一个时间步的隐状态 return out关键点在于Conv1d的输入格式要求是(batch, channels, seq_len)所以需要用permute把维度和LSTM要求的(batch, seq_len, input_size)区别开。我刚开始写混合模型时经常在这里搞混报错expected 3D input基本都是维度顺序不对。这里加了卷积核size为3的1D卷积padding设为1来保持时间长度不变然后通过MaxPool把时间步减半相当于让LSTM在更粗粒度的时间尺度上建模。4. 从数据到预测完整的运行流程和源码使用指南4.1 环境配置和依赖安装照着做就不会出问题这套项目的源码基于Python和PyTorch实现我在本地Windows和Linux服务器上分别跑通过依赖清单大致如下Python 3.8及以上版本PyTorch 1.10及以上版本CPU版就能跑通小数据集但训练速度慢建议装CUDA版NumPy、Pandas用于数据处理Matplotlib用于结果可视化Scikit-learn用于指标计算在项目根目录下执行pip install -r requirements.txt就能一键装完所有依赖。如果你在安装PyTorch时遇到网络问题建议直接到PyTorch官网按操作系统和CUDA版本生成对应的安装命令比直接用默认源可靠。配置好环境之后你可以先跑一下python train.py。如果一切正常终端会打印出当前epoch的loss训练结束后会在checkpoints/目录下生成模型权重文件。到这里整个链路就算通了。4.2 训练阶段的核心参数改哪个影响最大训练脚本train.py里默认的配置如下回溯窗口look_back96个时间点对应一天15分钟一个点预测步长pre_len1个时间点对应未来15分钟训练轮数epochs100带early stopping批大小batch_size64初始学习率0.001使用ReduceLROnPlateau调度我在调参时发现影响预测效果最大的是回溯窗口和特征组合而不是网络结构的隐层维度。回溯窗口设太短比如24个点模型看不到前一天的功率趋势多云天气预测偏差很大设太长比如144个点数据维度太高训练时间增加但效果提升不明显。项目默认的96个点是个不错的起点你可以手动改成48和144画loss对比曲线直观感受窗口长度的影响。另一个高频调参项是学习率。0.001在Adam优化器下一般没问题但如果loss曲线在初期就震荡得很厉害可以先降到0.0003试试。训练脚本里还加了一个很实用的early stopping机制——连续10个epoch验证集loss没有下降就停止训练并恢复最优权重。这个机制救过我好多次防止训练后期过拟合。4.3 预测结果的可视化别只盯着loss曲线predict.py脚本会调用训练好的模型对测试集进行预测并把预测值和真实值画在同一条时间轴上。我建议你把可视化图当作判断模型好坏的第一手工具因为误差指标只给一个数而曲线图能告诉你误差集中在哪些时段。从之前的实测来看常见的可视化输出效果如下晴天时段预测曲线贴合度很高误差基本在可接受范围内但傍晚时段特别是日落前后预测值和真实值会出现明显偏离因为这段时间辐照度变化剧烈且持续时间短模型输出的数值波动容易比真实值更大。这属于正常现象不必太纠结。画图时建议把时间轴设为横轴同一张图上画两条曲线真实功率label和预测功率pred。如果两条曲线走向一致但存在整体偏移那大概率是数据归一化时没有对齐如果只是某些尖峰时刻对不上那是模型学习不够需要调参或加数据。5. 评估指标怎么选别被单一的RMSE骗了5.1 不同场景下的指标关注重点模型训练完你得知道它到底好不好。这套项目里计算了三个常见指标均方根误差RMSE、平均绝对误差MAE和决定系数R²。RMSE对大误差更敏感适合衡量预测是否出现极端偏差MAE反映平均偏差水平更直观R²反映模型对真实功率波动的解释能力最大为1越接近1越好以真实项目经验来看R²在晴天工况下通常能到0.95以上但在多云或阴雨天下会降到0.7甚至更低。所以评估模型时建议分天气状况评估别只给一个总体的R²。我之前有台测试机跑了一个模型总R²0.92看着还可以。但分开看晴天0.97、阴天0.55说明模型在阴天基本瞎猜。如果有评估粒度更细的数据你可以按天气聚合评估定位模型短板然后针对性地在训练集里增加弱势天气样本。5.2 数据划分的正确姿势项目默认采用时间序列切分法来划分训练集、验证集和测试集确保时序顺序不被打乱。这一点很重要——如果像普通分类任务那样随机打乱数据模型会偷看到未来信息评估结果虚高。我建议的划分比例是训练集70%验证集15%测试集15%。注意验证集和测试集要选取连续时间段不要随机抽取才能真实反映模型在未来未知数据上的表现。重要提醒训练集和测试集在时间上必须没有重叠。比如你有2024年3月到6月的数据前70%做训练后30%做验证和测试。如果你把某几天的数据随机抽出来做验证模型已经见过相邻时刻的功率值预测自然会很准但这在真实部署中根本不可能发生。6. 常见问题与排查技巧跑这套代码最容易踩的坑6.1 训练loss不下降可能卡在哪如果你跑起来发现loss在几个epoch内都没有明显下降别急着调模型结构先按顺序排查这几件事确认输入数据是否归一化。如果功率原始数值是几千千瓦的量级直接喂给模型损失数值会巨大且下降缓慢。项目代码里有归一化步骤但如果你自己改了数据加载逻辑很容易漏掉这一步。检查学习率是否过小。0.001不行就试0.01但0.01可能直接loss炸掉多试几个值。建议设一组等比序列实验0.1、0.01、0.001、0.0001。确认标签target是否对应正确的时间步。我在处理滑动窗口数据时踩过一次坑——窗口不重叠还好一旦重叠容易把预测目标生成错位模型学到的是把上一时刻的值复制过来。模型是否在反传时梯度正常。打印一下每一层参数的梯度范数p.grad.norm()如果接近0可能是梯度消失如果到处是NaN可能是数据里有inf。6.2 预测曲线比真实曲线滞后一拍这是时序预测里最常见的现象通常意味着模型没有真正学到因果关系只是在复读上一个值。解决办法有几个增大回溯窗口让模型看到更长的历史趋势而不是只依赖最近几个点引入外生特征特别是当前时刻的辐照度。如果输入特征里没有辐照度模型等于在盲猜天气滞后问题几乎必然会存在用CNN提取特征后再进LSTM让模型先捕捉到辐照度变化的局部信号再结合历史功率做判断我最早用纯LSTM跑的时候滞后问题非常明显换了LSTMCNN混合架构后大幅改善。CNN卷积核能捕捉到辐照度在未来几分钟内会上升的局部趋势这个信息编码进特征序列后LSTM在输出时就能提前一步做出反应。6.3 引入未来时刻数据导致数据泄露这是另一个隐藏很深的问题。有些同学在特征构造时不小心把预测目标时间点的数据也加进了输入。比如要预测t1时刻的功率却把t1时刻的温度当作特征传了进来。这在测试时可能看不出来因为你有完整的历史数据但一旦部署上线t1时刻的温度压根还没测到模型就直接废了。所以你在构造特征时一定要严格要求输入特征里所有变量的最大时间戳必须早于预测目标的最小时间戳。6.4 模型在测试集上效果好但部署后效果差项目跑通了不代表结束从离线评估到线上运行还有一段路要走。最常见的问题是线上环境的数据格式跟训练时不统一比如训练时用的光伏电站A的数据部署到了光伏电站B电站B的装机容量、传感器布局都不同直接套用原模型必然失效。如果要做跨电站迁移一个低成本方案是用少量新电站数据微调fine-tune。冻结CNN层和LSTM层的权重只训练最后一层全连接层几十个epoch很快就能适配新电站的数据分布。我在自己的项目里试过用1周数据微调后R²能从0.3直接拉回0.85以上。7. 从这套源码出发项目还能怎么扩展跑通这套系统只是第一步。如果你有时间有精力以下几个扩展方向非常值得尝试也是实际工程里需求量最大的优化点。第一把单步预测扩展为多步预测。电网调度通常需要未来4小时甚至24小时的预测曲线建议项目在pre_len上做多步输出实验。需要提醒的是预测步长拉长后误差会快速积累建议采用多模型接力策略一个模型预测未来1小时另一个模型预测未来1到4小时而不是用一个模型从头预测到尾。第二引入天气类型作为上下文特征。光伏功率对天气类型极为敏感。如果有历史天气预报数据可以把天气类型晴、多云、雨编码为离散特征与气象数据一起拼接后输入模型。这能显著提升突变天气下的预测精度。第三尝试注意力机制。LSTMCNN的下一个升级方向通常是加注意力Attention。注意力机制可以让模型自己学习当前预测最应该关注历史哪个时间步比如阴天突然转晴时模型应该更关注几小时前某个类似的晴好时段。项目整体架构不变只需要在LSTM输出后接一个注意力层就能观察到效果提升。第四把代码服务化。项目目前是离线训练和预测脚本。如果你要把它部署成实时预测服务建议用Flask或FastAPI封装一个HTTP接口接收实时气象数据返回预测功率。再配合一个定时调度任务比如每天凌晨用最新数据重新训练一次就是一个完整的工程化方案。8. 写在最后的实操建议这套项目给我的整体感觉是小而完整——数据、模型、训练、评估都能闭环而且留了很多可以动手改的扩展点。我建议你的学习路径是这样的先把训练流程完整跑一遍再逐行读懂模型定义和数据处理脚本然后才开始动调参和改架构。不要一上来就追求最新SOTA模型混合模型在这类任务里其实已经够用关键是每一步都要理解为什么这么做。如果你在运行中遇到任何报错优先检查数据维度和归一化这两个环节90%的问题都出在这里。祝你在光伏预测这个方向玩得顺手。本文还有配套的精品资源点击获取