
简介面向电力系统状态监测与机器学习应用研究者的学术文献聚焦变压器故障诊断中油中溶解气体浓度到故障类型的非线性映射难题。论文发表于《上海电力学院学报》2014年第3期提出在标准粒子群算法中引入动态变异操作并与误差反向传播算法结合为混合训练策略用于优化BP神经网络初始权值与阈值有效缓解传统BP网络收敛缓慢、易陷入局部极小的问题。内容涵盖BP算法推导、附加动量改进、PSO寻优流程及仿真对比并给出具体诊断算例可直接借鉴其算法流程与参数设置。压缩包共1个PDF文件总大小约280KB单篇全文便携易存无需额外安装即可阅读。已有139人学习浏览信息密度高适合电力系统研究生、故障诊断工程师及相关算法开发者作为方法参考与代码复现的文献依据。1. 变压器故障诊断的智能化路线改进 PSO-BP 混合算法到底改了什么做电力设备状态监测的工程师对油中溶解气体分析DGA都不陌生。变压器内部发生过热或放电时绝缘油会分解出 H₂、CH₄、C₂H₆、C₂H₄、C₂H₂ 等特征气体气体组分和浓度与故障类型之间存在映射关系但这种映射高度非线性靠人工经验和三比值法去判经常遇到边界模糊、误判率高的问题。这篇论文的核心做法是把粒子群算法PSO做了动态变异改进再与 BP 神经网络组合成混合算法用改进 PSO 去搜索 BP 的初始权值和阈值把 BP 最容易踩的局部极小值坑提前规避掉。从结果看改进 PSO-BP 在 63 组测试样本上的诊断正确率达到 87.30%比标准 PSO-BP 的 85.71% 和纯 BP 的 82.52% 都有提升。收敛速度方面改进后的算法在更少的迭代代数内就能把训练误差压下来。适合谁看手里有 DGA 历史数据、想用神经网络做故障诊断建模的电力工程师或者在做 PSO 优化神经网络方向课题的研究生。本文会把这套算法的原理、参数设置、实现步骤和踩坑点全部拆开讲清楚。2. BP 神经网络的困境与 PSO 的改进思路先搞明白为什么混在一起2.1 BP 网络的结构与梯度下降的局限BP 神经网络是多层前馈网络信号前向传播、误差反向传播。每一层神经元的状态只影响下一层前向传播的输出和期望输出之间的误差不满足精度要求时就沿误差的负梯度方向调整各层权值和阈值反复迭代直到误差达标。原理听着简单但它是纯梯度下降方法不考虑历史经验积累实际训练中有两个很头疼的问题第一收敛慢。梯度下降在误差曲面平坦区走得很慢在陡峭区又容易震荡。第二容易陷入局部极小值。误差曲面通常很复杂随机初始化落在哪个极小值附近训练大概率就停在那个坑里导致最终训练后的网络泛化能力下降。论文里采用的一个缓解手段是附加动量法。权值学习公式长这样# 附加动量法的权值更新公式 # w(k) w(k-1) Δw(k) α * [w(k-1) - w(k-2)] def update_weight_with_momentum(w_prev, w_prev2, delta_w, alpha): w_prev: k-1 时刻的权值 w_prev2: k-2 时刻的权值 delta_w: 当前权值修正量 alpha: 动量学习率通常取 0.5~0.95 w_current w_prev delta_w alpha * (w_prev - w_prev2) return w_current这里的关键是最后一项alpha * (w(k-1) - w(k-2))它把上一次的权值变化方向叠加进来。当误差曲面出现局部极小值时梯度接近零普通 BP 会停下来但动量项带着历史变化惯性可以帮网络冲过平坦区或者小的局部坑。代价是 alpha 不能取太大否则权值更新过头网络误差震荡不收敛。但附加动量只是缓解解决不了根本问题。误差曲面极其复杂时初始权值选在哪个区域基本决定了网络能不能收敛到理想的解。这就是为什么需要 PSO 来专门搜索一组好的初始权值阈值。2.2 标准 PSO速度和位置更新公式与收敛特性粒子群算法的灵感来自鸟群觅食。每个粒子是解空间里的一个点代表问题的一个潜在解。粒子有速度和位置两个属性每次迭代时每个粒子根据自己找到过的最好位置个体极值 P_id和整个种群找到过的最好位置群体极值 P_gd来更新自己的速度和位置。速度和位置更新公式如下# 标准 PSO 速度与位置更新 def pso_update(v, x, p_best, g_best, w, c1, c2, r1, r2): v: 粒子当前速度 x: 粒子当前位置 p_best: 个体极值 g_best: 群体极值 w: 惯性权重控制上一时刻速度对当前速度的影响 c1: 个体学习因子通常取 1.5~2.0 c2: 群体学习因子通常取 1.5~2.0 r1, r2: 在 [0, 1] 之间均匀分布的随机数 v_new w * v c1 * r1 * (p_best - x) c2 * r2 * (g_best - x) x_new x v_new return v_new, x_new三个项的作用要理解到位惯性项w * v保留粒子之前的速度让粒子有延续性个体认知项c1 * r1 * (p_best - x)把粒子拉向它自己发现过的好位置社会认知项c2 * r2 * (g_best - x)把粒子拉向种群发现过的好位置。c1 和 c2 是非负常数r1 和 r2 是随机数提供搜索的随机性。标准 PSO 的优点很突出收敛快、通用性强、不需要梯度信息。但缺点同样明显所有粒子都在朝当前最优位置逼近如果这个最优位置只是局部最优整个种群就会被吸住失去在解空间内重新搜索的能力这就是所谓的早熟收敛。后期迭代效率也会明显下降因为粒子位置越来越集中种群多样性变差。2.3 动态变异线性变异概率公式与参数含义针对标准 PSO 的早熟问题论文引入了一个线性动态变异算子让变异概率随迭代进度逐步增大。变异概率的计算公式为# 线性动态变异概率 def dynamic_mutation_probability(iter_current, iter_max, p_max, p_min): iter_current: 当前迭代次数 iter_max: 最大迭代次数 p_max: 最大变异概率论文中取 0.35 p_min: 最小变异概率论文中取 0.01 p_current p_max - (p_max - p_min) * (iter_current / iter_max) return p_current注意这个公式是从论文中的形式整理过来的。核心逻辑是迭代初期变异概率接近 p_min种群几乎不发生变异保证粒子群集中搜索当前有利区域迭代后期变异概率逐步逼近 p_max粒子以越来越大的概率被重新初始化从而跳出当前搜索区域到更大空间里去寻找可能被遗漏的全局最优解。为什么变异概率不能全程都大因为变异操作意味着某些粒子会被随机重置如果概率过大每一代的最优个体可能被破坏算法就退化成随机搜索了。所以 p_max 取 0.35 而不是 0.5 或更高就是为了在保留历代最优个体和维持种群多样性之间找平衡。p_min 取 0.01 保证迭代初期几乎不变异让算法先正常收敛。这个参数设计思路和遗传算法里的变异概率是异曲同工本质上都是用小概率扰动来防止种群的搜索空间收缩得过快。3. 混合算法落地网络结构确定、粒子编码与完整流程3.1 网络拓扑3-35-6 结构的确定逻辑这个诊断任务的输入输出结构是明确的。输入特征选了 H₂、CH₄、C₂H₆、C₂H₄、C₂H₂ 五种气体的三个比值C₂H₂/C₂H₄、CH₄/H₂、C₂H₄/C₂H₆所以输入层是 3 个节点。输出是 6 种状态无故障、中低温过热、高温过热、局部放电、低能量放电、高能量放电采用 one-hot 编码对应故障类型期望输出为 1其余为 0所以输出层是 6 个节点。隐含层节点数才是真正需要斟酌的。论文的做法很朴素但非常有效把隐含层节点数从 1 遍历到 46记录每种结构下的网络预测误差和。结果在节点数为 4、5、29、31、35、36 时误差相对最小最终选定 35。这个选择背后是两层考量样本数只有 100 组训练数据隐含层太多容易出现过拟合逼近映射的复杂程度又要求足够的隐含层容量。表里的数据也说明了这一点节点数 4 时误差 46.61节点数 35 时误差 44.03差异没有想象中那么大但 35 在这个任务下是更稳妥的选择。# 隐含层节点数遍历的伪代码示意 def find_best_hidden_units(X_train, y_train, X_test, y_test, max_units46): errors {} for n_units in range(1, max_units 1): net BPNetwork(input_size3, hidden_sizen_units, output_size6) net.train(X_train, y_train, epochs300) pred net.predict(X_test) errors[n_units] sum(abs(pred - y_test)) # 找出误差最小的节点数组合 sorted_errors sorted(errors.items(), keylambda x: x[1]) return sorted_errors[:10] # 取前 10 个候选这里要提醒一件事隐含层节点数不是越大越好。节点数少网络拟合能力不足误差降不下来节点数过多网络可能把训练样本的噪声也学进去测试集误差反而反弹这就是经典的过拟合。遍历 46 组然后挑误差最小的是学术论文里正规的做法工程实践里如果算力有限可以只扫 5、10、15、20、25、30、35、40 这八个点趋势基本能看明白。3.2 粒子编码设计与适应度函数粒子群优化神经网络核心是把网络的权值和阈值编码成粒子的位置向量。3-35-6 的网络结构下权值数量是 3×35 35×6 105 210 315 个阈值数量是 35 6 41 个所以每个粒子的维度是 315 41 356。种群规模 30就意味着一开始随机撒了 30 个 356 维的粒子在解空间里。适应度函数用于评价每个粒子的好坏。论文用的是网络训练后预测输出和期望输出之间的误差绝对值之和公式为# 适应度函数预测误差绝对值之和 def fitness_function(y_pred, y_true, k1): y_pred: 网络预测输出 y_true: 网络期望输出 n: 测试样本总数 k: 常数系数通常取 1 F k * (sum(|y_pred_i - y_true_i|) / n) n len(y_true) error_sum sum(abs(p - t) for p, t in zip(y_pred, y_true)) F k * (error_sum / n) return F适应度值越小说明粒子对应的这组权值和阈值越优秀。粒子群每一次迭代都要把 356 维的位置向量解码成网络的权值和阈值跑一遍前向传播算出预测输出再算适应度值。这个过程计算量不小所以种群规模不能无脑加大论文里种群规模 30、最大迭代次数 300 是在个体长度、搜索速度和运行时长之间权衡后的结果。3.3 完整流程从粒子初始化到最优权值阈值赋值整个混合算法的流程可以分为三大块网络结构确定、粒子群优化、网络训练预测。具体步骤是第一步根据输入参数个数3 个气体比值和输出参数个数6 种故障类型确定网络拓扑结构 3-35-6第二步根据权值和阈值的总个数确定粒子个体长度 356第三步初始化 30 个粒子的速度和位置每个粒子携带一组完整的权值和阈值第四步迭代开始每个粒子解码出网络参数前向传播计算预测输出代入适应度函数得到适应度值第五步更新个体极值和群体极值第六步按动态变异概率判断是否对粒子重新初始化第七步更新粒子速度和位置第八步判断是否达到最大迭代次数 300未达到则回到第四步第九步将算法找到的最优个体解码为网络的初始权值和阈值赋值给 BP 网络第十步BP 网络继续训练到误差满足精度要求输出预测结果。# 改进 PSO-BP 混合算法的主流程 def improved_pso_bp(X_train, y_train, X_test, y_test): # 网络结构 input_size, hidden_size, output_size 3, 35, 6 dim input_size * hidden_size hidden_size * output_size \ hidden_size output_size # 356 # PSO 参数 swarm_size 30 max_iter 300 w 0.6 # 惯性权重 c1, c2 2.0, 2.0 # 学习因子 p_max, p_min 0.35, 0.01 # 1. 初始化粒子群 swarm [initialize_particle(dim) for _ in range(swarm_size)] p_best [ind.copy() for ind in swarm] g_best swarm[0].copy() # 2. 迭代寻优 for t in range(max_iter): p_mut dynamic_mutation_probability(t, max_iter, p_max, p_min) for i, particle in enumerate(swarm): fitness fitness_function( bp_predict(particle, X_train), y_train) if fitness fitness_function(bp_predict(p_best[i]), y_train): p_best[i] particle.copy() if fitness fitness_function(bp_predict(g_best), y_train): g_best particle.copy() # 3. 动态变异 if random.random() p_mut: particle initialize_particle(dim) # 重新初始化 # 4. 速度和位置更新 v update_velocity(v, particle, p_best[i], g_best, w, c1, c2) particle[:] particle v # 5. 用全局最优个体初始化 BP 网络并训练 bp_net BPNetwork(input_size, hidden_size, output_size) bp_net.load_weights(g_best) bp_net.train(X_train, y_train, epochs500) # 6. 预测 return bp_net.predict(X_test)这段代码的关键点是变异操作发生在速度位置更新之前被选中的粒子直接重新随机初始化它的历史速度也跟着重置适应度值的计算使用训练集数据但最终评估网络好坏用的是测试集数据。实际调试时最容易犯的错是把适应度函数里的样本数 n 搞混——公式里分母是测试样本总数如果训练时用了全量样本要相应修改。4. 故障诊断实战DGA 特征选择与 163 组样本的实验设计4.1 特征选择为什么用三比值而不是直接输入五种气体浓度神经网络的输入特征直接决定模型的学习上限。直接输入 H₂、CH₄、C₂H₆、C₂H₄、C₂H₂ 五种气体的浓度值理论上可行但有一个很实际的问题不同变压器的油体积不同、负荷水平不同气体浓度的绝对值差异很大神经网络很容易因为输入数值范围过大而饱和导致训练不收敛或者收敛到很差的解。论文采用了三比值特征C₂H₂/C₂H₄、CH₄/H₂、C₂H₄/C₂H₆。这个做法的来源是经典的罗杰斯比值法和 IEC 三比值法——C₂H₂/C₂H₄ 反映放电性故障CH₄/H₂ 反映局部放电和过热C₂H₄/C₂H₆ 反映热性故障的温度区间。用比值天然消除了油量和负荷差异带来的数值尺度问题也是 DGA 诊断领域的标准做法。注意三比值法的局限比值编码对某些边界故障样本是无效的例如两种气体的比值都接近 1 时编码可能落入未定义区域。但作为神经网络的输入特征比值本身仍然携带了足够的信息量因为网络学习的是连续映射不像传统三比值法需要离散编码。4.2 数据集构建163 组样本的类别分布与划分策略论文收集了 163 组变压器故障数据类别分布如下故障类型样本数占比无故障2213.50%中低温过热4024.54%高温过热4628.22%局部放电106.13%低能量放电53.07%高能量放电4024.54%这个分布非常不平衡局部放电只有 10 组低能量放电只有 5 组。数据划分策略是各类别内部先随机打乱再按比例取前 100 组做训练剩余 63 组做测试。这样保证训练集和测试集里都包含各类别样本避免某类故障在测试集里完全缺失。作为对比常见的错误做法是直接对整个数据集随机切分不按类别分层。如果低能量放电的 5 组样本恰好全进了测试集训练集里就完全没见过这类故障模型对它天然是盲的。分层抽样虽然不能解决数据量少的问题但至少保证了训练集和测试集分布一致。4.3 实验结果三个算法的正确率对比与逐类分析三种算法的诊断结果对比如下诊断算法正确率BP82.52%PSO-BP85.71%改进 PSO-BP87.30%改进 PSO-BP 比纯 BP 提高了 4.78 个百分点比标准 PSO-BP 提高了 1.59 个百分点。提升幅度看起来不大但注意测试集只有 63 组样本每提升一个正确率意味着至少多判对一两个样本对于变压器这种高价值设备的故障诊断每一个准确判对的样本都对应着一次可能避免的停电事故或设备损坏。从训练误差曲线看无优化的 BP 网络训练误差明显大于两个优化后的网络改进 PSO-BP 相比标准 PSO-BP训练误差下降得更快在更少的迭代代数内就达到了相近的误差水平。这说明动态变异的引入确实帮助算法跳出了局部极小值——标准 PSO 在迭代中后期粒子聚集后容易停在某个次优区域而动态变异让部分粒子在后期脱离群体去更远的地方搜索。逐类诊断结果中有一个很值得注意的现象无故障和局部放电这两类的正确率偏低。论文给出的解释是这两类用于网络训练的数据太少没有建立起良好的映射关系。局部放电测试样本虽然少但结果正确原因是它的测试样本特征与训练时的同类样本较接近。这里揭示了一个工程问题不平衡数据下少样本类别是模型误判的高发区域后续可以考虑用 SMOTE 过采样或代价敏感学习来缓解。5. 避坑与常见问题从参数调到数据集划分的五个坑5.1 隐含层节点数选错网络要么欠拟合要么过拟合现象按照 3-35-6 结构训练时误差能降下来但改成 3-10-6 后训练误差一直不下去改成 3-80-6 后训练误差很低测试集正确率反而下降。原因隐含层节点数太少网络容量不足映射能力受限节点数太多网络把训练样本中的噪声细节也学了去泛化能力下降。解决老老实实做节点数遍历。不要只试两三个值就拍脑袋选一个至少要在 1 到 46 的范围内扫一遍找出误差和最小的若干个候选节点数再结合样本量选一个偏中间的值。如果算力不允许全遍历最少也要覆盖从小到大的 8 个点观察误差曲线的变化趋势找拐点附近的值。5.2 数据不平衡导致少数类故障诊断盲区现象整体正确率看着还行87.30%但拆开看无故障和局部放电两类正确率明显低于其他类别。如果只报总体准确率这个问题很容易被忽视。原因训练集里局部放电只有约 6 组数据100 组的 6.13%低能量放电约 3 组样本太少导致网络很难学到这两类的稳定特征边界。解决至少要分层抽样确保各类别在训练集和测试集中的比例与整体分布一致。数据量允许时可以做数据增强对少样本类别的特征向量加小幅噪声生成合成样本。还有一个更实用的思路把二分类或多分类改造成层次分类——先分大类无故障、过热、放电再在过热和放电内部细分温度区间和能量级别让每一级的样本平衡度更好。5.3 变异概率设置不当要么不起作用要么破坏收敛现象把 p_max 设置成 0.8 后训练误差在后期反而出现明显波动甚至最优个体的适应度值变差把 p_max 设为 0.05收敛曲线和标准 PSO 几乎一样动态变异形同虚设。原因变异概率过大时即使迭代后期大量粒子被随机重置可能覆盖掉历史最优个体变异概率太小粒子无法跳出局部最优区域改进效果消失。解决遵循论文的参数范围p_max 取 0.3~0.4p_min 取 0.01~0.05。每一代更新完最优个体后可以加一个保护逻辑判断当前最优粒子是否被变异影响如果是保留变异前的最优副本。工程实现上代码里需要单独记录 g_best 的备份变异操作不针对 g_best 所指向的粒子执行。5.4 收敛判据只看训练误差忽略测试集表现现象训练误差降到 0.001 以下但测试集上正确率只有 70% 出头明显过拟合。原因BP 网络在训练集上迭代次数过多把样本噪声学进去了。改进 PSO 优化初始权值后BP 本身的训练仍然可能过拟合尤其当训练 epochs 设得很大的时候。解决训练过程中每过一定的 epoch比如每 50 代就在测试集上测一次误差记录测试误差最低时的模型参数训练结束时回滚到那个最优快照。好习惯是训练和测试曲线画在同一张图上观察训练误差持续下降而测试误差开始回升的那个交叉点那就是合适的停止迭代位置。5.5 PSO 迭代不收敛检查随机数种子与粒子初始化范围现象同一个数据集跑多次正确率在 80% 到 87% 之间波动有一次甚至只收敛到很差的解。原因粒子初始化范围和随机数种子对 PSO 的影响非常大。初始化范围太宽粒子在有效解区域外的无效空间里浪费大量迭代范围太窄粒子分布密集很快就聚集到局部最优。解决权值和阈值的初始化范围通常取 [-1, 1] 或 [-0.5, 0.5]。跑实验时固定几个随机种子分别记录结果取平均值或中位数作为最终指标而不是只报告最好的一次。论文里的 87.30% 也应该理解成多次实验的典型值不是必然复现值。6. 把诊断结果做实典型样本的预测输出解析与落地技巧6.1 三个典型样本的 DGA 数据与预测输出对照论文给出了三个典型故障样本的测试结果。用三比值法判断为高温过热、低能放电和高温过热改进 PSO-BP 的预测输出与之一致。这三个样本的预测输出向量实际含义是向量中对应故障类型的位置数值接近 1其余位置接近 0。比如预测输出向量中索引 2高温过热位置为 0.92其他位置均小于 0.05说明网络对该样本的置信度较高。工程上判断预测结果时不要只看 argmax 的输出索引还要看最大值和第二大值的差距。差距大于 0.3 时可以置信差距小于 0.1 说明网络在两类故障之间摇摆这种情况宁可人工复核也不要直接按最大概率输出去执行检修策略。6.2 复现时如何快速验证算法实现是否正确一个实用技巧先用纯 BP 在 163 组数据上跑一遍正确率应该在 82% 左右。如果纯 BP 的结果偏差太大先排查数据预处理环节再跑标准 PSO-BP正确率应该在 85% 上下最后跑带动态变异的改进版本87% 附近。如果底线结果对不上后两个算法的改进效果就没有参考意义。我个人的习惯是先把适应度函数的计算逻辑单独抽出来做单元测试用一组已知权值阈值的网络验证前向传播输出是否正确再接入 PSO 迭代。因为 PSO 迭代一旦跑起来300 代 × 30 粒子 × 356 维参数排错的成本非常高不如在最前面把基础环节固定住。6.3 把动态变异思路迁移到其他诊断场景这套改进 PSO-BP 的框架不限于变压器 DGA 诊断。滚动轴承故障诊断、GIS 局部放电模式识别、电机定子匝间短路诊断只要是特征到故障类型的非线性映射问题都可以套用。需要改的只有输入特征维度、输出类别数、隐含层节点数重新遍历确定这三个环节。从那以后我每次做 PSO 优化神经网络的实验都强制走一遍固定随机种子、分层抽样、隐含层遍历、测试误差回滚这四步省了很多翻车重来的时间。这份论文资源里包含了完整的算法推导、参数设置和各步骤误差数据照着复现一遍比看十篇综述都管用希望帮到你。本文还有配套的精品资源点击获取