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

资讯详情

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

模糊神经网络机械故障诊断:从振动信号到可复现推理链路

模糊神经网络机械故障诊断:从振动信号到可复现推理链路 简介这份资源面向机械故障诊断方向的研究生、工程师及MATLAB学习者聚焦模糊逻辑与神经网络融合模型在设备故障识别中的落地实现。包内共8个文件以5个m脚本和3个mat数据文件为主脚本承担模型构建、训练与测试流程mat文件则保存归一化后的特征数据与支持向量机相关中间结果压缩包整体约7KB轻量便于快速运行与二次修改。内容围绕模糊集合与隶属函数、模糊推理、前馈或径向基网络结构、模糊化与去模糊化步骤展开并涉及谱分析、小波变换等故障特征提取思路以及数据预处理、模型训练、性能评估与在线监测的完整诊断流程。已有492人学习适合希望借助MATLAB工具箱复现模糊神经网络诊断案例、理解非线性非确定性信息处理方法的读者参考。1. 模糊神经网络做机械故障诊断从振动信号到可复现的推理链路设备点检时最头疼的不是没有数据而是数据“像又不像”。轴承内圈剥落和滚动体点蚀的频谱包络往往只差几个边频带老师傅拿手一摸能说出个大概可要把这套经验固化成一条能自动跑的诊断链路纯阈值法立刻翻车——工况一变阈值全废。模糊神经网络机械故障诊断要解决的正是这个夹缝问题用神经网络学特征映射用模糊逻辑处理“故障程度介于轻微与中度之间”这类边界样本。它适合手里已经有振动采集通道、想把诊断从人工判读推进到半自动推理的现场工程师也适合做旋转机械状态监测方向、需要一套可解释性比纯黑箱稍好的算法骨架的人。下面这条链路我按“信号怎么进、特征怎么出、网络怎么搭、结果怎么验”的顺序拆开讲每一步都落到能跑的命令和参数上。2. 振动信号怎么变成模糊神经网络的输入采样、分段与特征工程2.1 采样参数定错后面全白搭机械故障诊断的第一道坎不在算法在采集。滚动轴承的故障特征频率通常落在 500 Hz 到 5 kHz早期微弱冲击的高频共振带甚至能到 10 kHz 以上。按香农定理采样率至少是关注最高频率的 2.56 倍工程上我一般直接取 12.8 kHz 或 25.6 kHz给抗混叠滤波器留足过渡带。采样点数按“一段信号至少覆盖 10 个转频周期”来定转频 25 Hz 时10 个周期是 0.4 s12.8 kHz 采样下就是 5120 点。实际做数据集时我习惯取 2048 或 4096 点一段段间重叠 50%这样既保证每段里有足够的冲击重复次数又不至于让单段太长导致网络输入维度爆炸。提示采集时同步记录转速转速波动超过 ±2% 的段直接丢弃否则故障特征频率会漂移模糊隶属度函数根本对不准。2.2 时域、频域、时频域特征各取什么原始振动波形直接喂网络不是不行但样本需求量大、训练慢现场小样本场景下不划算。常见做法是先提取统计特征再让模糊神经网络去学特征到故障类别的映射。时域上我固定取这几个均方根值RMS、峭度Kurtosis、峰值因子Crest Factor、裕度因子Margin Factor。峭度对早期冲击特别敏感正常轴承峭度接近 3出现剥落时会明显抬升但峭度到后期反而可能回落所以不能单靠它。频域特征用包络谱更稳。先对原始信号做 Hilbert 变换取包络再对包络做 FFT然后提取故障特征频率处的幅值。以 6205 深沟球轴承为例外圈故障频率 BPFO、内圈故障频率 BPFI、滚动体故障频率 BSF 都有现成公式代入转速和几何参数就能算。时频域如果算力允许加一层小波包分解取各频带能量占比作为补充特征。下面这段代码把一段振动信号转成 12 维特征向量可以直接接后面的网络。import numpy as np from scipy.fft import fft, fftfreq from scipy.signal import hilbert def extract_features(signal, fs, bpfo, bpfi, bsf): # 时域特征 rms np.sqrt(np.mean(signal**2)) kurt np.mean((signal - np.mean(signal))**4) / (np.std(signal)**4 1e-12) peak np.max(np.abs(signal)) crest peak / (rms 1e-12) margin peak / (np.mean(np.sqrt(np.abs(signal)))**2 1e-12) # 包络谱特征 envelope np.abs(hilbert(signal)) env_spectrum np.abs(fft(envelope - np.mean(envelope))) freqs fftfreq(len(signal), 1/fs) pos_mask freqs 0 freqs freqs[pos_mask] env_spectrum env_spectrum[pos_mask] def amp_at(target, tol2.0): idx np.argmin(np.abs(freqs - target)) lo max(0, idx - int(tol / (freqs[1] - freqs[0]))) hi min(len(env_spectrum), idx int(tol / (freqs[1] - freqs[0])) 1) return np.max(env_spectrum[lo:hi]) f_bpfo amp_at(bpfo) f_bpfi amp_at(bpfi) f_bsf amp_at(bsf) f_rot amp_at(bpfo / 3.5) # 粗略估计转频谐波实际用转速计更准 # 频带能量占比 total_energy np.sum(env_spectrum**2) 1e-12 low_band np.sum(env_spectrum[freqs 1000]**2) / total_energy mid_band np.sum(env_spectrum[(freqs 1000) (freqs 5000)]**2) / total_energy high_band np.sum(env_spectrum[freqs 5000]**2) / total_energy return np.array([rms, kurt, crest, margin, f_bpfo, f_bpfi, f_bsf, f_rot, low_band, mid_band, high_band, f_bpfo / (f_bpfi 1e-12)])这段代码里fs是采样率bpfo、bpfi、bsf需要按轴承型号和转速提前算好。amp_at函数在目标频率附近取一个容差窗口内的最大幅值容差默认 2 Hz是为了容忍转速微小波动。最后返回的 12 维向量里前 4 维是时域统计量中间 4 维是特征频率幅值后 4 维是频带能量占比和比值。实际用时我会把每个特征做 z-score 归一化否则 RMS 的量级会压过其他特征。2.3 模糊化把连续特征映射成隶属度模糊神经网络和普通神经网络最大的区别就在输入层之后多了一步模糊化。每个特征不再是一个确定数值而是对若干模糊集合的隶属度。比如峭度这个特征我定义三个模糊集正常K 接近 3、轻微冲击K 在 3.5 到 5 之间、严重冲击K 大于 5。隶属度函数用高斯型或三角型都行高斯型更平滑三角型计算快。下面用三角型给个例子。def triangular_mf(x, a, b, c): # a 左底b 峰c 右底 if x a or x c: return 0.0 if x b: return (x - a) / (b - a 1e-12) return (c - x) / (c - b 1e-12) def fuzzify_kurtosis(k): # 三个模糊集正常、轻微、严重 mu_normal triangular_mf(k, 2.0, 3.0, 4.0) mu_slight triangular_mf(k, 3.0, 4.5, 6.0) mu_severe triangular_mf(k, 5.0, 7.0, 10.0) return np.array([mu_normal, mu_slight, mu_severe])参数a, b, c的选取直接决定诊断灵敏度。我一般先用正常样本统计出峭度的均值和标准差正常集峰取均值左右底取均值 ±1.5 倍标准差轻微集和严重集再根据故障样本分布调。如果现场没有故障样本就按经验值先设后续用在线数据慢慢修。模糊化之后每个特征变成 3 维隶属度12 维特征就扩展成 36 维再送入后面的神经网络层。3. 模糊神经网络结构怎么搭从 ANFIS 到可训练隶属度3.1 为什么选 ANFIS 而不是纯 MLP纯 MLP 做故障分类精度可以很高但有个硬伤输入输出之间的关系藏在权重里现场工程师问“为什么判成内圈故障”你只能给个热力图说服力有限。ANFIS自适应神经模糊推理系统把模糊规则嵌进网络结构每条规则对应一个“如果峭度偏高且 BPFO 幅值大则外圈故障”这样的可读语句。规则数不多时诊断报告里能直接写出触发了哪几条规则这在设备验收和故障复盘时很管用。ANFIS 的典型结构是五层输入层、模糊化层、规则推理层、归一化层、输出层。输入层节点数等于特征数模糊化层每个输入对应若干隶属度函数规则层做模糊与运算归一化层算各规则触发强度占比输出层做加权求和。可训练参数主要是隶属度函数的中心和宽度以及输出层的线性系数。用梯度下降或者混合算法前向最小二乘 反向梯度都能训。3.2 用 PyTorch 搭一个可训练的模糊神经网络下面这个实现把模糊化层写成可学习的高斯隶属度函数规则层用乘积做与运算输出层做加权平均。这样整个网络可以端到端训练同时保留模糊规则的可解释性。import torch import torch.nn as nn class FuzzyNN(nn.Module): def __init__(self, n_features, n_rules, n_classes): super().__init__() self.n_features n_features self.n_rules n_rules # 每个特征对每条规则有一个高斯隶属度中心 c 和宽度 sigma self.centers nn.Parameter(torch.randn(n_features, n_rules)) self.log_sigmas nn.Parameter(torch.zeros(n_features, n_rules)) # 输出层每条规则对每个类别的贡献权重 self.rule_weights nn.Parameter(torch.randn(n_rules, n_classes)) def forward(self, x): # x: (batch, n_features) # 计算隶属度 (batch, n_features, n_rules) sigmas torch.exp(self.log_sigmas) 1e-6 diff x.unsqueeze(2) - self.centers.unsqueeze(0) mu torch.exp(-0.5 * (diff / sigmas.unsqueeze(0))**2) # 规则触发强度对特征维做乘积 (batch, n_rules) firing torch.prod(mu, dim1) # 归一化 firing_norm firing / (firing.sum(dim1, keepdimTrue) 1e-12) # 输出 (batch, n_classes) out torch.matmul(firing_norm, self.rule_weights) return out, firing_normn_features是输入特征数n_rules是模糊规则条数一般取 5 到 15 条太少欠拟合太多容易过拟合且规则可读性下降。centers和log_sigmas用对数形式是为了保证宽度始终为正。forward返回分类输出和归一化触发强度后者可以用来分析每条规则对当前样本的贡献。训练时损失函数用交叉熵优化器用 Adam学习率从 1e-3 开始如果损失震荡就降到 1e-4。3.3 训练参数怎么设批量、轮数、早停批量大小我一般取 32 或 64样本量小于 500 时取 16。训练轮数不固定看验证集损失通常 200 到 500 轮足够。早停耐心值设 20 轮验证损失连续 20 轮不降就停。学习率用余弦退火比固定值稳初始 1e-3最低降到 1e-5。下面这段训练循环可以直接套。def train_fuzzy_nn(model, train_loader, val_loader, epochs300, lr1e-3, patience20): optimizer torch.optim.Adam(model.parameters(), lrlr) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_maxepochs) criterion nn.CrossEntropyLoss() best_val float(inf) wait 0 for epoch in range(epochs): model.train() for xb, yb in train_loader: optimizer.zero_grad() out, _ model(xb) loss criterion(out, yb) loss.backward() optimizer.step() scheduler.step() model.eval() val_loss 0.0 with torch.no_grad(): for xb, yb in val_loader: out, _ model(xb) val_loss criterion(out, yb).item() val_loss / len(val_loader) if val_loss best_val: best_val val_loss wait 0 torch.save(model.state_dict(), best_fuzzy_nn.pth) else: wait 1 if wait patience: print(fEarly stop at epoch {epoch}) break return model这里train_loader和val_loader按 8:2 划分如果类别不平衡用加权交叉熵权重取类别频率的倒数。保存最佳模型而不是最后一轮是因为模糊神经网络在验证集上波动比普通 MLP 大最后一轮未必最好。4. 避坑与排查模糊神经网络诊断现场最容易翻车的五件事4.1 隶属度函数初始化不当导致规则全死现象训练一开始损失就不降检查触发强度发现所有样本都只激活同一条规则。原因centers用标准正态随机初始化如果特征归一化没做好大部分输入落在所有高斯函数的尾部隶属度全接近零乘积之后只有数值最大的那条规则存活。解决初始化centers时用训练集特征的均值和分位数比如每条规则的中心取不同分位点宽度取特征标准差的 0.5 到 1 倍。归一化必须在模糊化之前做z-score 或 min-max 都行我倾向 z-score因为高斯隶属度对尺度更敏感。4.2 转速波动没补偿特征频率对不上现象同一轴承同一故障上午采的数据判成外圈下午判成内圈。原因转速从 1480 rpm 漂到 1520 rpmBPFO 偏移了十几赫兹而amp_at的容差窗口只有 2 Hz取到的幅值其实是噪声。解决采集时同步转速用实际转速重算特征频率如果没有转速计用包络谱里转频谐波的最大值反推转速再动态调整容差窗口到 ±5 Hz。更稳的做法是把特征频率幅值换成“特征频率处幅值 / 相邻频带平均幅值”的比值降低对绝对频率的敏感度。4.3 样本不均衡让网络偏向多数类现象正常样本 2000 段内圈故障只有 80 段训练完网络把几乎所有样本都判成正常。原因交叉熵损失被多数类主导模糊规则层也倾向于把触发强度集中到正常规则。解决损失函数加类别权重权重取总样本数 / (类别数 * 该类样本数)同时在数据加载时对少数类做重叠采样但重叠率不要超过 75%否则同一段信号反复出现会导致过拟合。模糊规则数也可以按类别先验分配正常类少给几条规则故障类多给几条。4.4 只看准确率忽略规则可解释性现象测试集准确率 98%但导出规则一看所有规则的隶属度函数几乎重叠等于没有模糊划分。原因训练时只优化分类损失没有对隶属度函数加约束网络为了降低损失把高斯函数拉得很宽模糊性名存实亡。解决在损失里加一项正则惩罚隶属度函数的宽度过大或中心过于集中比如lambda * sum(1/sigma)或者对中心做多样性约束。lambda取 1e-4 到 1e-3太大会掉精度太小不起作用。训练完把centers和sigmas导出来画成隶属度曲线人眼过一遍重叠太严重的重新初始化再训。4.5 在线推理时特征提取和训练不一致现象离线训练准确率很高部署到边缘设备后误报率飙升。原因训练时用 scipy 的hilbert和fft部署时为了省算力换成了简化的包络检波或者采样率从 12.8 kHz 降到 6.4 kHz 但特征频率没重算。解决把特征提取代码封装成独立模块训练和推理共用同一份实现采样率、滤波器参数、容差窗口全部写成配置项部署前用同一段原始信号分别跑离线和在线逐特征对比数值误差超过 1% 就查。边缘设备算力不够时优先降采样率而不是换算法降采样后记得重算特征频率和容差。5. 让模糊神经网络诊断真正落地规则导出与在线更新训练完一个模糊神经网络只是开始现场要的是能持续用的诊断链路。我一般做两件事规则导出和在线更新。规则导出是把centers、sigmas和rule_weights翻译成“如果峭度隶属轻微冲击且 BPFO 幅值隶属高则外圈故障置信度 0.87”这样的语句写进诊断报告。下面这段代码把训练好的模型转成规则表。def export_rules(model, feature_names, class_names, top_k3): centers model.centers.detach().numpy() sigmas torch.exp(model.log_sigmas).detach().numpy() weights model.rule_weights.detach().numpy() rules [] for r in range(model.n_rules): conditions [] for f in range(model.n_features): c centers[f, r] s sigmas[f, r] conditions.append(f{feature_names[f]}≈{c:.2f}(σ{s:.2f})) scores weights[r] top_classes np.argsort(scores)[::-1][:top_k] conclusion , .join([f{class_names[i]}:{scores[i]:.2f} for i in top_classes]) rules.append(f规则{r1}: 如果 且 .join(conditions) f则 {conclusion}) return rulesfeature_names按提取顺序传入class_names是故障类别名。导出的规则里中心值接近正常范围的规则通常对应正常类中心值偏离大的对应故障类。如果某条规则对所有类别的权重都差不多说明这条规则没学到东西可以删掉再微调。在线更新我一般用两种策略。一种是滑动窗口微调把最近 200 段带标签的样本现场确认过的加入训练集用低学习率 1e-4 只更新输出层权重模糊化层冻结这样不会破坏已有的规则结构。另一种是规则增删如果连续出现置信度低于 0.6 的样本且人工确认是新故障模式就增加一条规则中心初始化为该样本的特征值宽度取当前规则宽度的平均值然后小学习率训 50 轮。两种策略都要求保留一份验证集更新后验证集准确率掉超过 2% 就回滚。注意在线更新前一定先做数据漂移检测如果特征分布和训练集比 KL 散度超过阈值先查传感器和工况别急着改模型。这套链路我在几个电机轴承台上跑过从 12 维特征到 10 条规则的模糊神经网络正常、内圈、外圈、滚动体四分类验证集准确率能到 94% 左右规则导出后现场师傅能看懂每一条判断依据。最深的教训是模糊神经网络的精度上限由特征提取决定模糊层只是把边界样本的处理变得更可控别指望它去补信号处理欠下的债。每次换轴承型号或工况先把特征频率和隶属度函数重新对一遍比调网络结构管用得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表