ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

小波神经网络预测代码:Python毕设工程包实战指南

小波神经网络预测代码:Python毕设工程包实战指南 简介这份毕业设计资源聚焦小波神经网络WNN预测方向面向具备一定信号处理与机器学习基础的高校学生及研究人员用于学习小波变换与神经网络融合建模的完整实现思路。压缩包共6个文件以5个m脚本和1个mat数据文件为主整体约5KB其中脚本承担小波基函数定义、导数计算、层析分析与神经网络训练预测等模块mat文件则提供交通流量等实际场景数据便于直接运行与调试。目前已有98人学习下载可作为课程设计或论文复现的参考起点。读者可借此理解小波多分辨率分析与神经网络自适应学习的结合方式掌握从数据加载、模型搭建到预测验证的完整流程并在此基础上调整参数、替换数据集为后续科研与工程应用打下基础。需注意代码仅供交流学习禁止商业用途。1. 小波神经网络预测代码一份能直接跑通毕设的 Python 工程包如果你正在做基于 Python 的毕业设计选题又落在时间序列预测、负荷预测、风速预测或者信号趋势外推这类方向上大概率绕不开小波神经网络WNN这个词。它把传统 BP 网络的隐层激励换成了小波基函数靠平移和伸缩因子去逼近非平稳信号在电力负荷、交通流、气象数据这类波动剧烈的序列上往往比纯 BP 收敛更稳、拟合更细。这份「毕业设计-小波神经网络预测代码.rar」就是围绕这个思路打包的一套可运行工程核心是 Python 实现覆盖数据预处理、小波基构造、网络训练、预测输出和误差评估几个环节。它适合两类人一类是刚接触预测模型、需要一份能改参数就能出图的新手另一类是已经写过 BP 但被局部极小值和震荡折磨过、想换小波基试试的熟手。下面我按拆包后的真实结构把怎么用、参数怎么调、哪里容易翻车讲清楚。2. 拆开压缩包先看什么文件结构与运行链路2.1 目录里各文件到底管什么拿到压缩包别急着双击运行先解压看结构。这类毕设代码包通常不会太复杂但命名随意理清依赖关系能省掉一半调试时间。常见布局是一个主训练脚本、一个数据文件、一个网络定义模块、一个绘图或评估脚本外加 requirements 或说明文档。你要先确认哪一个是入口判断依据是它有没有if __name__ __main__:以及是否调用了数据读取和训练循环。文件/目录典型作用先看还是后看main.py / train.py训练入口串起数据、模型、训练、保存先看data/ 或.csv/.xlsx原始时序数据含时间列和数值列先看model.py / wnn.py小波神经网络结构定义重点看utils.py / preprocess.py归一化、滑窗、划分训练测试集重点看plot.py / evaluate.py预测曲线、误差指标输出后看requirements.txt依赖清单先装如果包里没有 requirements常见依赖是 numpy、pandas、matplotlib、torch 或 tensorflow 二选一少数轻量实现只用 numpy 手写反向传播。先跑pip list对一下版本别等报错再回头找。2.2 环境准备与第一次运行我一般会新建虚拟环境再装依赖避免和系统里其他毕设项目打架。命令不复杂但顺序别乱# 创建并激活虚拟环境Python 版本建议 3.8 到 3.10 python -m venv wnn_env # Windows 下激活 wnn_env\Scripts\activate # Linux / macOS 下激活 source wnn_env/bin/activate # 安装常见依赖版本按包内说明调整 pip install numpy pandas matplotlib scikit-learn # 如果用的是 PyTorch 实现 pip install torch装完先别改任何代码直接跑一次入口脚本看它能不能走完一轮。第一次运行的目标不是精度而是确认数据能读进来、网络能前向、损失能下降。如果报FileNotFoundError多半是数据路径写死了绝对路径改成相对路径即可如果报形状不匹配先去看数据读取那几行的reshape和滑窗长度。import pandas as pd import numpy as np # 读取时序数据假设第一列是时间第二列是待预测值 df pd.read_csv(data/series.csv) values df.iloc[:, 1].values.astype(float) # 最大最小归一化避免量纲差异导致训练震荡 vmin, vmax values.min(), values.max() norm (values - vmin) / (vmax - vmin) # 滑动窗口构造监督样本window 是输入步长horizon 是预测步长 def make_samples(seq, window12, horizon1): X, y [], [] for i in range(len(seq) - window - horizon 1): X.append(seq[i:i window]) y.append(seq[i window:i window horizon]) return np.array(X), np.array(y) X, y make_samples(norm, window12, horizon1) print(X.shape, y.shape) # 形如 (样本数, 12) (样本数, 1)这段代码做了三件事归一化、滑窗、形状确认。window12表示用前 12 个时刻预测下一个时刻做负荷预测常用 24 或 96做风速预测常用 6 到 12具体看你的采样间隔。归一化必须做小波基对输入幅值敏感不归一化很容易出现梯度爆炸。滑窗的horizon决定你是单步预测还是多步预测毕设里单步最常见多步要额外处理误差累积。2.3 小波神经网络的结构定义WNN 和普通 BP 的差别就在隐层。普通 BP 用 sigmoid 或 reluWNN 用母小波函数通过平移因子 b 和伸缩因子 a 对输入做变换。常见母小波有 Morlet、Mexican hat、Gaussian 导数。Morlet 在预测任务里用得最多因为它兼顾时频局部化波形平滑梯度好求。import torch import torch.nn as nn class MorletWNN(nn.Module): def __init__(self, in_dim, hidden8, out_dim1): super().__init__() # 输入层到隐层的权重 self.w nn.Parameter(torch.randn(in_dim, hidden) * 0.1) # 平移因子 b 和伸缩因子 a每个隐节点一组 self.b nn.Parameter(torch.zeros(hidden)) self.a nn.Parameter(torch.ones(hidden)) # 隐层到输出层 self.out nn.Linear(hidden, out_dim) def morlet(self, x): # Morlet 母小波cos(5x) * exp(-x^2/2) return torch.cos(5 * x) * torch.exp(-x ** 2 / 2) def forward(self, x): # x: (batch, in_dim) z x self.w # 线性组合 z (z - self.b) / (self.a 1e-8) # 平移与伸缩 h self.morlet(z) # 小波激励 return self.out(h)hidden8是隐层小波元个数太小欠拟合太大过拟合且训练慢毕设数据量不大时 6 到 12 比较稳。a初始化为 1、b初始化为 0 是常规起点训练中它们会自适应调整。1e-8是防止除零别省。cos(5x)里的 5 是 Morlet 的中心频率一般不改改了要同步调整初始化。如果你用的是 TensorFlow结构一样把nn.Parameter换成tf.Variable即可。3. 训练、调参与预测输出把代码跑出可用结果3.1 训练循环与损失选择训练部分决定你能不能出图。毕设里回归预测默认用 MSE如果数据里有明显离群点可以换 MAE 或 Huber避免个别异常值把网络带偏。优化器首选 Adam学习率 1e-3 起步配合学习率衰减更稳。from torch.utils.data import TensorDataset, DataLoader # 转成张量并划分训练/测试集前 80% 训练 X_t torch.tensor(X, dtypetorch.float32) y_t torch.tensor(y, dtypetorch.float32) n len(X_t) split int(n * 0.8) train_ds TensorDataset(X_t[:split], y_t[:split]) test_ds TensorDataset(X_t[split:], y_t[split:]) train_loader DataLoader(train_ds, batch_size16, shuffleTrue) model MorletWNN(in_dimX.shape[1], hidden8, out_dim1) opt torch.optim.Adam(model.parameters(), lr1e-3) scheduler torch.optim.lr_scheduler.StepLR(opt, step_size200, gamma0.5) loss_fn torch.nn.MSELoss() for epoch in range(1000): model.train() total 0.0 for xb, yb in train_loader: opt.zero_grad() pred model(xb) loss loss_fn(pred, yb) loss.backward() opt.step() total loss.item() * len(xb) scheduler.step() if epoch % 100 0: print(fepoch {epoch}, loss {total / split:.6f})batch_size16适合几百到几千条样本样本上万可以加到 32 或 64。epoch1000是上限实际看 loss 曲线连续 100 轮不降就可以停。StepLR每 200 轮把学习率砍半能帮网络在后期精细收敛。打印间隔设 100 是为了不刷屏调试阶段可以改成 10。如果 loss 一直不降先查归一化有没有做、学习率是不是太大、a有没有变成负数导致小波函数发散。3.2 预测、反归一化与误差指标训练完必须做反归一化否则你画出来的曲线和原始数据对不上答辩时一眼就被看穿。误差指标至少给 MAE、RMSE、MAPE 三个单给一个说服力不够。model.eval() with torch.no_grad(): pred_test model(X_t[split:]).numpy().flatten() # 反归一化回原始量纲 pred_inv pred_test * (vmax - vmin) vmin true_inv y[split:].flatten() * (vmax - vmin) vmin # 三个常用误差指标 mae np.mean(np.abs(pred_inv - true_inv)) rmse np.sqrt(np.mean((pred_inv - true_inv) ** 2)) mape np.mean(np.abs((pred_inv - true_inv) / (true_inv 1e-8))) * 100 print(fMAE{mae:.4f}, RMSE{rmse:.4f}, MAPE{mape:.2f}%)1e-8同样是防除零真实值里如果有 0MAPE 会失真这时候改用 MAE 或 RMSE 更合适。反归一化用的vmin、vmax必须是训练集统计出来的不能拿全量数据重算否则等于把测试集信息泄漏进训练指标会虚高这是毕设里最隐蔽的翻车点之一。画图时把真实值和预测值叠在一张图上横轴用时间纵轴用原始量纲再单独画一张误差曲线基本就够答辩用了。3.3 小波基与隐层节点怎么选选型不是拍脑袋。Morlet 适合连续、平滑、有周期性的序列比如负荷和温度Mexican hat 适合带突变和尖峰的信号比如故障冲击Gaussian 导数介于两者之间。隐层节点数从 6 开始试每次加 2看测试集 RMSE 是否下降一旦测试误差回升就是过拟合信号。常见做法是固定随机种子跑三次取平均避免单次结果偶然性太大。# 固定种子保证结果可复现 import torch, numpy as np, random def set_seed(s42): random.seed(s); np.random.seed(s) torch.manual_seed(s); torch.cuda.manual_seed_all(s) set_seed(42)种子不固定你这次跑出 MAPE 3%下次跑出 8%答辩现场复现不出来就很被动。hidden和window建议做一个小网格window 取 6、12、24hidden 取 6、8、10组合跑一遍把 RMSE 记下来做成表这本身就是毕设里能写进论文的实验部分。4. 避坑与排查这几处翻车我见过太多次4.1 现象loss 变成 nan 或直接不降原因通常是学习率过大、归一化遗漏、或者a在训练中变成 0 甚至负数导致(z-b)/a爆炸。解决先把学习率降到 1e-4 试确认归一化在训练前完成再给a加一个软约束比如在 forward 里用torch.abs(self.a) 1e-8或者初始化时把a设成 1.0 并限制其下界。4.2 现象预测曲线整体平移形状对但数值差一截这是反归一化用错统计量的典型表现。有人图省事拿全量数据的 min/max 做反归一化训练时却只用训练集归一化两边不一致。解决把vmin、vmax在归一化前就存下来训练、预测、反归一化全程用同一组值测试集不参与统计。4.3 现象测试集指标好得离谱MAPE 低于 1%先别高兴大概率是数据泄漏。滑窗构造样本时如果先划分再滑窗相邻样本会跨训练测试边界或者归一化用了全量数据。解决先按时间顺序切分原始序列再各自滑窗归一化统计量只从训练段计算。时间序列不能随机打乱划分shuffleTrue只用在训练集内部的 batch 上。4.4 现象换台电脑或重装环境后结果对不上原因多是随机种子没固定、依赖版本不一致、或者用了 GPU 而另一台只有 CPU浮点运算顺序不同会带来微小差异。解决在入口脚本第一行就set_seedrequirements 里锁版本号论文里注明运行环境。差异在 1% 以内属正常超过就要查代码。4.5 现象训练集误差很低测试集一塌糊涂典型过拟合。隐层节点太多、训练轮数太多、样本太少都会导致。解决减少hidden加早停验证 loss 连续 N 轮不降就停或者加一点权重衰减weight_decay1e-4。毕设数据量通常不大早停比调网络结构更省事。5. 进阶技巧把小波神经网络用出论文该有的样子想让这份代码在答辩里站得住光跑通不够得做出对比和解释。我一般会做三组对照纯 BP、WNN、以及换不同母小波的 WNN用同一份数据、同一个滑窗、同一个训练轮数把 MAE、RMSE、MAPE 列成表。这样你能说清楚小波基到底带来了多少提升而不是空谈「效果更好」。模型母小波隐层节点RMSEMAPEBP无8待填待填WNNMorlet8待填待填WNNMexican hat8待填待填表格里的数必须是你自己跑出来的别抄。跑的时候固定种子每个配置跑三次取平均把均值和标准差都记下来标准差能说明模型稳不稳。另一个加分点是画出小波基的时频响应解释为什么 Morlet 适合你的数据——如果数据有周期性Morlet 的振荡特性就对得上如果数据是冲击型Mexican hat 更合适。这部分不用写太长两三段配上图就够。还有一个容易被忽略的点预测步长。单步预测指标好看但实际场景往往要多步。你可以把horizon改成 3 或 6观察误差随步长怎么增长画一条误差随步长上升的曲线这比单步结果更有说服力。多步预测时不要每一步都重新训练用递归方式把上一步预测值喂回输入同时记录误差累积情况。# 递归多步预测示意horizon3 model.eval() window 12 history list(norm[:window]) preds [] with torch.no_grad(): for _ in range(3): xin torch.tensor(history[-window:], dtypetorch.float32).view(1, -1) p model(xin).item() preds.append(p) history.append(p) # 把预测值当真实值继续喂 preds_inv [p * (vmax - vmin) vmin for p in preds] print(preds_inv)递归多步的坑在于误差会滚雪球第一步偏一点后面越偏越多。所以多步结果一定要和单步分开报别混在一起。如果多步误差涨得太快可以考虑直接训练一个输出维度等于步长的网络一次吐出多步代价是样本构造要改。最后说个血泪经验毕设代码最怕「在我电脑上能跑」。交稿前把整个工程拷到一台干净机器上从建虚拟环境开始走一遍把缺的包、写死的路径、没固定的种子全部补上。从那以后我每次交付前都强制走一遍全新环境复现宁可多花半小时也不在答辩前夜发现跑不起来。希望这份拆解帮到你代码包拿去改改参数就能用别浪费在环境上。本文还有配套的精品资源点击获取
返回列表