ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CNN-LSTM-Attention光伏功率预测Matlab实现:多变量多步时序建模与评估

CNN-LSTM-Attention光伏功率预测Matlab实现:多变量多步时序建模与评估 简介这份资源提供基于CNN-LSTM-Attention的Matlab完整源码与数据面向光伏功率多变量多步预测场景适合计算机、电子信息、数学等专业学生用于课程设计、期末大作业或毕业设计。方法融合卷积神经网络特征提取、长短期记忆网络时序建模与注意力机制加权可有效捕捉发电功率的复杂动态变化输出预测图、误差图及R2、MAE、MAPE、MSE、RMSE等评价指标。压缩包共7个文件包括2个.m主程序与计算脚本、2张结果示意图、1个.mat数据文件、1份Excel光伏历史数据及1个说明文档整体仅2.46MB结构简洁便于快速运行和二次开发。代码采用参数化编程参数易改注释清晰逻辑明了说明文档还特别指出真实发电功率含0时MAPE会无穷大使用时跳过该指标即可。目前已有175人学习下载可用于光伏功率预测课题的算法验证与毕设参考也可在此基础上扩展至其他时序多步预测任务。1. 光伏功率预测为什么绕不开 CNN-LSTM-Attention光伏功率预测这个任务最容易踩的坑不是模型不收敛而是把预测结果交出去之后对方只看未来三小时到底能出多少电。气团移动、云层遮挡带来的分钟级波动加上温度湿度对组件效率的影响让这个问题的输入天然就是多变量的输出天然就是多步的。CNN-LSTM-Attention 是这类任务里值得最先跑通的结构卷积提局部突变LSTM 抓持续趋势Attention 决定哪些历史时刻对下一个预测点最有用。这套 Matlab 工程把三者封装成可直接运行的源码带 2019 年全年光伏数据、训练好的模型文件和使用说明运行在 Matlab R2023b 及以上。适合课程设计、期末大作业也适合想拿一套可复现基线的工程人员。2. 多变量多步预测的结构设计输入张量、滑窗与注意力加权2.1 CNN、LSTM、Attention 在光伏序列里各干什么光伏功率序列有几个显著特征。第一辐照度突变是局部事件出现在相邻的几个采样点内。第二功率曲线有日内周期性上午爬升、午后回落周期尺度远大于卷积核尺寸。第三不同时刻对未来预测的贡献不同预测 15:00 的功率时14:45 的功率比 10:00 的功率信息量大得多。Conv1D 解决第一点。一维卷积核沿时间轴滑动感受野只有几个采样点专门提取「辐照度骤降」「功率跳变」这类局部模式。卷积核参数共享不会因为模式出现在不同时刻而需要重复学习。光伏数据里这种局部模式高度重复卷积层用 16 到 64 个卷积核就够。LSTM 解决第二点。门控结构让网络能把数十个时间步之前的状态保留下来适合建模日内周期和缓慢变化的环境温度趋势。在超短期光伏功率预测里LSTM 隐状态设 64128 维基本能覆盖 1 小时到 3 小时的依赖长度。Attention 解决第三点。它作用在 LSTM 的输出序列上不是加在特征维度上。LSTM 每个时间步输出一个隐向量 h_iAttention 打分函数给每个时间步一个权重最后加权求和得到上下文向量score_i w^T · tanh(W_i · h_i b)alpha_i softmax(score_i)context sum(alpha_i · h_i)网络在输出时刻会「盯着」最近的几个时间步而不是把 12 个历史时刻的信息平均掉。这就是 Attention 层在多变量时序预测中与 LSTM 搭配时的核心语义。2.2 多变量输入是怎么组织成张量的压缩包里的光伏2019.xlsx 是逐条记录的多列数据。多变量体现在输入维度上每一个时间步不只是功率一个标量而是辐照度、温度、湿度、风速、历史功率等多个通道。以 5 个特征为例一个样本是 (histSteps × 5) 的矩阵histSteps 是回溯窗口长度。特征通道物理含义单位与功率的关系GHI水平面总辐照W/m²最强正相关环境温度空气温度℃弱正相关影响组件效率湿度相对湿度%负相关高湿常伴随多云风速水平风速m/s影响组件散热历史功率上一时段出力kW自回归信息实际构造样本时用滑动窗口。假设原始序列长度 L回溯窗口 12预测步长 3那么样本数约等于 L - 12 - 3 1。滑动窗口切分是这套工程里最值得留意的一段% 滑窗构造多变量多步样本 histSteps 12; % 回溯历史窗口 predSteps 3; % 预测未来步数 featDim 5; % 多变量特征通道数 numSamples size(featRaw, 1) - histSteps - predSteps 1; X zeros(numSamples, histSteps, featDim); % 样本数×时间步×特征数 Y zeros(numSamples, predSteps); % 每个样本对应未来3个功率值 for i 1:numSamples X(i, :, :) featRaw(i : i histSteps - 1, :); Y(i, :) tgtRaw(i histSteps : i histSteps predSteps - 1); endX 的第一维是样本序号第二维是时间步第三维是特征通道Y 的一行就是未来 predSteps 个时刻的功率。这个三维组织方式直接对接 sequenceInputLayer等长序列不需要转换成 cell 数组更省内存。参数说明histSteps 决定了模型能看到多长的历史取值太小抓不到日内趋势取值太大会稀释 Attention 的权重分布常见做法是先按业务需要定在 1224。predSteps 是业务要求的预测时域预测步数越大整体误差上升越明显一般取 16 比较现实。2.3 多步预测的两种落地方式直接多步与递归多步多步预测不是简单把输出层维度改成 predSteps 就完事构造监督信号的方式有两种。直接多步把未来 predSteps 个点一次性作为回归目标递归多步则是先用单步模型预测 t1再把预测值拼到输入末尾预测 t2逐点滚动。递归方式省显存但误差会随步数累积而且训练和推理时的输入分布不一致漂移问题在光伏这种强波动序列上很明显。直接多步在工程上更稳。训练时监督信号就是真实未来值推理时一步到位缺点是网络要同时拟合多个 horizon近端误差小、远端误差大最后画出来的误差图是随预测步数递增的斜坡。这个现象是正常的不是模型坏了。如果是做工程落地可以把 predSteps 拆开训练三份单步模型做集成对比。3. Matlab 工程实现文件职责、层图搭建与参数化训练3.1 压缩包里的文件各负责什么CNN-LSTM-Attention.zip 解压后核心是三个东西主脚本 main.m、误差计算函数 calc_error.m、数据文件光伏2019.xlsx。另有一个 CNN_LSTM_ATTENTION.mat这是训练收敛后保存的网络与归一化参数加载后可以直接跑预测也可以作为增量训练的起点。两张 png 是作者跑完后的标准输出1.png 是测试集预测对比曲线2.png 是逐时间步误差分布。main.m 的执行顺序是读 Excel → 归一化 → 滑窗构造 X/Y → 划分训练集测试集 → 定义网络层 → 训练 → 反归一化 → 调 calc_error 计算指标 → 画图。这个顺序本身就是多变量时序预测的标准流程换数据时不需要调整整体结构。注意 zip 包里有个 txt 提示文件专门说了 MAPE 的事因为真实功率序列里有大量夜间零点MAPE 算出来是无穷大第四章会专门解释处理方式。3.2 网络搭建从输入层到回归输出层搭建网络推荐用 layerGraph 而不是直接把层数组丢给 trainNetwork因为中间要插入 Attention 层。一个典型的直接多步结构如下layers [ sequenceInputLayer(5, Name, in, MinLength, 12) % 5个特征最短长度12 convolution1dLayer(3, 32, Padding, same, Name, conv1) reluLayer(Name, relu1) maxPooling1dLayer(2, Stride, 2, Name, pool1) lstmLayer(96, OutputMode, sequence, Name, lstm) attentionLayer(Name, attn) % 对时间步加权输出上下文向量 fullyConnectedLayer(3, Name, fc) % 直接输出未来3步 regressionLayer(Name, out) ]; lgraph layerGraph(layers);attentionLayer 在 Matlab 2023 里可以用 Deep Network Designer 导入预置模块也可以用自定义层实现。核心运算片段如下% Attention 前向计算的核心片段自定义层中 % h: [numHidden, seqLen]LSTM 输出的隐状态序列 score attentionW * h; % 每个时间步一个未归一化得分 alpha softmax(score, 2); % 沿时间维归一化得到权重 context sum(alpha .* h, 2); % 加权求和 - [numHidden, 1]attentionW 是层的可学习参数尺寸 1×numHidden。这里最容易出错的是 softmax 作用的维度写错导致权重把所有时间步都平均掉Attention 层就退化成全局平均池化。卷积核取 3感受野覆盖三个相邻采样点对一个 15 分钟粒度的序列来说正好覆盖 45 分钟的局部变化。maxPooling 步长为 2把序列长度压缩一半LSTM 展开步数减少训练速度和显存占用都会改善代价是时间粒度变粗。序列长度从 12 压到 6 对日内趋势提取影响不大可以这样配置。3.3 训练选项与参数化配置main.m 的特点是参数化编程超参数全部集中在脚本开头的配置区修改一处即可全局生效而不是散落在代码中间。建议至少把下面这些参数抽出来参数推荐值调整依据histSteps12回溯窗口与采样粒度强相关predSteps3业务预测时域numFilters32特征通道数数据量小就减半lstmUnits96隐状态维度过大会过拟合InitialLearnRate0.001Adam 下的常见起点MiniBatchSize32显存不足就减半MaxEpochs200配合早停使用Dropout0.2LSTM 输出后加防过拟合训练代码一般是这样一组选项options trainingOptions(adam, ... InitialLearnRate, 0.001, ... MaxEpochs, 200, ... MiniBatchSize, 32, ... GradientThreshold, 1, ... % 防止LSTM梯度爆炸 ValidationData, {XVal, YVal}, ... ValidationFrequency, 20, ... OutputNetwork, best-validation, ... Plots, training-progress);GradientThreshold 在 LSTM 训练里几乎是必需项光伏序列中的功率突变会产生大梯度不设梯度裁剪时 loss 曲线会突然跳到 NaN。ValidationFrequency 每 20 次迭代算一次验证集误差OutputNetwork 选 best-validation 而不是 last-epoch能在过拟合后自动回滚到最优权重。4. 评价指标详析R2、MAE、MSE、RMSE 与 MAPE 失效场景4.1 五个指标的公式与业务含义压缩包内 calc_error.m 计算五个指标。它们的侧重点不同组合起来才能判断模型是否真正可用。指标公式意义MSEmean((y-yhat)^2)平方误差放大极端误差RMSEsqrt(MSE)回到功率量纲的均方根误差MAEmean(abs(y-yhat))平均绝对误差最直观R21 - SS_res/SS_tot相对均值基线解释了多少方差MAPEmean(abs((y-yhat)/y))*100%百分比误差分母为 0 则失效R2 是回归任务里最容易误读的指标。它比较的是模型误差和「直接用平均值预测」的误差R20.9 只说明比均值基线好很多不代表误差绝对值小。对光伏功率RMSE 和 MAE 更该看RMSE 对尖峰误差敏感MAE 反映平均偏移。R2 高但 RMSE 偏大多半是少数极端阴晴转换时刻预测失败拉高了平方项。4.2 MAPE 在光伏数据里为什么必然失效光伏电站夜间功率是 0阴天时刻也可能接近 0。MAPE 的分母是真实功率真实值为 0 时误差直接变成无穷大NaN 或者 Inf 会污染后面所有统计结果。压缩包里的提示 txt 写得很直白这个数据不要看 MAPE。提示zip 包内的说明文件特别标注了这一点。真实功率序列中存在大量 0MAPE 必然是 Inf这不代表模型坏了。我一般会顺手写一个「非零样本 MAPE」只统计真实功率大于阈值的点得到白天有出力时段的平均百分比误差这个指标对业务更有意义% 非零功率样本的MAPE避免分母为0污染 % 只在真实功率大于阈值时参与计算 thr 0.01 * max(yTrue); % 阈值取最大功率的1% mask yTrue thr; mapeNonZero mean(abs((yTrue(mask) - yPred(mask)) ./ (yTrue(mask)))) * 100;阈值设 1% 是为了把所有接近零功率的夜间样本排除这个阈值本身也可以作为参数暴露到 main.m 的配置区里。4.3 一个自包含的指标计算函数如果只想保留稳定指标可以把 calc_error.m 精简成这样function [R2, MAE, MSE, RMSE] calc_error(yTrue, yPred) % 输入为列向量长度一致 e yTrue - yPred; MSE mean(e.^2); RMSE sqrt(MSE); MAE mean(abs(e)); SStot sum((yTrue - mean(yTrue)).^2); SSres sum(e.^2); R2 1 - SSres / SStot; % 不返回MAPE避免夜间零功率导致Inf end这样调用一次拿到四个指标结合预测对比图就能判断模型状态。如果要做论文或报告建议把测试集按晴天、阴天、雨天分桶后各算一次 R2光伏功率预测里分天气状况评估比整体指标更有说服力这也是超短期光伏功率预测评估的常见做法。5. 复现与排错从光伏 2019 数据到增量训练5.1 把数据换成自己的光伏电站记录拿到这套源码后最常见的需求是换成自己电站的数据。核心注意三点。第一列顺序要与 main.m 读取时保持一致最稳妥是读表后按列名取数不按位置索引。第二时间必须连续缺测必先用 fillmissing 线性插值否则滑窗错位训练出来的模型等于把错误样本硬背下来。第三采样间隔变了要同步改 histSteps15 分钟粒度下回溯 12 点只覆盖 3 小时1 小时粒度下回溯 12 点覆盖半天两者的感受完全不同。换数据后先跑 20 个 epoch 验证 loss 下降趋势再放完整训练不要一上来就全量跑。5.2 运行期常见报错排查表下面几条是这个工程在 Matlab 2023 环境里最容易遇到的报错出现时按表对照处理。现象原因处理提示找不到 attentionLayer自定义层文件不在当前路径addpath 到层文件目录或从 Deep Network Designer 导入loss 变 NaN学习率过大 / 输入有 NaN / 梯度爆炸检查归一化结果调低 InitialLearnRate打开 GradientThreshold预测曲线是水平直线输出层权重饱和或输入特征与目标无关检查是否用了未来数据泄漏检查归一化是否反了内存不足MiniBatchSize 太大MiniBatchSize 从 32 降到 16 或 8误差图在远端步长明显变大多步预测的正常现象不是 bug按业务需求裁剪预测步数MAPE 显示 Inf夜间功率为 0按第四章方法过滤或忽略5.3 用预训练模型继续训练CNN_LSTM_ATTENTION.mat 里存的是已经收敛的网络可以直接加载预测也可以用它做增量训练。增量训练对新电站数据很有效光伏板老化或电站扩容后的新数据量不大从头训练容易过拟合从预训练权重出发微调是省样本的实用技巧data load(CNN_LSTM_ATTENTION.mat); % 内含训练好的 net net data.net; options trainingOptions(adam, InitialLearnRate, 1e-4, ... MaxEpochs, 50, MiniBatchSize, 32); net trainNetwork(XNew, YNew, net.Layers, options);注意这里学习率要调小预训练权重已经接近最优区域学习率保持 0.001 会把已经学好的卷积核冲坏。微调阶段一般 50 个 epoch 内就能收敛。这套「预训练 微调」的思路同样能迁移到电池 SOC 估计、风速预测这类结构和任务高度相似的时序回归问题上只需要把输入特征数和输出维度对应改掉。本文还有配套的精品资源点击获取
返回列表