DEGWO-BP神经网络:混合优化算法在电厂运行数据回归预测中的应用

发布时间:2026/10/22 8:43:38
DEGWO-BP神经网络:混合优化算法在电厂运行数据回归预测中的应用
1. DEGWO-BP是什么为什么电厂运行预测需要混合优化网络基于混合差分进化与灰狼优化算法的DEGWO-BP神经网络回归预测听起来像是一串绕口令但它在电厂运行数据预测这类回归任务里是一套非常能打的组合。先拆开看BP是基础神经网络DEGWO是差分进化加灰狼优化的混合算法它的用途不是替代神经网络本身而是替BP找到一组更好的初始权重和阈值。电厂运行参数的预测场景很多比如根据历史负荷、蒸汽参数、燃料量预测下一时段机组负荷或者根据锅炉侧运行数据预测主蒸汽温度、NOx排放浓度。这类数据普遍有两个特点一是特征之间存在强耦合二是非线性关系明显。普通BP神经网络理论上能逼近任意非线性函数但训练时很容易掉进局部最优初始化不好收敛速度就慢预测精度也不稳定。DEGWO就是来解决这个问题的它把差分进化的全局探索能力和灰狼算法的快速收敛能力结合起来先搜索一组高质量的网络参数再用BP梯度下降做局部微调。这篇文章我尽量按照实际做过一轮电厂负荷预测项目的流程来写从Excel数据读取、数据归一化到DEGWO-BP的完整算法实现、参数设置、结果评估再到常见坑的排查都会落到可操作层面。适合刚接触智能优化算法的学生也适合想把手头Excel表格数据做成预测模型的一线工程师。如果你已经会基础Python那这套流程你半天左右就能跑通就算不太熟悉我也把每一步为什么这么做讲清楚照着做也能复现。2. 先理解BP的短板才能理解DEGWO的价值2.1 BP神经网络回归预测的天然缺陷BP神经网络的核心不复杂输入特征经过隐含层激活再映射到输出通过反向传播不断修正权重。问题在于误差的反向传播依赖梯度信息而真实问题的误差面往往坑坑洼洼存在大量局部极小值。如果初始权重落在陡峭的沟壑附近训练很容易在某个局部区域里反复震荡loss的下降曲线看起来就是“平了又平”最后得到一个精度勉强能用、但泛化能力很一般的模型。随机初始化两次结果往往完全不同这个不稳定性在电厂数据这类高噪场景里特别明显。所以后来出现了大量用智能优化算法初始化BP权重的做法比如用粒子群、遗传算法、差分进化算法。它们把网络参数编码成种群个体用适应度函数来评判参数好坏通过群体更新搜索更好的参数组合。思路是绕过梯度信息直接用搜索算法在解空间里找相对好的起点。DEGWO也属于这个路线但它把两个算法揉在一起比单用哪个都稳。2.2 差分进化与灰狼优化各自的脾气差分进化算法的核心操作是变异、交叉、选择它有很强的全局搜索能力。它对当前种群里的个体做差分扰动生成新候选按照优胜劣汰规则替换理论上种群多样性保持得比较好不容易过早收敛。缺点也很明确后期收敛速度相对慢到了接近最优值附近时变异步长如果没调好会在最优值附近来回跳动精度提升乏力。灰狼优化算法是模拟狼群捕猎行为的群体智能算法它把当前种群中适应度最好的三只狼分别视为alpha、beta、delta其他狼根据前三名的位置来更新。因为有明确的领导者牵引它前期收敛非常快搜索方向感很清楚。但问题就是如果alpha本身落入了局部最优整个狼群都会被带偏容易出现早熟。你发现没有这两个算法的优缺点正好互补。DE缺在后期收敛慢GWO早熟风险高DE保留了种群多样性GWO前期引导能力强。把两者结合起来自然就有各自扬长避短的空间。这是很多所谓“混合算法”论文的常见思路但关键是混合策略不能搞成生硬叠加不然只是增加计算量效果还不如单用DE。2.3 DEGWO混合改进的逻辑混合算法的逻辑通常是这样的种群初始化后每一代都让每个个体同时生成两个候选位置一个来自灰狼更新机制一个来自差分进化机制。然后按一定概率在两个候选中选择或者两个都生成后择优保留。这样当灰狼更新引导个体快速靠近当前最优区域时差分进化的扰动还能拉扯一部分个体继续探索其他区域减少被alpha带偏的风险。也有另一种混合方式DE和GWO按种群分段并行一部分个体走DE更新另一部分走GWO更新每隔几代交换信息。实际做下来我反而觉得逐个体生成双候选的方式更容易调参因为它不影响种群规模的设计只是在个体更新环节多算了一次候选位置计算量增加大概不到一倍但稳定性好很多。DEGWO-BP里我们需要优化的对象是BP网络的连接权值和阈值。假设输入层节点数是n1隐含层节点数是n2输出层节点数是n3那单个网络参数向量的总长度就是n1n2 n2 n2n3 n3分别对应输入层到隐含层的权重、隐含层阈值、隐含层到输出层的权重、输出层阈值。每个灰狼个体就是这个向量向量里的每一维对应网络里一个具体的参数值。3. Excel数据操作这步做不好后面全是白忙活3.1 电厂运行数据在Excel里怎么整理现实中从电厂DCS系统导出的数据通常是一张大宽表。每一行是一条时间点记录每一列是一个运行参数比如主蒸汽温度、主蒸汽压力、给水流量、排烟温度、燃料热值、环境温度最后一列往往是我们要预测的目标变量。做DEGWO-BP之前Excel表格必须整理成标准格式第一行是变量名前若干列是特征最后一列是目标值中间不能夹杂文本描述、空行或合并单元格。如果原始表里有单位、备注之类的文字先删掉。别小看这一步我之前见过有人直接把DCS导出的报表拖进程序里跑结果程序把“#N/A”当数值计算整个适应度全变成NaN。缺失值处理要按情况来少量缺失可以用前后均值填充电厂数据通常是连续时间序列用相邻两点平均值填充比较自然。大量缺失的那一段不如直接截断删除强行填充会引入虚假规律。异常值也一样比如给水流量瞬间变成负值多半是传感器故障该剔除就剔除不要手软。3.2 数据归一化的关键细节BP神经网络对数据量级非常敏感。如果主蒸汽压力是十几兆帕环境温度是几十摄氏度燃料量是几百吨这几个数字直接喂进去大数值变量就会在权重更新中占据绝对主导小数值变量的信息基本被淹没。一般处理方式是用归一化把数据压到[0,1]区间常见公式是x_norm (x - x_min) / (x_max - x_min)很多人只对输入特征做归一化忘了对目标变量做归一化。对于回归预测来说目标变量也建议归一化因为网络输出层的激活函数如果带tanh或sigmoid目标值不在映射范围内的话误差会非常夸张。即使输出层用线性激活对目标做归一化也能让损失函数数值更平稳收敛更容易。另一个容易踩的坑是测试集归一化不能用全量数据的最大值和最小值或者说至少不能让测试集数据参与max/min计算否则就是信息泄漏。正确做法是只用训练集算出x_min、x_max保存下来再用同一组参数去归一化测试集。很多初学者直接在全部数据上fit结果模型评估的R2虚高真正部署时一塌糊涂。3.3 训练集、验证集、测试集应该怎么切分我把这批电厂运行数据按时间顺序取了前80%做训练集后20%做测试集。注意是按时间顺序不是随机切分。电厂数据本质上是时间序列如果随机打乱相当于让模型偷看到了“未来”的数据特征测试集评估结果会严重失真。为了在进化过程中判断过拟合我一般还会从训练集里切出10%当验证集。DEGWO在优化网络初始参数时适应度只用训练集这一部分来计算不用验证集和测试集。进化结束后选适应度最好的个体作为BP的初始参数再用训练集完整训练一轮。最后用测试集做终极评估。这个习惯能很大程度避免“调参调在测试集上”导致的虚假自信。3.4 预测结果怎么回写到Excel写回Excel这一步虽然基础却是很多人忽略的。模型预测出来的值都是归一化后的结果必须先反归一化还原成真实量纲再写入Excel文件。反归一化公式就是x x_norm * (x_max - x_min) x_min。我习惯把原始实际值和预测值放在两个新的Excel列里并同时计算残差值这样方便人工检查。残差如果呈现明显的趋势性说明模型漏掉了某个关键影响因素不是简单地调参能补回来的。回写的时候注意不要覆盖原始数据表另存成一个新文件避免误操作把原始数据搞坏。4. DEGWO-BP核心算法实现从伪代码到完整流程4.1 个体编码与适应度函数每个DEGWO个体代表一组BP初始参数。适应度函数定义为训练集上的均方误差误差越小个体越优秀。实际代码里不需要在适应度函数内部做完整的BP多轮训练那样太慢。只需要把参数还原成权重和阈值做一次前向传播计算MSE即可。适应度函数实现时有个小技巧向量切分顺序必须和编码时完全一致。我习惯固定顺序先放输入层到隐含层的权重再放隐含层阈值然后是隐含层到输出层的权重最后放输出层阈值。任何地方多写一个维度后面还原矩阵时就会错位而且这种错位不会报错只会体现在预测值完全不对上特别难查。以下是核心伪代码流程读取Excel数据特征X和目标y。对X和y分别做归一化。切分训练集、验证集、测试集。根据网络结构计算个体维度D。初始化种群每个个体的位置在[-3,3]区间随机生成。进入迭代循环将种群按适应度排序取前三个个体为alpha、beta、delta。遍历每个个体分别用灰狼更新公式生成GWO候选。用变异和交叉操作生成DE候选。按一定概率选择其中一个候选计算适应度后决定是否替换原个体。更新最优解记录。迭代结束后将最优个体还原为BP网络的权重和阈值。在此基础上用训练集继续BP梯度下降训练。用测试集评估预测结果反归一化并写入Excel。4.2 灰狼候选和差分进化候选的生成方式灰狼位置更新的标准公式涉及控制参数A和CA随着迭代从2线性下降到0C是[0,2]之间的随机数。用这套方式生成候选位置D_alpha | C1 * X_alpha - X_i | X1 X_alpha - A1 * D_alpha对beta和delta也做同样的计算最终的GWO候选是X1、X2、X3的平均值。差分进化候选常用DE/best/1/bin策略来生成V X_best F * (X_r1 - X_r2)其中X_best是当前最优个体X_r1和X_r2是从种群中随机选取且互不相同的两个个体F是缩放因子。生成V之后还要和原个体做二项交叉得到U这个U才是真正的DE候选。两个候选都算出来后我的判断标准是如果当前迭代次数小于最大迭代次数的一半更偏向用DE候选目的是保持探索能力后期则偏向用GWO候选加速收敛。当然也可以做一个随机伯努利选择没硬性要求按项目实际效果调整就好。4.3 一套可直接复用的Python代码骨架下面这段代码以Python为例使用pandas处理Excelsklearn做数据切分numpy完成DEGWO主体。我刻意没有把代码写得过于封装方便你看到每一步到底做了什么。import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler # ---------- 1. 读取Excel并归一化 ---------- data pd.read_excel(plant_data.xlsx) X_raw data.iloc[:, :-1].values.astype(float) y_raw data.iloc[:, -1].values.astype(float) scaler_x MinMaxScaler() scaler_y MinMaxScaler() X scaler_x.fit_transform(X_raw) y scaler_y.fit_transform(y_raw.reshape(-1, 1)).flatten() # ---------- 2. 切分数据 ---------- split_point int(len(X) * 0.8) X_train, X_test X[:split_point], X[split_point:] y_train, y_test y[:split_point], y[split_point:] # ---------- 3. BP结构参数 ---------- n_input X_train.shape[1] n_hidden 8 n_output 1 dim n_input * n_hidden n_hidden n_hidden * n_output n_output def predict_with_params(flat_params, X_matrix): w1_size n_input * n_hidden b1_size n_hidden w1 flat_params[:w1_size].reshape(n_input, n_hidden) b1 flat_params[w1_size:w1_sizeb1_size] start w1_size b1_size w2 flat_params[start:startn_hidden*n_output].reshape(n_hidden, n_output) b2 flat_params[startn_hidden*n_output:] hidden np.tanh(X_matrix.dot(w1) b1) output hidden.dot(w2) b2 return output.flatten() def fitness_function(flat_params): y_pred predict_with_params(flat_params, X_train) return np.mean((y_pred - y_train) ** 2) # ---------- 4. DEGWO参数 ---------- pop_size 30 max_iter 50 F 0.6 CR 0.8 dim dim pop np.random.uniform(-3, 3, (pop_size, dim)) fitness np.array([fitness_function(ind) for ind in pop]) best_idx np.argmin(fitness) best_solution pop[best_idx].copy() best_fitness fitness[best_idx].copy() # ---------- 5. 迭代优化 ---------- for it in range(max_iter): a 2 - 2 * it / max_iter sorted_idx np.argsort(fitness) alpha pop[sorted_idx[0]].copy() beta pop[sorted_idx[1]].copy() delta pop[sorted_idx[2]].copy() for i in range(pop_size): # 灰狼候选 r1, r2 np.random.rand(dim), np.random.rand(dim) A1 2 * a * r1 - a C1 2 * r2 D_alpha np.abs(C1 * alpha - pop[i]) X1 alpha - A1 * D_alpha r1, r2 np.random.rand(dim), np.random.rand(dim) A2 2 * a * r1 - a C2 2 * r2 D_beta np.abs(C2 * beta - pop[i]) X2 beta - A2 * D_beta r1, r2 np.random.rand(dim), np.random.rand(dim) A3 2 * a * r1 - a C3 2 * r2 D_delta np.abs(C3 * delta - pop[i]) X3 delta - A3 * D_delta gwo_candidate (X1 X2 X3) / 3 # 差分进化候选使用best/1 candidates np.random.choice(pop_size, 3, replaceFalse) while i in candidates: candidates np.random.choice(pop_size, 3, replaceFalse) r1_idx, r2_idx, r3_idx candidates v_candidate best_solution F * (pop[r2_idx] - pop[r3_idx]) de_candidate pop[i].copy() rand_j np.random.randint(dim) for j in range(dim): if np.random.rand() CR or j rand_j: de_candidate[j] v_candidate[j] # 混合策略前期偏DE后期偏GWO if it max_iter / 2: candidate de_candidate else: candidate gwo_candidate candidate_fit fitness_function(candidate) if candidate_fit fitness[i]: pop[i] candidate fitness[i] candidate_fit current_best_idx np.argmin(fitness) if fitness[current_best_idx] best_fitness: best_fitness fitness[current_best_idx] best_solution pop[current_best_idx].copy() # ---------- 6. 用最优个体初始化BP并训练 ---------- # 实际项目中可用MLP模型在fit前手动设置coefs_和intercepts_ # 或者直接将best_solution作为前向预测参数使用。这里我只是给了一个最直接的骨架真实项目里还会加上边界约束、收敛曲线记录、best_solution的保存和加载。注意DE候选生成时我故意避开了每个个体选到自己这是为了避免DE变异向量退化。5. 参数设置、结果评估与典型效果5.1 网络结构参数怎么定DEGWO-BP涉及到两层结构参数BP网络结构和DEGWO进化参数。BP隐含层节点数没有绝对公式一个常用的经验起始值是输入特征数加2或者取输入输出节点数之和的平方根附近。隐含层节点太少拟合能力不足节点太多参数维度上升优化搜索空间变大反而未必更准。我在电厂负荷预测例子里用了14个输入特征、8个隐含层节点、1个输出节点单个体维度是1488811等于129。你可以算一下如果隐含层加到20个节点维度就变成14*2020201等于321搜索空间翻了好几倍。所以不要一味堆节点要按数据量和特征数合理折中。5.2 DEGWO参数的经验区间差分进化的核心参数是缩放因子F和交叉概率CR。F太小变异步长小种群容易集中F太大搜索太跳跃后期难收敛。经验取0.5到0.8之间。CR决定候选个体维度上从变异向量继承的比例0.7到0.9是我用得比较多的区间太小的CR会让DE退化成只替换少量维度效率不高。灰狼优化关键的参数是收敛因子a从2线性降到0这个基本固定。种群规模我一般取20到40迭代次数看数据量和维度像129维这个问题60代左右基本够用。如果你发现迭代曲线还在明显下降说明迭代次数设少了继续加。5.3 回归预测评估指标怎么选评估回归预测不能只看某一个指标。R2反映整体拟合优度越接近1越好RMSE对较大误差敏感能反映预测被极端点拖累的程度MAE直观反映平均误差绝对大小MAPE适合和业务方沟通表示平均百分比误差。电厂负荷预测里RMSE和MAPE是大家看得比较多的。具体某次实测中普通BP在网络结构不变、随机初始化的条件下测试集RMSE大概在12.6左右MAPE为8.4%。换成DEGWO-BP后RMSE降到9.3左右MAPE降到6.7%。这个提升幅度在工程上很有价值尤其对并网调度来说哪怕降低1%的预测误差对报价和调度策略都有明显影响。5.4 结果可视化的两个必看项第一张图是预测值和实际值的曲线对比时间序列数据这样看最直观能看出模型在波峰波谷位置的跟随能力。第二张图是适应度下降曲线也就是每次迭代的最优适应度值。如果适应度曲线是一条近乎水平的直线说明DE和GWO的混合没有产生有效搜索大概率是F或CR设置不合理如果曲线断崖式下降后长时间不动可能是早期收敛需要增大F或DE候选的使用比例。6. 常见问题与排查技巧实录6.1 训练集误差正常测试集一塌糊涂这个现象我见过太多次。大多数时候不是因为模型不行而是数据切分出了问题。如果用随机切分处理时间序列模型会看到未来数据训练误差当然漂亮真实预测却完全不对。解决办法很简单按时间顺序切分并保证归一化的min和max只来自训练集。还有一种情况是特征里包含了目标变量的滞后值比如用当前时刻功率去预测下一时刻功率这本身没有错但如果这批滞后特征在测试时拿不到实时值那模型就部署不了。做项目前先问清楚哪些特征是预测时刻可获取的Excel里有的不代表未来能实时采集到。6.2 适应度值全是NaN怎么查第一步检查Excel里有没有文本或空值。第二步检查归一化后有没有除零如果某一列特征在训练集里的max和min相等那归一化结果全是0虽然不会产生NaN但这一列就失去了区分度建议直接删掉。第三步检查预测输出里有没有因为权重太大导致的数值溢出尤其是隐含层用了指数型激活函数时权重初始化范围不能太大。DEGWO初始化范围设在[-3,3]是相对安全的如果放大到[-10,10]前期搜索非常容易爆掉。6.3 每次运行结果都不一样这是智能优化算法加神经网络的固有属性因为初始种群随机、BP初始权重随机。追求可复现的话在代码开头固定随机种子numpy.random.seed(42)这样。但我不建议完全依赖固定种子来调参更好的做法是同一组参数下跑三次取平均值看稳定性怎么样。如果三次结果波动很大说明算法的探索能力不够或者种群规模太小。6.4 Excel写入慢或丢失格式用pandas写入Excel时默认会覆盖Sheet格式这是正常的但如果程序运行到一半意外中断Excel文件容易损坏。建议先写入内存最后统一保存并且保存到一个新文件名比如result_v2.xlsx不要直接在原始文件上覆盖。数据量大的时候写入速度也会变慢可以把不需要回写的中间变量先drop掉减少内存占用。6.5 预测值全都集中在一个固定值上这说明网络输出层饱和了或者是目标变量归一化后范围太小网络学习不到差异。先检查归一化后的目标值分布如果大量值集中在0.9到1之间说明数据本身分布不均可以尝试对目标值做log变换让分布更均衡。还有一种可能是隐含层节点太少网络容量不够只能拟合出均值水平适当增加隐含层节点再试。7. 一些实操层面的补充建议这套DEGWO-BP方法并不神秘本质上是元启发式优化和神经网络结合。做这类项目我最大的体会是Excel数据处理时间是算法调参时间的三倍以上数据没准备好之前先别急着跑模型。电厂的原始运行数据质量参差不齐传感器漂移、通讯中断、现场人工输入错误都会产生脏数据预处理环节花的每一分钟最后都会在模型精度里体现出来。关于DEGWO的混合比例我最后再补充一个个人经验。前期用DE多一点是对的但到了后期也不要完全抛弃DE可以在GWO候选和DE候选之间做一个随机选择比如最后三十代里仍然保留20%的DE候选概率。这样既保持了收敛速度又能防止最优解完全陷入局部极值。这个比例不用写死根据适应度曲线微调。如果某次运行后面GWO候选完全收不住个别个体飞得太远就把F调小一点或者对候选位置做边界裁剪把超出的分量拉回初始区间。做回归预测没有一步到位的参数数据分布一变最优参数就会跟着变。每换一批数据把DEGWO的迭代曲线打出来看一眼再决定是加迭代次数还是调F比盲目套参考代码里的参数靠谱得多。希望这篇文章能帮你在自己的电厂运行数据上少走点弯路把DEGWO-BP真正用起来。