简介一份聚焦小电流接地故障选线问题的人工神经网络建模研究PDF适合电力系统继电保护人员、配电网运维人员以及关注深度学习方法在故障诊断中应用的算法学习者。论文以110kV/35kV配电系统为例从故障暂态行波特征分析入手系统介绍小电流接地故障特征、常规BP神经网络原理以及遗传算法优化的改进神经网络模型。包内共1个PDF文件约360KB无需额外配套资料即可独立阅读可作为论文研读、算法复现与故障选线研究参考。目前已有113人学习。通过研读可掌握遗传算法中的遗传算子调整、染色体结构优化与自适应交叉变异概率如何改善初始网络权重和BP网络结构理解改进算法相比常规算法在输出误差与正确选线率上的提升为后续探索深度信念网络、卷积神经网络等更高级模型奠定基础。1. 小电流接地选线为什么总选错把难题扔给人工神经网络配电网里的故障单相接地能占到八成以上。真正让继保人员紧张的却不是保护怎么跳而是故障到底出在哪条线上——小电流接地系统的接地电流只有几安到几十安十回出线的零序电流波形看起来都差不多一个判断失误就要一条条拉闸去试。这正是人工神经网络选线方法要啃的骨头不再手工推导物理判据而是把选线当做一个分类问题从故障波形里抽特征让网络自己学出一套决策边界。这篇笔记写给要做选线算法验证的继保工程师和相关方向的研究生我会把从仿真数据准备、特征提取到模型训练和现场验证的完整路径写清楚顺带交代参数设法和踩过的坑照着搭一版并不难。2. 选线问题的病根传统判据在哪些场景下集体失效2.1 中性点接地方式把选线搅成了什么局面小电流接地只是一个统称实际工作中最常见的是两套接线中性点不接地和中性点经消弧线圈接地。这两套系统里单相接地故障的零序电流来源完全不同传统选线方法在它们之间的表现也天差地别。中性点不接地系统故障点不会形成大的短路电流回路各条出线只有对地电容电流。故障后非故障线路的电容电流方向是从母线流向线路故障线路的零序电流则是所有非故障线路电容电流的叠加方向反过来从线路流向母线。这就给“比幅比相”留了空间找幅值最大的、方向相反的那一支通常就是故障支路。这套判据在故障点过渡电阻小、系统规模明确时相当管用。麻烦出在经消弧线圈接地的系统。消弧线圈串在中性点和地之间它发的是感性电流用来抵消系统的容性电流把接地点残流压到几安到十几安电弧自然熄灭。代价是故障线路零序电流的规律被彻底改写过补偿状态下故障线路零序电流与健全线路不仅方向相同幅值也不再保证最大有时还不如一条健全长线路的电容电流大。传统“比幅比相”在这里几乎全部失效。这就把选线推向了所有判据都不太可靠的边缘稳态量被补偿掉了暂态量受故障初相角制约注入信号又要额外设备。它不像大电流接地系统那样可以直接用零序过流定位而是一个“信号弱、方向乱、时间短”的模式判别难题。人工神经网络的价值恰恰在这里——它不企图用一条公式吃遍所有故障形态而是学习不同运行方式下的特征组合。2.2 稳态判据、注入判据和暂态判据的适用边界现场一直有几种传统选线方案在服役各有各的看家本领也各有各的翻车场景。做一个简单的对比能看得更清楚判据类型原理适用场景典型失效场景零序电流幅值比较故障线路零序电流幅值较大不接地、电容电流大、低阻接地消弧线圈过补偿、高阻接地零序电流相位比较故障线路电流方向与健全线路相反不接地、低阻接地消弧线圈过补偿、电容电流小五次谐波比较消弧线圈对五次谐波补偿弱故障线路谐波量大消弧线圈接地系统非线性负荷谐波污染严重S注入法向PT二次侧注入信号跟踪路径各种接地方式但需要注入装置间歇性电弧、高阻、注入设备停运暂态首半波法故障初始暂态电流首半波极性故障初相角大、线路长度差异小故障初相角过零、长线路衰减严重从这张表能读出两件有意思的事。第一没有任何一种判据在所有场景下都成立它们更像是互补关系的多把钥匙能不能打开门要看现场条件。第二几乎所有判据的分析对象都是同一堆信号——零序电流、零序电压、谐波和暂态分量——区别在于怎么组合这些信号。这就给了学习型方法机会人工神经网络可以把这些被传统判据单个使用的量全部放进同一个特征向量让网络自己挑哪些组合最稳定。实际工程中选线装置往往把几种判据做成“投票”少数服从多数。但当多数判据同时失效时比如消弧线圈过补偿加高阻接地投票也只是让错误更自信。用人工神经网络替换或并联这套投票逻辑本质上是把决策从固定规则换成了数据驱动的权重分配。做这件事的第一步是把选线问题严格定义成一个有明确输入、输出和训练样本的分类任务。3. 把选线重构为分类任务人工神经网络的输入输出设计3.1 特征向量出线零序电流不是拿来就用的用人工神经网络做选线第一步不是搭网络而是决定喂给它什么。最直观的想法是把故障瞬间各条出线的零序电流原始波形整段丢进去让网络自己看。这个思路在理论上没有错但实际很难落地按10kHz采样率故障前20ms加故障后80ms就是1000个点十条出线就是上万维输入需要的训练样本量动辄几十万条而选线问题恰恰是小样本场景现场录波一年未必攒得下一千条有效的接地故障样本。我在搭这类模型时的习惯是沿用传统选线方法的看盘思路把物理上被验证过有区分度的量抽出来作为人工神经网络的输入特征。单条出线的特征一般取这样几个零序电流基波幅值、基波相对母线零序电压的相位差、五次谐波幅值占比、暂态高频能量约300-3000Hz频带、故障起始瞬间首半波极性。这五个量正好对应前文表格里的五种传统判据它们互有冗余又有互补适合作为网络输入。全部出线加母线侧零序电压合起来就组成一个完整的样本向量。母线电压相位在这里很关键它作为基准让每条出线的相位差具备可比性否则各条线各自为政网络学不到线间相对关系。特征分量对应传统量作用零序电流基波幅值幅值比相法高阻与低阻的幅度刻度基波相位差对母线零序电压相位比较法区分过补/欠补方向变化五次谐波占比谐波法对消弧线圈补偿不敏感暂态高频能量暂态法故障初相角大时有效首半波极性首半波法区分故障与非故障的早期线索这里要特别强调一个维度规整问题典型配电网有八到十二条出线但样本里不同馈线的数量会变化。做训练数据时常见做法是把该系统的出线数固定下来按统一顺序排列各出线特征如果现场出线数变化就需要在模型外层做输入模板的映射而不是让网络去适应不定长的结构。神经网络对输入维度的变化极其敏感这个在后期对接装置时最容易吃亏。另一个容易忽略的细节是角度特征的编码方式。相位差在物理上是周期量0度和360度是同一个方向如果直接把角度数值送进网络数值上却相差360个单位网络会错误地认为这两个样本差异巨大。所以角度特征在进入网络前要拆成sin和cos两个分量既保留周期性又消除数值跳变。这样一来每条出线最终送入网络的是六个数值不是五个。3.2 网络拓扑与训练策略BP网络够用别一上来就堆层确定好输入后网络结构反而简单。中小规模样本下一个单隐层的前馈网络就能覆盖大部分选线任务隐藏层神经元数量没有绝对公式经验上取输入维度的1到2倍、再在验证集上调一轮就够。输入维度六十左右时隐层神经元通常设在64附近再加一个较小的输出层输出节点数就是故障线路数加一多出的那一个表示母线故障因为母线接地在工程上必须被选出来不能让它糊里糊涂归到某条出线头上。为什么不能一出问题就加深网络这也是个值得琢磨的点。接地故障样本的获取成本高几百到几千条样本撑死深层网络的参数量动辄几十万小样本上极易过拟合——训练集准确率百分之百验证集只有七成。我在这个场景下更愿意相信两层到三层的容量把心思放在特征和样本质量上而不是堆参数。训练时几个细节值得注意输入先用标准化的方式映射到差不多的尺度避免幅值特征和谐波占比特征在梯度上互相压制验证集按故障场景划分而不要随机打乱保证同一场景的数据不会同时泄漏进训练集和验证集训练用早停机制观察验证集损失连续若干轮不下降就拉倒。输出层的激活按多分类配置损失函数用交叉熵这些是神经网络训练里的常规配置但放到选线场景里它们补的是小样本稳定性这味药。4. 用仿真数据跑通人工神经网络选线的最小训练流程4.1 仿真场景配置没有真实录波时的替代方案现场录波数据稀缺是选线研究的常态绝大多数训练样本靠仿真生成。我一般用10kV配电网模型十条架空出线出线长度在2到8公里之间错开消弧线圈过补偿度设成8%左右负载电阻电感不对称度按实际配网习惯留一点。故障模块设置在出线中段通过改参数可以批量生成不同场景。关键是把故障参数的取值范围铺开。故障位置按线路全长的25%、50%、75%三个点分别布置过渡电阻取5、20、100、500、1000欧姆几档高阻档必须覆盖否则模型在实际高阻故障面前寸步难行故障初相角从0度到360度按15度步长扫一遍这一步很费仿真时间但绝不能省因为初相角接近0度时暂态分量极小模型必须见过这种“难啃”样本。消弧线圈脱谐度也可以做正负几档的变化把过补偿、全补偿、欠补偿都涵盖进去。仿真参数取值说明馈线数10固定维度故障位置25%、50%、75% 长度三条位置档过渡电阻5/20/100/500/1000Ω含高阻档故障初相角0-360°15°步长覆盖暂态弱区消弧线圈脱谐度-8% / 0 / 8%过/全/欠补偿每个故障场景仿真一次记录故障前后共100ms的零序电压和电流波形然后切成样本。故障起始时刻可以通过零序电压突变自动检测仿真脚本里留一个固定的预触发窗口保证故障前有2个周波、故障后有3个周波的稳定数据段。这一步做扎实后面特征提取才有统一的时间轴。4.2 特征提取与训练代码从波形到选线结果波形数据不能直接送进网络先经过特征提取。下面这一段是特征提取脚本的核心逻辑我用Python的numpy完成基波和谐波计算并把暂态能量用带通滤波求出来。import numpy as np fs 10000 # 采样率 10kHz f0 50 # 工频 50Hz feat [] for line in range(n_lines): i0 zero_seq_current[line] # 该出线零序电流整段 u0 bus_zero_seq_voltage # 母线零序电压整段 # 去直流 i0_ac i0 - np.mean(i0) u0_ac u0 - np.mean(u0) # 用故障后20ms开始的40ms窗算基波幅值与相位 win slice(fs * 20 // 1000, fs * 20 // 1000 fs * 40 // 1000) I_spec np.fft.rfft(i0_ac[win]) U_spec np.fft.rfft(u0_ac[win]) f_axis np.fft.rfftfreq(len(i0_ac[win]), 1 / fs) k1 np.argmin(np.abs(f_axis - f0)) k5 np.argmin(np.abs(f_axis - 5 * f0)) amp1 np.abs(I_spec[k1]) / (len(i0_ac[win]) / 2) amp5 np.abs(I_spec[k5]) / (len(i0_ac[win]) / 2) phase_diff np.angle(I_spec[k1]) - np.angle(U_spec[k1]) # 暂态高频能量用汉宁窗抑制频谱泄漏 I_hf np.fft.rfft(i0_ac[win] * np.hanning(len(i0_ac[win]))) band (f_axis 300) (f_axis 3000) energy_hf np.sum(np.abs(I_hf[band])) # 首半波极性取故障后前10ms内极值符号 peak_win i0_ac[:fs * 10 // 1000] polarity np.sign(peak_win[np.argmax(np.abs(peak_win))]) feat.append([amp1, np.sin(phase_diff), # 角度拆成sin/cos np.cos(phase_diff), amp5 / amp1, energy_hf, polarity])这段代码里窗函数从故障发生后第20ms处开始取40ms刚好两个工频周期。amp1是基波幅值的标幺化表达它用于表征故障线路的稳态响应虽然是传统判据的量但在网络里它会和其他特征形成组合。关键的是相位差它以母线零序电压为参考把各出线的相对相位放在同一个坐标系里并且按前面说的拆成了sin和cos两个分量。五次谐波占比用的是与基波的比值不直接用绝对量这样不同系统电容电流水平的差异不会带偏网络。energy_hf是把带通频带内的频谱分量求模求和得到的是首半波法之外的另一种暂态表达对高阻接地的敏感度和首半波极性互补。样本生成时每跑完一个仿真场景就调用一次这段逻辑把特征追加到特征矩阵同时记录一个标签。标签的编码方式需要提前定好十回出线对应0到9母线故障对应10共十一类。模型训练我用PyTorch写一个两层全连接网络下面是完整的最小训练流程import torch import torch.nn as nn from torch.utils.data import TensorDataset, DataLoader class SelectorNet(nn.Module): def __init__(self, in_dim, hidden_dim, out_dim): super().__init__() self.net nn.Sequential( nn.Linear(in_dim, hidden_dim), nn.Tanh(), nn.Linear(hidden_dim, out_dim) ) def forward(self, x): return self.net(x) # 数据标准化用训练集统计量验证集复用同一组 mean, std X_train.mean(0), X_train.std(0) X_train_n (X_train - mean) / std X_val_n (X_val - mean) / std train_ds TensorDataset(torch.tensor(X_train_n, dtypetorch.float32), torch.tensor(y_train, dtypetorch.long)) val_ds TensorDataset(torch.tensor(X_val_n, dtypetorch.float32), torch.tensor(y_val, dtypetorch.long)) train_dl DataLoader(train_ds, batch_size32, shuffleTrue) val_dl DataLoader(val_ds, batch_size64, shuffleFalse) model SelectorNet(in_dimX_train_n.shape[1], hidden_dim64, out_dim11) optimizer torch.optim.Adam(model.parameters(), lr1e-3) loss_fn nn.CrossEntropyLoss() best_val float(inf) for epoch in range(200): model.train() for xb, yb in train_dl: optimizer.zero_grad() loss loss_fn(model(xb), yb) loss.backward() optimizer.step() model.eval() val_loss_total, cnt 0.0, 0 with torch.no_grad(): for xb, yb in val_dl: val_loss_total loss_fn(model(xb), yb).item() * len(xb) cnt len(xb) val_loss val_loss_total / cnt # 早停验证集loss连续改善才保存模型 if val_loss best_val: best_val val_loss torch.save(model.state_dict(), selector.pt)训练循环里用了早停验证集loss每下降一次就保存一次权重200个epoch跑完磁盘上留下的是验证集表现最好的那一版而不是最后一个epoch的权重。batch_size取32学习率取0.001这是小样本分类任务里比较稳的起点。隐藏层激活用Tanh而不用ReLU主要原因在于输入特征里混有sin、cos和极性这类有正负的信息Tanh的零中心特性在这类特征上更匀称实测收敛也稳定。标准化这一步要特别注意这里用的是训练集的均值和标准差验证集和测试集必须复用同一组统计量而不是各自单独算否则验证集的数据分布被人为改变评估结果没有参考意义。输入维度由出线数乘以每条出线的特征数决定十条线乘以六个特征就是60维输出11类。如果实际系统的出线数不是10输入维度和输出类别都要同步调整模型结构本身不需要大改。4.3 结果评估准确率不是唯一指标训练完成后最忌只看总准确率。小电流接地选线场景里漏选和误选的代价完全不同漏选意味着故障线没被找出来调度还要人工拉路排查误选则是直接把健康出线切掉造成不该有的停电。模型评估必须把这两种错误单独统计。混淆矩阵是最直接的观察工具建议训练完先打印一份重点看两类错误一类是母线故障被分到某条出线另一类是某条出线的高阻故障被分到另一条出线。还有一个容易忽略的评估角度把输出层每个类别的置信度分布拉出来看。高阻故障和初相角过零的样本理论上输出概率应该集中在正确类别但整体置信度偏低这是网络在说“我不太确定”。如果出现概率峰值在两三个类别间来回跳的情况说明特征对这些样本的区分度不足这时该回头补特征、补数据而不是加网络层数。对于置信度偏低的输出现场逻辑会在装置里做闭锁处理宁可报“无法选线”也不能报错误线路。仿真环境里有一件事要养成习惯把每个样本对应的场景参数线路编号、故障位置档位、过渡电阻值、初相角和特征向量一起存盘。后续重新调整特征或换网络结构时可以直接按场景筛选数据集也能给组里同事做“作业包”式的复现——一份特征文件加一段训练脚本换人重跑也能得到同样的曲线和混淆矩阵。这个习惯帮我省了很多重复仿真时间。5. 人工神经网络选线落地避坑从仿真到现场的排查笔记5.1 仿真训练很准一换现场数据就翻车仿真集上准确率做到95%以上跑到现场录波上掉到60%这是我见过最多的翻车模式。现象很有迷惑性因为仿真里的波形看上去跟实际波形非常接近故障特征也“正常”但模型就是判不对。原因几乎都出在仿真模型的“过分干净”上。理想仿真里电压源三相对称、负载恒定、线路参数对称而实际配电网三相不平衡是常态负荷还会随时间波动这些偏差会叠加到零序电流上改变特征分布。模型在理想分布上学到的决策边界根本不知道真实数据的方差有多大。解决思路分两层。第一层是给仿真数据做“加噪”在电压源里加2到3度的三相不平衡角负荷按额定值的80%到120%随机波动再在电流通道叠加少量白噪声。这一套扰动后重新仿真生成第二批数据混合训练模型的鲁棒性会立刻上一个台阶。第二层是把现场已经确认的故障录波追加进训练集做增量微调让模型逐渐贴近本单位电网的真实特征。5.2 消弧线圈补偿状态一换网络集体失灵现象比较惊悚过补偿状态下做出来的模型遇到消弧线圈切换成全补偿或欠补偿运行选线准确率直接掉到接近抛硬币。故障线路零序电流的相位规律在不同补偿状态之间会发生明显翻转幅值关系也会重新洗牌。在过补偿训练集上网络学到的最优特征组合可能恰恰是把“相位差方向”当成了第一决策维度。排查路径其实清晰对消弧线圈系统不能假设系统永远在同一种补偿状态下运行。我一般会在仿真参数表里把脱谐度做成负8%、0%、正8%三档全部生成样本。更稳妥的做法是把脱谐度本身作为一个输入特征放进网络让它学会“看补偿状态再决定用哪些判据”。现场拿不到脱谐度时也可以用母线零序电压的幅频特征间接估计效果差点但够用。这种对运行方式变化的敏感性是所有物理判据工程化时要考虑的事人工神经网络也不例外。数据驱动模型本质上是在训练集的统计分布里找规律训练集没有覆盖到的运行方式模型就不会有正确的反射。覆盖面这个功课只能靠仿真场景设计来补。5.3 特征尺度不一致训练曲线发散训练时loss降得很慢或者来回震荡这类问题多数不是网络本身的问题而是特征预处理埋了雷。最典型的雷是把角度特征直接用“度”作为数值送进网络。0度和360度在物理上是同一个方向但在数值空间里距离360个单位网络怎么学都会觉得这两个样本“差异很大”。同理基波幅值的数值可能是几十安而谐波占比是零点几的小数尺度差两个数量级共享梯度的优化器会无所适从。解决办法在前面代码里已经用过所有幅值类特征统一做标准化角度特征不要保留原始角度而是拆成sin和cos两个分量。sin和cos的组合天然能表达角度周期性0度和360度变为(0,1)和(0,1)这两个几乎一样的向量网络不再被角度跳变牵着鼻子走。首半波极性这类只有正负号的量就不用再标准化保持本来的语义。这类排错经验总结成一个习惯任何一个新特征进入特征向量前先单独打印它的最小值、最大值、标准差看一看它和其他特征的尺度关系。数据探查十分钟能省下面调试一整天。训练曲线发散了优先查特征而不优先调网络这是我在选线项目上的原则。5.4 母线故障被模型硬分到某条出线母线接地时所有出线的零序电流方向规律和线路故障不一样特征向量和线路故障样本也有差异。但如果训练集里母线故障样本太少模型会倾向于把母线故障划归到样本量最大的那几类也就是出线故障表现出来就是母线故障时模型每次强选一条线而且选的线还不一定固定。这个问题的原因就是类别样本不均衡和输出类别设计不全。第一要确认输出类别里有没有独立的“母线故障”类很多初版方案只给每条出线一个输出节点母线故障就只能“硬归”到某条线。第二要为母线故障单独生成仿真样本母线处设故障点覆盖不同过渡电阻和初相角。第三可以在损失函数里给少数类样本加权PyTorch的CrossEntropyLoss可以直接传一个weight参数让网络在训练时对母线故障的错误分类付出更大代价。混淆矩阵是发现这个问题最快的手段母线故障行里如果错误项散布在多个出线列基本就是样本不足或类别缺失造成的。补完样本后要重新做整轮回归测试因为权重调整可能改变模型对其他类的分类偏好不能只看母线一种故障的准确率。6. 上线前把好最后一关用录波回放验证选线模型仿真里怎么调都是一百分不意味着装置装上就能用。电气设备的出厂验证里录波回放是离现场最近的一环做法是把真实故障录波文件按标准格式读出来按采样点逐帧回放到选线装置或后台算法的输入端看算法在真实波形上的选线结果。6.1 录波回放的核心观察项回放验证的重点不是看准确率而是看三件事。第一结果输出时间现场要求在故障后一到几个工频周期内给出可靠选线结论超过时限就没有操作意义第二判据输出的稳定性回放同一段波形十次结果应该完全一致出现抖动说明算法里有随机因素或阈值临界问题第三故障解除后的复归逻辑单相接地消失后装置要能自动回到监视状态不能卡死在故障态。回放项目观察指标通过标准已知线路故障选线结果与故障录波来源一致10/10 次一致母线故障不被错分出线输出母线故障类输出时间故障后 ms 级出结果小于整定时限置信度偏低样本闭锁还是强选优先闭锁并告警再往深走一步如果手头的真实录波量还凑不齐一个回归集可以在仿真波形上叠加实测录波的环境噪声仿真场景生成覆盖不足的部分依然能完成这轮验证。这也是为什么我强调仿真场景参数要存档关键时刻它们是对照组。6.2 进阶方向从全连接网络到时序模型如果手上的录波数据足够多可以考虑把首半波和暂态能量这类手工特征换成原始暂态波形用一维卷积或循环网络直接学习时域模式。这个方向把特征工程的压力转移给了网络容量但需要更严格的样本管理否则过拟合会比全连接网络来得更快。我的判断是基础特征工程都没做扎实之前换网络结构救不了数据的短板。从传统比幅比相到人工神经网络选线最大的变化不是工具的复杂度而是思考方式从“设计一条判据然后证明它”变成“准备一组充分覆盖特征的样本让网络自己找规律”。我自己吃过亏的地方全在数据和样本设计上网络结构反而是最不费心的环节。现在每收一版模型我都先跑一遍回归集确认没有把上一版的能力改丢才肯拿出去做现场试验。这条习惯保留了模型的“后悔药”也值得你试试希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?