尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

概率神经网络PNN用于变压器故障诊断:DGA数据建模与MATLAB实现

概率神经网络PNN用于变压器故障诊断:DGA数据建模与MATLAB实现 简介面向MATLAB初学者的概率神经网络PNN分类预测实例专门针对变压器故障诊断问题适合学习神经网络在工业设备状态监测中的应用。压缩包内共2个文件包含一个mat数据文件和一个m脚本文件整体仅有3KB轻量便于下载与运行。案例基于历史监测数据电压、电流、温度等构建PNN模型通过输入层、模板层和分类层完成概率估计再依据贝叶斯决策输出最可能的故障类型覆盖数据预处理、模型构建、训练和测试评估等完整环节。通过该案例读者可掌握MATLAB内置pnn函数的使用方法理解PNN无需反向传播的快速学习机制并能将同样的流程迁移到其他多分类问题中提升故障检测准确性和效率。目前已有131人学习下载适合课程设计或工程应用参考。1. 用PNN做变压器故障诊断先别急着训练变压器故障诊断最常用的数据是油中溶解气体DGA分析结果。很多工程师第一反应是用BP神经网络训练一个分类模型但BP的隐藏层节点数、学习率、动量因子都要调样本少时还容易过拟合。概率神经网络PNN不一样它把每个训练样本直接作为模式层神经元通过Parzen窗估计近似贝叶斯后验概率。换句话说训练过程只是一个赋值动作唯一的超参数是平滑因子spread。这里不依赖任何现成源码包从MATLAB神经网络工具箱自带的newpnn函数出发给出从特征编码到故障分类预测的完整技术路径并重点说明spread调参和验证方式面向想快速搭建可复现模型的一线工程师。2. 概率神经网络结构贝叶斯决策与Parzen窗估计2.1 从贝叶斯决策到PNN的映射PNNProbabilistic Neural Network是Specht在1990年提出的一种前馈神经网络本质上是把Parzen窗密度估计嵌入到贝叶斯分类决策框架里。假设训练样本共有K类输入向量x被分到第k类的条件是在已知第k类条件概率密度p(x|Ck)和先验概率P(Ck)时后验概率P(Ck|x)最大。贝叶斯公式本身很简单难点在于p(x|Ck)未知。PNN不假设数据服从特定分布而是用训练样本直接估计对第k类中的每个样本xi以xi为中心放置一个高斯核最后对所有核求平均。这个估计式可以写成f_k(x) 1/(N_k (2π)^(d/2) σ^d) * Σ_i exp(-||x - xi||² / (2σ²))其中N_k是第k类样本数d是特征维数σ是平滑因子。在实际MATLAB的newpnn实现中分母常被合并到径向基函数的偏置里因为比较各类别时公共系数不影响排序。因此PNN把传统BP神经网络的学习过程变成了密度估计过程没有隐层权重训练没有学习率也没有局部极小值。这一点也让它特别适合变压器故障小样本场景。变压器故障样本往往不到几百条BP网络迭代后很容易陷入过拟合而PNN将所有训练样本直接保存只要平滑因子选择合理分类边界反而更稳定。高斯核之所以常用是因为它满足非负、积分为1等核函数基本要求而且两个核叠加后的密度估计也是连续函数正好对应真实故障数据中类别边界存在的模糊区。2.2 模式层与求和层的作用在MATLAB神经网络工具箱中PNN由一层径向基神经元和一层竞争神经元实现。严格分有输入层、模式层、求和层、输出层四部分。输入层负责把特征向量分发到模式层模式层神经元数量等于训练样本总数每个神经元的权值向量就是一个训练样本。对输入x第i个模式神经元的输出是radbas(n) exp(-n²)其中n是输入向量与权值向量的欧氏距离乘以偏置b。这里的b由spread决定可以理解为b 0.8326/spread0.8326是radbas下降到0.5时的常数。样本与训练中心距离越远输出越小。求和层按类别把模式层输出累加。如果某类有多个样本就把多个高斯峰值叠加后的结果作为该类得分。最终输出层是一个竞争层使用compet函数选取得分最大的类别。通过vec2ind即可把one-hot形式的输出矩阵转换成类别标签。用一个小例子看一下网络结构% 两特征、两类样本共4个点 P [0 1 0 1; 0 0 1 1]; % 每列是一个样本 Tc [1 1 2 2]; % 两类标签 T full(ind2vec(Tc)); % 转为指示矩阵 net newpnn(P, T, 0.3); % 创建PNN disp(net.layers{1}.size); % 模式层神经元数样本数4P是2×4矩阵函数约定列是样本行是特征。T的第一列对应[1;0]第二列也是[1;0]第三列是[0;1]第四列是[0;1]。net.layers{1}.size会返回4说明每个训练样本都作为独立的径向基中心保留在网络里。newpnn内部其实等价于先计算dist距离矩阵再叠加radbas层。2.3 关键超参数spread只控制一个变量newpnn的第三个参数spread就是上文公式中的σ。在MATLAB中spread并不是直接传给高斯核的σ而是通过偏置b 0.8326/spread映射进去。spread越大径向基函数越平缓距离很远的样本也会对决策有贡献spread越小神经元只对非常接近训练样本的区域有响应决策边界扭曲表现为训练集准确率接近100%、测试集却很低。因此spread是PNN唯一需要调节的超参数比BP网络调多个参数省事得多。另外要注意spread的合适范围取决于输入特征的尺度。如果特征没有归一化比如H2浓度上千、C2H2浓度只有个位欧氏距离会被大数值特征主导此时spread可能需要很大的值才能覆盖合理范围。所以实际流程里应该先做标准化再搜索spread。下面表格给出一个粗略起点场景参考spread范围常见问题样本量少且分布集中0.11过小时严重过拟合样本量中等特征已归一化0.52过大导致类别边界模糊高维特征样本稀疏15过小使密度估计不连续这个范围不是死规则只是帮助缩小交叉验证的搜索区间。正规做法是先标准化再取0.05到10等对数间隔搜索。3. 构建变压器故障DGA数据集特征选择与故障标签编码3.1 输入特征7种溶解气体的浓度与归一化变压器故障诊断最常用的数据来源是油中溶解气体分析DGA。正常运行和故障状态下油纸绝缘材料分解产生不同气体。常见气体及指示意义如下特征序号气体主要指示故障1H2低能量放电、局部放电2CH4中低温过热3C2H6低温过热4C2H4高温过热5C2H2电弧放电6CO固体绝缘热分解7CO2固体绝缘老化有的诊断标准把CO/CO2单独做比值也有用H2/CH4等比值特征。常见的做法是先用原始体积分数构建特征矩阵再做归一化。因为DGA数据的数量级相差很大C2H2浓度可能只有0.1μL/L而H2可能上千如果不做归一化newpnn计算欧氏距离时高浓度特征会完全淹没低浓度特征。常见做法是对每个特征减去均值再除以标准差也可以缩放到[0,1]。PNN对特征缩放很敏感训练前必须统一。如果量纲不一致spread的含义会被扭曲。我一般使用z-score标准化因为它在交叉验证中更容易处理新来的样本。3.2 故障分类标签编码类别编号与ind2vec之间的转换变压器故障类型通常划分为五到六类正常、中低温过热、高温过热、低能放电、高能放电。为了做多分类预测先把每个样本的故障类型映射为整数标签整型标签故障类型1正常2低温过热3高温过热4低能放电5高能放电newpnn无法接受整数标签作为目标矩阵必须转换为每列只有一个1的指示矩阵。用ind2vec会把每个标签对应的行置为1训练完成后用vec2ind把输出矩阵每列最大分量所在的行号还原为标签。% 将标签行向量转换为神经网络目标向量 labels [1; 2; 5; 3; 2]; T ind2vec(labels); % T是5×5稀疏矩阵 T_full full(T); % 显示完整矩阵 disp(T_full);T_full第一列是[1;0;0;0;0]因为第一个样本标签是1。注意ind2vec期望输入是行向量所以labels必须转置为1×Q。训练结束后的输出矩阵也是稀疏或数值矩阵用vec2ind直接转成列向量即可。3.3 训练集与测试集划分分层抽样而不是无脑randperm变压器DGA样本天然不均衡正常样本可能很多高能放电样本可能只有几十条。如果直接随机打乱划分出来的测试集很可能某一类缺失或比例偏差。习惯上用cvpartition做分层抽样它默认按每个类别比例分离rng(1); X rand(100, 7); % 模拟100个样本7个DGA特征 labels repmat([1;2;3;4;5], 20, 1); % 每类20个样本 cv cvpartition(labels, HoldOut, 0.25); idxTrain cv.training; idxTest cv.test; fprintf(训练样本数%d测试样本数%d\n, sum(idxTrain), sum(idxTest));cvpartition返回的对象里training和test是逻辑索引。HoldOut参数表示测试集比例这里25%。如果不用cvpartition用randperm也可以但要自己确认每个类都被采到很麻烦。在构造真实DGA数据集时还要注意同一个变压器多次采样数据不能同时出现在训练集和测试集。稳妥做法是按变压器ID划分保证同一台变压器的数据整体进入训练集或测试集。这个细节在样本少时容易被忽略但会明显高估模型在新变压器上的表现。4. MATLAB中训练PNN分类器从newpnn到sim4.1 最小可用代码训练一个变压器故障诊断PNN这一节给出一个可以直接运行的完整MATLAB代码。为了避免依赖外部DGA文件代码先用随机数据生成模拟特征和标签真实应用时只需要把X和labels替换成自己的数据。% PNN变压器故障诊断最小示例 rng(42); nSamples 150; % 样本数量 X rand(nSamples, 7); % 7个DGA气体特征随机生成模拟值 labels randi([1 5], nSamples, 1); % 5类故障随机标签 % 标准化列均值为0标准差为1 mu mean(X); sigma std(X); X (X - mu) ./ sigma; % 分层划分 70%训练 / 30%测试 cv cvpartition(labels, HoldOut, 0.3); Xtr X(cv.training, :); Ytr labels(cv.training); Xte X(cv.test, :); Yte labels(cv.test); % 训练PNNspread先设0.5后面交叉验证再调 spread 0.5; net newpnn(Xtr, ind2vec(Ytr), spread); % 分类预测 YpredVec sim(net, Xte); % 输出 5×nTest 矩阵 Ypred vec2ind(YpredVec); % 每列最大行索引 % 评估 acc mean(Ypred Yte); fprintf(测试集准确率: %.2f%%\n, acc * 100); % 混淆矩阵 confusionchart(Yte, Ypred);代码逻辑X是样本×特征矩阵但newpnn要求输入矩阵每列代表一个样本所以训练和预测时都转置。ind2vec(Ytr)把标签转为稀疏目标矩阵。sim(net, Xte)返回每个样本对应每个类别的得分vec2ind取最大得分作为预测类别。confusionchart用来检查哪些故障类别容易混淆。运行这段随机示例准确率可能只有20%左右因为特征是随机的标签也是随机的这符合预期。真正使用时应替换X和labels。上面标准化时使用全数据集计算mu和sigma严格来说有信息泄漏更合理的做法是用训练集统计量来标准化测试集后面交叉验证章节会重点强调。4.2 newpnn的三个输入参数P、T、spreadnewpnn(P, T, spread)的三个参数必须满足下面约定参数维度说明PR×Q输入样本矩阵R是特征数Q是样本数每列为样本TQ×Q目标类别矩阵由ind2vec生成每列只有一个1spread1×1平滑因子唯一需要调的参数常见错误是直接把列向量labels传给newpnn会报维度错误。另一个容易忽略的是T和P的列数必须一致也就是每个样本都要有对应标签列。如果分类数Q很大T保持稀疏矩阵会少占内存full转换只用于演示。4.3 输出矩阵原来不是概率读结果要看相对得分sim返回的YpredVec每一列是类别得分来自求和层没有经过softmax归一化所以不能直接把它当概率。但得分之间的相对大小可以当置信度参考。用max可以同时取到最大值和类别[score, idx] max(YpredVec, [], 1); Ypred idx; conf score; % 未归一化得分idx是每列最大值的行号score是最大得分。score如果接近0说明所有类别得分都低样本可能落在类别间模糊区score接近1说明某个类别明显占优。实际工程里我会把score低于0.3的输出标成待人工复核而不是硬给一个故障类型这样可以减少误判代价。5. 平滑因子spread怎么调交叉验证与网格搜索5.1 spread的过拟合与欠拟合现象PNN分类性能几乎完全由spread决定。spread过小时每个训练样本只影响很小的局部决策边界会把训练样本一个个孤立出来造成训练准确率极高、测试准确率低下的过拟合。spread过大时所有径向基神经元的重叠区域变大每个类别得分都趋向某个均值分类器退化成按样本数投票丢失细节。下面是一个典型趋势spread训练集准确率测试集准确率0.05100%62%0.298%76%0.594%82%1.085%84%2.074%81%5.061%73%当spread在1附近时训练集和测试集准确率接近模型表现最好。注意这个表格只是示意不代表任何公开数据集具体最佳值由特征缩放方式决定。如果在标准化之前用原始浓度spread最佳值可能跳到10以上这说明统一特征尺度非常重要。5.2 在MATLAB里做5折交叉验证搜索spreadspread不应拍脑袋决定。常见做法是5折交叉验证加网格搜索代码可以这样做spreadList [0.05 0.1 0.2 0.5 1.0 2.0 5.0 10.0]; rng(1); cv cvpartition(labels, KFold, 5); cvAcc zeros(length(spreadList), 1); for i 1:length(spreadList) foldAcc zeros(cv.NumTestSets, 1); for k 1:cv.NumTestSets trIdx cv.training(k); teIdx cv.test(k); % 用训练集统计量标准化训练和测试 muTr mean(X(trIdx,:)); sigTr std(X(trIdx,:)); sigTr(sigTr eps) 1; % 防止零方差特征 XtrCv (X(trIdx,:) - muTr) ./ sigTr; XteCv (X(teIdx,:) - muTr) ./ sigTr; netCv newpnn(XtrCv, ind2vec(labels(trIdx)), spreadList(i)); predCv vec2ind(netCv(XteCv)); foldAcc(k) mean(predCv labels(teIdx)); end cvAcc(i) mean(foldAcc); fprintf(spread%.2f 交叉验证准确率%.2f%%\n, spreadList(i), cvAcc(i)*100); end [bestAcc, bestIdx] max(cvAcc); bestSpread spreadList(bestIdx); fprintf(最佳spread%.2f交叉验证准确率%.2f%%\n, bestSpread, bestAcc*100);两个关键点一是在每一折内部用训练集的均值和标准差去标准化测试集避免数据泄漏二是用cvpartition自带的NumTestSets循环5次。由于PNN训练只是赋值5折交叉验证的耗时通常远小于BP网络的多次训练。5.3 选择最佳spread的另一个标准稳定性交叉验证准确率最大的spread不一定是最佳选择。当几个连续spread值准确率接近时优先选更大的那个因为大spread意味着决策边界更平滑、对噪声容忍度更高。因此建议把cvAcc打印出来后在最大准确率下降不超过0.5个百分点且spread最大的点作为最终选择。另外要结合混淆矩阵查看每个类的召回率不要只看总准确率特别是在故障类型不均衡时。6. PNN分类预测结果的三个验证细节混淆矩阵、误判样本与故障倾向输出6.1 用混淆矩阵定位易混淆的故障类型只汇报准确率在故障诊断里远远不够。变压器故障中高温过热和高能放电往往因为特征接近被错分。用confusionchart可以直接看到哪些类别互相混淆confusionchart(Yte, Ypred);对角线数字大说明预测稳定非对角线数字大说明两个类别特征区分度不足。PNN没有训练权重改模型本身不能解决类间重叠问题只能通过增加有效特征或剔除冗余特征来改善。6.2 用输出得分识别低置信度样本分类预测输出每列的最大得分可以当置信度参考。建议设置阈值比如得分低于0.3就标为需复核低于0.1标为无法判断[score, pred] max(YpredVec, [], 1); pred pred; lowConf score 0.3; fprintf(低置信度样本数: %d\n, sum(lowConf));对低置信度样本可以查看该样本的原始DGA特征结合三比值法等传统判据进行人工判断。这也是PNN的优势输出得分保留了相对倾向而不是像BP那样只给一个硬分类结果。6.3 小样本下用留一法验证如果变压器故障数据只有几十到一百多条5折交叉验证的偏差偏大更稳妥的是留一法。MATLAB代码如下n size(X,1); looPred zeros(n,1); for i 1:n trIdx true(n,1); trIdx(i) false; teIdx false(n,1); teIdx(i) true; netLoo newpnn(X(trIdx,:), ind2vec(labels(trIdx)), bestSpread); looPred(i) vec2ind(netLoo(X(teIdx,:))); end looAcc mean(looPred labels); fprintf(留一法准确率: %.2f%%\n, looAcc*100);留一法需要训练n次但PNN没有迭代速度可以接受。注意这里的X使用标准化后的特征更严谨的做法是在循环内用训练集统计量再标准化一次。最终如果留一法准确率明显低于5折交叉验证说明模型对样本敏感泛化能力有限需要回到特征工程重新处理训练数据。本文还有配套的精品资源点击获取
返回列表