1) 小波神经网络 概念
对小波神经网络最常用、最好训练的形式是 小波基函数网络(Wavelet Basis Network):
\[\hat y(t)=\hat P(t)=\sum_{k=1}^{K} w_k\cdot \psi\!\left(\frac{z_k-b_k}{a_k}\right)+w_0
\]
- (\(\psi(\cdot)\)):母小波(一般选 Morlet 最稳)
- (\(z_k\)):进入第 (\(k\)) 个小波节点的输入向量分量(通常就是某维特征,或线性组合)
- (\(a_k>0\)):尺度,(\(b_k\)):平移
- (\(w_k,w_0\)):线性输出权
直觉:它不是去“小波变换后再接 NN”,而是把小波当成一种带尺度/平移的可学习基函数,网络通过学习 ((a_k,b_k,w_k)) 来拟合负荷的非线性周期性。
本文示例使用 一维输入版(每一维输入各自进自己的小波节点,结构简单、稳定),你要升级到“(z=W x) 线性组合版”我也可以补。
2) 电力负荷预测:怎么把问题做成监督学习
设负荷序列为 (\(P(1),P(2),\dots,P(N)\)),采样间隔=1h(或15min,同理)。
(1) 经典单步预测输入向量
\[\mathbf{x}(t)=
\big[P(t-1),P(t-2),\dots,P(t-L),D(t),H(t),\mathbb{1}_{\text{weekend}}(t)
\big)\]
- 历史负荷:(\(L=24\))(小时)或 (96)(15min)
- 日历特征:日编号 (D)、小时编号 (H)、周末/节假日指示
- 温度/天气:能拿到就加(效果提升很大)
输出:(\(\hat P(t)=f(\mathbf{x}(t))\))
(2) 归一化
建议用滑动窗口 z-score 或 min-max,这里先用简单 min-max:
Pn = (P - min(P))/(max(P)-min(P)+eps);
负荷预测里别把未来信息泄露进归一化(即不要用全局 future max/min 去归一化 test 段),工程上常见做法是:用 train 段统计做映射,test 段 clip。
3) 小波(Morlet)定义与网络前向
Morlet 母小波(复小波取实部即可):
\[\psi(u)= \cos(5u)\,\exp\!\big(-u^2/2\big)
\]
前向计算(单样本 (\(x\in\mathbb{R}^d\)),这里让每个小波只吃一个维度 (\(x(j)\)),最稳):
- 假设有 (\(K\)) 个小波节点,且 (\(K = d\times m\))(每层维度 (\(m\)) 个 (\((a,b)\)))
- 对第 (\(j=1..d\)) 维输入,对应小波组 (\(k=(j-1)m+1 .. jm\))
\[u = (x(j)-b_k)/a_k,\quad h_k=\psi(u)
\]
- 输出
\[\hat y = w_0 + \sum_{k=1}^{K} w_k\,h_k
\]
4) MATLAB:可运行的最小 Demo(单步预测 + MAPE/RMSE)
这是原理级可复现代码(不是调库),你可以直接贴进 MATLAB 跑通,再换成你的真实负荷 CSV。
%% ========= 1. 数据:造一条“有日周期+周末+噪声”的负荷 =========
Fs = 24; % 24点/天
N = 14*Fs; % 14天
t = (1:N)';base = 100*ones(N,1);
daily = 30*(0.5+0.5*cos(2*pi*(t-7)/24)); % 日间高峰
week = 15*(mod((1:N)'-1,7)>=5); % 周末抬升
P = base + daily + week + 5*randn(N,1); % 负荷
P = max(P,50);% 可视
figure; plot(t,P); grid on; title('Synthetic Load'); xlabel('hour index');%% ========= 2. 构造监督样本(lag-24 单步预测)=========
L = 24; % 历史长度
D = L + 2; % 输入维:24负荷 + hour + weekend_flagX = []; Y = [];
for i = (L+1):Nhist = P(i-L:i-1);hr = mod(i-1,24)/24; % 小时归一化到 [0,1]we = double(mod(i-1,7)==5 | mod(i-1,7)==6);xi = [hist(:)./120 ; hr ; we]; % 简单归一化(你的真实数据再校准)X = [X; xi'];Y = [Y; P(i)];
end% 输出也归一化(可选但更稳)
Ymean = mean(Y); Ystd = std(Y)+eps;
Y = (Y-Ymean)/Ystd;%% ========= 3. 训练/测试切分(前70%训练)=========
n = size(X,1);
ntr = floor(0.7*n);
Xtr = X(1:ntr,:); Ytr = Y(1:ntr);
Xte = X(ntr+1:n,:); Yte = Y(ntr+1:n);%% ========= 4. 初始化 WNN(Morlet 小波基)=========
d = size(X,2); % 输入维
m = 2; % 每个维的小波个数(可调)
K = d*m; % 总小波节点% 参数打包:theta = [a(:); b(:); w(:); w0]
a0 = 0.5+0.3*rand(K,1);% 尺度
b0 = rand(K,1); % 平移(建议用输入统计量初始化更好)
w0 = randn(K,1)*0.1;
w00= 0;
theta0 = [a0;b0;w0;w00];psi = @(u) cos(5*u).*exp(-u.^2/2); % Morlet(实部)% ---------- 前向 ----------
function [y, H, Jac] = wnn_forward(X, theta, d, m)K = d*m;a = theta(1:K); b = theta(K+1:2*K); w = theta(2*K+1:3*K); w0 = theta(end);Ns = size(X,1);H = zeros(Ns,K);for i=1:Nsidx=0;for j=1:dfor r=1:mk=idx+r;u=(X(i,j)-b(k))/a(k);H(i,k)=psi(u);endidx=idx+m;endendy = H*w + w0;% Jacobian wrt theta(数值也行,但解析更稳定)Jac = []; % 你把解析导放这里,或下面用数值Jacobian(见训练)
end% ---------- 目标函数(带一点正则)==========
lambda = 1e-4;
fun = @(th) wnn_obj(th, Xtr, Ytr, d, m, lambda, psi);%% ========= 5. 训练:Levenberg-Marquardt(推荐)=========
opts = optimoptions('lsqnonlin',...'Algorithm','levenberg-marquardt',...'Display','iter',...'MaxIterations',120,...'StepTolerance',1e-8);[theta_hat,~,res] = lsqnonlin(fun, theta0,[],[],opts);%% ========= 6. 推理 + 反归一化 + 指标 =========
pred_tr = wnn_pred(Xtr, theta_hat, d, m, psi)*Ystd + Ymean;
pred_te = wnn_pred(Xte, theta_hat, d, m, psi)*Ystd + Ymean;Ytr_true = Ytr*Ystd + Ymean;
Yte_true = Yte*Ystd + Ymean;fprintf('TRAIN MAPE=%.2f%% RMSE=%.3f\n',mape(Ytr_true,pred_tr),rmse(Ytr_true,pred_tr));
fprintf('TEST MAPE=%.2f%% RMSE=%.3f\n',mape(Yte_true,pred_te),rmse(Yte_true,pred_te));figure; plot(Yte_true,'k'); hold on; plot(pred_te,'r--'); grid on;
legend('True','WNN Forecast'); title('WNN Load Forecast (Test)');%% ========= 工具函数 =========
function F = wnn_obj(th, X, Y, d, m, lam, psi)K = d*m;a=th(1:K); b=th(K+1:2*K); w=th(2*K+1:3*K); w0=th(end);Ns=size(X,1); E=zeros(Ns,1);for i=1:Nss=w0;idx=0;for j=1:dfor r=1:mk=idx+r;u=(X(i,j)-b(k))/a(k);s=s + w(k)*psi(u);endidx=idx+m;endE(i)=s-Y(i);end% 软正则(抑制权值爆炸)F = [E; sqrt(lam)*w; sqrt(lam)*(a-0.5)];
endfunction y = wnn_pred(X, th, d, m, psi)K=d*m; a=th(1:K); b=th(K+1:2*K); w=th(2*K+1:3*K); w0=th(end);Ns=size(X,1); y=zeros(Ns,1);for i=1:Nss=w0; idx=0;for j=1:dfor r=1:mk=idx+r;u=(X(i,j)-b(k))/a(k);s=s+w(k)*psi(u);endidx=idx+m;endy(i)=s;end
endfunction v=mape(a,b), v=mean(abs(a-b)./max(abs(a),1e-6))*100; end
function v=rmse(a,b), v=sqrt(mean((a-b).^2)); end
参考代码 用于小波神经网络电力负荷预测 www.youwenfan.com/contentcnv/81439.html
5) 你把它用到“真实电力负荷 CSV”
- 读入:
data = readtable('load.csv');拿到P = data.Load;与时间戳 - 做特征:
hour = hour(timestamp),weekend = (weekday==6|7)- 有温度:
x_temp = (T-20)/15
- 归一化要“训练统计→测试”(更规范)
- 输入维改成:
[P(t-1)...P(t-L), hour_norm, weekend, temp_norm] - 小波节点数先从 每维 m=2~4 试(
K=d*m),过大会过拟合
