十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

RBF-BP复合神经网络在变压器DGA故障诊断中的应用实践

RBF-BP复合神经网络在变压器DGA故障诊断中的应用实践 简介这是一篇面向电力运维人员、电气工程学生及神经网络算法学习者的学术论文PDF。资源围绕变压器故障诊断场景提出RBF-BP复合神经网络模型借助RBF网络实现非线性快速逼近再将结果输入BP网络完成故障判别并以DGA油中溶解气体数据为输入覆盖无故障、中低温过热、高温过热、低能量放电、高能量放电五类常见故障。文中给出了五层复合网络结构、高斯函数与Sigmoid函数配置、45组训练样本与5组检验样本的仿真流程并附有实际输出数据对比表便于读者复现和掌握复合网络构建思路。压缩包共1个文件为PDF格式大小1.23MB排版清晰包含图表与结论分析。该资源已有117人学习浏览可作为电力设备故障诊断及神经网络应用研究的有益参考。1. 变压器故障诊断为什么要用RBF-BP复合神经网络变压器内部发生热故障或放电故障时绝缘油会分解出特征气体。DGA油中溶解气体分析是现场最容易采集到的数据但传统三比值法有一块硬伤当气体比值不在编码表内时直接判不出类型。单用BP网络能拟合非线性关系却因为变压器样本量小、特征维度低训练经常陷进局部极小单用RBF网络局部响应灵敏但基函数中心选不好整体精度波动很大。RBF-BP复合神经网络把RBF层当作一种自适应特征映射再由BP层做全局分类既能吸收局部敏感度又保留了反向传播的判别能力。下面按我实际调试这套模型的经验从特征构造、网络搭建到参数设置一步步拆开讲适合做电力设备状态监测和后端算法落地的人参考。2. 先定输入DGA气体特征与故障标签的编码方式2.1 七种气体、五种故障类型输入层怎么设计变压器故障诊断用的输入特征绝大多数来自油中溶解气体分析。最常用的是七种气体H2、CH4、C2H6、C2H4、C2H2、CO、CO2。这七种气体在不同故障类型下会有不同的产气规律比如局部放电主要产氢高温过热主要产乙烯电弧放电会同时产乙炔和氢。故障类型一般归纳为五类低温过热、高温过热、局部放电、低能放电、高能放电有时也会把“正常”单独作为一类。我一般把输入层定为7维也就是七种气体的体积分数或归一化浓度输出层用One-Hot编码类别数是几类就设几个神经元。气体浓度绝对不能直接裸着喂进网络。不同变压器的油量、负荷、采样时间不同绝对浓度可差两个数量级。常见的做法是先做对数变换log(1x)压掉极端高值再用MinMaxScaler缩放到0到1。CO和CO2这对气体要特别注意它们和固体绝缘老化有关在区分过热与放电时作用明显但经常和总烃耦合所以我在项目里会把它们也放进特征而不是单独剔除。下表是七种气体与主要故障的粗略对应帮助建立直觉。气体主要关联故障H2局部放电、电弧放电CH4低温过热、放电初期C2H6中低温过热C2H4高温过热C2H2高能放电、电弧放电CO固体绝缘过热CO2固体绝缘老化2.2 构造RBF-BP训练集的Python代码下面这段代码从CSV读入DGA实测数据生成RBF-BP网络需要的特征矩阵X和标签矩阵y。数据文件里至少要有七列气体浓度和一列故障类型。import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler, OneHotEncoder df pd.read_csv(dga_samples.csv) # 假设列名: h2, ch4, c2h6, c2h4, c2h2, co, co2, fault_type gas_cols [h2, ch4, c2h6, c2h4, c2h2, co, co2] X_raw df[gas_cols].values # 对数变换后再归一化防止个别气体浓度过大主导梯度 X_log np.log1p(X_raw) scaler MinMaxScaler(feature_range(0, 1)) X scaler.fit_transform(X_log) encoder OneHotEncoder(sparse_outputFalse) y encoder.fit_transform(df[[fault_type]])代码说明log1p对零浓度值友好避免出现log(0)MinMaxScaler把特征压到0到1区间统一量纲OneHotEncoder把故障类型字符串变成稀疏矩阵对应的稠密向量sparse_outputFalse是scikit-learn 1.2之后的写法老版本用sparseFalse。要注意fit_transform是同时拟合并转换后面做交叉验证时必须只在训练集上fit再transform验证集和测试集否则会有数据泄漏。2.3 为什么单一BP或RBF做变压器故障诊断都不够稳单一BP网络是全局逼近器每一个训练样本都会更新所有权值。DGA样本通常只有几百条七维输入对BP来说结构偏简单训练时容易过拟合而且初始权值不同会导致多次训练结果差异很大。更麻烦的是故障类型之间边界并不清晰比如低能放电和高能放电在气体比例上只差一个数量级BP网络很容易在边界处震荡。单一RBF网络是局部逼近器每个基函数只对靠近自己中心的输入产生明显响应。RBF的中心通常用K-Means聚类得到中心数量定少了欠拟合定多了又会把故障边界切碎。而且RBF输出层的权值虽然可以用最小二乘法求解但一旦中心选择不理想局部响应区域会出现空洞。RBF-BP复合网络的做法是用RBF层把样本映射到高维空间保留局部敏感特性再用BP层做加权组合和分类决策。这样RBF负责“感知相似度”BP负责“划分边界”正好互补。3. 搭一个最小可见的RBF-BP复合神经网络3.1 串联结构RBF层做高维映射BP层做决策我采用的RBF-BP复合网络是串联型结构而不是并联投票。串联型把RBF层的输出直接作为BP层的输入梯度传播路径短训练时不容易发散。具体结构如下输入层7维DGA特征。RBF层M个高斯基函数每个基函数输出exp(-||x-c_i||^2 / (2*sigma_i^2))。BP层一个全连接隐层加ReLU激活再接输出层。输出层softmax前的logits类别数等于故障类型数。这里面的关键点是RBF层的中心和宽度怎么确定。我一般先对训练集跑K-Means把M个聚类中心作为c_i每个中心到最近两个中心的距离均值作为sigma_i的初始值。这样RBF层每个基函数都覆盖一个局部分布区域不会出现两个中心重叠太多或完全分离的情况。RBF层的输出向量表示“输入样本和各故障模式中心的相似度”BP层再在这个相似度空间里学习分类边界。3.2 核心参数节点数、基函数宽度、学习率RBF-BP复合网络里最影响效果的参数集中在RBF层和BP隐层。下面是我常用的一组初始范围实际项目里围绕这些值做网格搜索。参数推荐范围说明RBF节点数M8~20少于7维输入容易欠拟合多于30在小样本下过拟合基函数宽度sigma0.1~1.0由K-Means距离自动估计后乘0.8~1.2缩放BP隐层节点数5~15可以设0层直接softmax但带一层能处理复杂边界学习率0.001~0.01Adam/RMSProp建议默认SGD才需要手动调批量大小16~32DGA样本少全批量训练也常见迭代轮数100~300配early stopping看验证集loss基函数宽度sigma是最敏感的参数。sigma太小每个基函数只响应周围极近的点RBF层输出的向量非常稀疏sigma太大所有基函数输出都趋于相同常数RBF层等于白设。我推荐先用K-Means距离自动估计然后跑一次验证集根据准确率按0.1的步长微调。3.3 RBF-BP复合网络训练代码与参数说明下面用PyTorch实现一个最小可跑的版本。自定义的RBFLayer接收输入并计算高斯径向基函数输出RBFBPNet把RBF层接到两个全连接层上。训练时只更新BP层的权值RBF中心和sigma保持不变这样能避免梯度把中心推离样本分布。import torch import torch.nn as nn import torch.optim as optim from sklearn.cluster import KMeans class RBFLayer(nn.Module): def __init__(self, centers, sigma): super().__init__() self.centers torch.tensor(centers, dtypetorch.float32) self.sigma torch.tensor(sigma, dtypetorch.float32) def forward(self, x): # x: (batch, features) diff x.unsqueeze(1) - self.centers.unsqueeze(0) # (batch, M, features) dist_sq (diff ** 2).sum(dim-1) return torch.exp(-dist_sq / (2 * self.sigma ** 2)) class RBFBPNet(nn.Module): def __init__(self, kmeans_centers, sigma, bp_hidden8, num_classes5): super().__init__() M kmeans_centers.shape[0] self.rbf RBFLayer(kmeans_centers, sigma) self.fc1 nn.Linear(M, bp_hidden) self.fc2 nn.Linear(bp_hidden, num_classes) def forward(self, x): rbf_out self.rbf(x) h torch.relu(self.fc1(rbf_out)) return self.fc2(h) # 假设X, y已经通过第2章代码得到且X只在训练集上完成归一化 kmeans KMeans(n_clusters10, random_state0).fit(X) centers kmeans.cluster_centers_ sigma 0.5 model RBFBPNet(centers, sigma, bp_hidden8, num_classesy.shape[1]) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.005) X_t torch.tensor(X, dtypetorch.float32) y_t torch.tensor(y.argmax(axis1), dtypetorch.long) for epoch in range(200): model.train() optimizer.zero_grad() out model(X_t) loss criterion(out, y_t) loss.backward() optimizer.step() if epoch % 50 0: print(fepoch {epoch}, loss {loss.item():.4f})代码逻辑说明RBFLayer计算输入与每个中心的欧氏距离平方经高斯核函数输出M维向量维度与聚类中心数相同RBFBPNet将RBF输出接一个全连接层和输出层输出未经过softmax的logits。训练时候CrossEntropyLoss内部自带softmax所以输出层不再额外接Softmax。注意centers和sigma在这里是普通torch.tensor不会参与梯度更新。如果想让中心和sigma也参与训练需要改成nn.Parameter但小样本下容易训练不稳定不推荐。3.4 防止数据泄漏的几个细节RBF中心必须只由训练集拟合。如果对全量数据做K-Means再划分测试集测试样本的信息会通过中心位置泄露进网络评估指标会虚高。归一化的scaler同样只能fit训练集。你可以在交叉验证循环里对每一折重新fit也可以先fit在训练集上再复用。样本划分时要按故障类型分层。直接随机划分可能导致某类故障全在测试集里模型对这一类的准确率表现为0。4. 实验验证分层交叉验证、训练曲线与混淆矩阵4.1 数据划分与数据集来源变压器故障诊断方向没有统一的大规模公开数据集这是实际落地的第一道坎。常见做法有三条一是用实验室或运维单位的历史油色谱台账字段包括日期、七种气体浓度、故障类型故障类型必须经过吊芯检查或电气试验确认二是从IEC TC 10或国内论文的典型案例表里手工录入一条案例就是一行记录三是自己用三比值法规则生成合成样本但合成样本会丢掉现场噪声只能用来验证网络结构能不能收敛。样本量一般就是200到800条。这个规模下网络结构必须小交叉验证比留出法更可靠。我在项目里常用5折分层交叉验证每折训练时留出20%作为验证集做early stopping最后报告那5折测试集上的平均指标。4.2 交叉验证与评估代码下面这段代码在5折交叉验证里每一折都对原始浓度做log1p变换再在训练折上fit归一化scaler然后用训练折重新拟合K-Means中心。这样能确保测试折没有任何信息参与训练。from sklearn.model_selection import StratifiedKFold from sklearn.metrics import accuracy_score, confusion_matrix from sklearn.preprocessing import MinMaxScaler skf StratifiedKFold(n_splits5, shuffleTrue, random_state42) accs [] conf_mats [] for train_idx, test_idx in skf.split(X_log, y.argmax(axis1)): scaler MinMaxScaler().fit(X_log[train_idx]) X_train scaler.transform(X_log[train_idx]) X_test scaler.transform(X_log[test_idx]) y_train y[train_idx] y_test y[test_idx] kmeans KMeans(n_clusters10, random_state0).fit(X_train) model RBFBPNet(kmeans.cluster_centers_, sigma0.5, bp_hidden8, num_classesy.shape[1]) optimizer optim.Adam(model.parameters(), lr0.005) X_train_t torch.tensor(X_train, dtypetorch.float32) y_train_t torch.tensor(y_train.argmax(axis1), dtypetorch.long) X_test_t torch.tensor(X_test, dtypetorch.float32) y_test_t torch.tensor(y_test.argmax(axis1), dtypetorch.long) for _ in range(150): model.train() optimizer.zero_grad() loss criterion(model(X_train_t), y_train_t) loss.backward() optimizer.step() model.eval() with torch.no_grad(): pred model(X_test_t).argmax(dim1).numpy() accs.append(accuracy_score(y_test.argmax(axis1), pred)) conf_mats.append(confusion_matrix(y_test.argmax(axis1), pred)) print(平均准确率: {:.4f} (/- {:.4f}).format(np.mean(accs), np.std(accs)))这段代码里最容易被忽略的是criterion变量它是在交叉验证外定义的CrossEntropyLoss实例循环里复用没问题。K-Means的random_state0固定否则每一折的中心位置会因随机初始化漂移导致结果不可复现。conf_mats存了每一折的混淆矩阵后面可以累加后按行归一化看每类的召回情况。4.3 读懂指标精确率、召回率和混淆矩阵平均准确率只是一个大致参考。变压器故障样本不平衡比如“正常”类样本多“高能放电”类样本少这时候只看准确率会被多数类掩盖。下面是一份示意形式的分类报告展示每个故障类的精确率、召回率和F1。故障类型精确率召回率F1样本数正常0.950.930.94120低能放电0.880.900.8980高能放电0.850.740.7935低温过热0.900.860.8870高温过热0.820.910.8665高能放电样本只有35个召回率74%意味着大约有9个高能放电被漏掉。对于电力设备来说把高能放电误判成过热比反向误判更严重因为检修优先级完全不同。这时候要回到混淆矩阵看它被分到了哪一类通常是C2H2和C2H4的比值落在边界区RBF基函数覆盖重叠过大。解决办法是适当调小sigma让每个局部区域的响应更尖锐或者对少数类做SMOTE过采样后重新训练。5. 现场部署的进阶技巧样本不平衡、阈值与增量更新5.1 样本不平衡时用Focal Loss调整梯度直接在CrossEntropyLoss上加类别权重是最快的办法但权重是静态的对难分的边界样本不敏感。Focal Loss在交叉熵基础上加了一个调制因子(1-p)^gamma当模型对某个样本已经很有把握时p接近1损失会被压低当样本处于边界、p很小损失保持较高。这样梯度会集中在难分的高能放电和放电类样本上。import torch.nn.functional as F class FocalLoss(nn.Module): def __init__(self, alpha0.25, gamma2.0): super().__init__() self.alpha alpha self.gamma gamma def forward(self, logits, target): ce F.cross_entropy(logits, target, reductionnone) p torch.exp(-ce) alpha_t self.alpha focal alpha_t * (1 - p) ** self.gamma * ce return focal.mean()p是模型对正确类别的预测概率(1-p)^gamma是调制系数gamma一般取2。alpha用于控制正负样本权重如果只分放电和非放电两类可以设置非放电类0.25、放电类0.75如果要多类就要给每个类别单独配alpha会多出一个超参需要额外网格搜索。5.2 置信度阈值和增量微调部署时不要只看softmax输出的最大概率要加两道阈值。我常用的策略如下场景阈值范围处置方式高置信softmax概率 0.85直接输出故障类型中置信0.60 ~ 0.85输出类型并附带“待复核”标记低置信 0.60不判型提示结合色谱复查阈值从验证集上取95%分位数确定而不是人工拍脑袋。对于样本特别少的故障类可以把低置信阈值单独下调到0.5避免该类永远不触发告警。最后讲一个现场技巧模型更新不要每次全量重训。RBF中心和sigma保持不动只对BP层的两个全连接层做增量微调学习率降到0.001以下。用新确认的故障样本混合一部分旧样本每次只训练20~30轮微调后回到验证集看一遍旧类别召回率有没有明显下滑。这个做法既能让模型吸收新的故障分布又不会因为几百个新样本就打乱已学好的边界。本文还有配套的精品资源点击获取
返回列表