news 2026/5/1 10:35:14

OrderCam-Diag:基于阶次分析和类激活映射的旋转机械可解释故障诊断(Python)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OrderCam-Diag:基于阶次分析和类激活映射的旋转机械可解释故障诊断(Python)

以角域重采样和阶次分析为核心,通过将时域振动信号转换为转速不变的阶次域表示,消除了转速波动对故障诊断的影响;结合希尔伯特包络分析增强周期性冲击特征,并利用一维CNN进行多类别故障分类;还引入了Grad-CAM可解释性分析,生成注意力热力图直观展示模型决策依据,实现了从数据预处理、特征提取、模型训练到可视化解释的完整端到端智能诊断流程,提升了轴承等旋转机械故障诊断的准确性、鲁棒性和可解释性。

算法步骤

1. 数据加载与预处理

加载CWRU轴承振动数据集

提取转速信息并计算旋转频率

故障类型自动识别与标签编码

2. 角域重采样

将时域信号从时间域转换到角度域

基于转速进行线性插值,实现均匀角度采样

消除转速波动对分析结果的影响

3. 包络分析

应用希尔伯特变换提取信号包络

增强周期性冲击特征(轴承故障特征)

抑制非周期噪声干扰

4. 阶次谱生成

对角度域包络信号进行FFT变换

生成与转速无关的阶次谱(cycles/revolution)

实现故障特征的转速不变表示

5. 时-阶次谱分析

滑动窗口分段处理

对每个窗口进行阶次分析

生成阶次随时间演化的二维谱图

6. 深度学习分类

一维CNN提取深度特征

多类别故障分类(正常/内圈/外圈故障)

模型训练与优化

7. 可解释性可视化

Grad-CAM生成注意力热力图

可视化模型关注的关键特征区域

提供分类决策的直观解释

8. 结果评估与展示

自动峰值检测与标注

多视图可视化(时域、频域、阶次域)

故障诊断结果综合展示

class CWRUDataLoader: def __init__(self, base_path): """ 初始化CWRU数据加载器 Args: base_path (str): CWRU数据集根目录路径 """ self.base_path = Path(base_path) self.fs = 12000 # 采样频率12kHz self.n_rev = 64 # 每转采样点数 # 数据存储 self.X = None # 时域信号 self.Y = None # 故障标签 self.rpm = None # 转速(标量) self.filename = None # 文件名 # 故障类型映射字典 self.fault_types = { 'normal': 0, 'ball': 1, 'inner_race': 2, 'outer_race': 3 } def get_label_from_path(self, file_path: Path) -> int: """ 从文件路径中提取故障标签 Args: file_path (Path): 数据文件路径 Returns: int: 故障类型编码 (0-3) """ # 将路径转换为字符串 path_str = str(file_path) # 根据路径中的关键词判断故障类型 if 'Normal' in path_str or 'normal' in path_str: return self.fault_types['normal'] elif 'Ball' in path_str or 'B' in path_str or 'ball' in path_str: return self.fault_types['ball'] elif 'IR' in path_str or 'Inner' in path_str or 'inner' in path_str: return self.fault_types['inner_race'] elif 'OR' in path_str or 'Outer' in path_str or 'outer' in path_str: return self.fault_types['outer_race'] # 尝试从父目录名判断 parent_dir = file_path.parent.name if 'Normal' in parent_dir: return self.fault_types['normal'] elif 'B' in parent_dir: return self.fault_types['ball'] elif 'IR' in parent_dir: return self.fault_types['inner_race'] elif 'OR' in parent_dir: return self.fault_types['outer_race'] print(f"Warning: Could not determine fault type from path: {path_str}") return -1 # 未知类型 def extract_rpm_value(self, rpm_data): """ 从MATLAB加载的RPM数据中提取标量值 Args: rpm_data: 从MATLAB加载的RPM数据 Returns: float: RPM标量值 """ # 如果rpm_data是NumPy数组,提取标量值 if isinstance(rpm_data, np.ndarray): # 扁平化并取第一个元素 rpm_flat = rpm_data.flatten() if len(rpm_flat) > 0: return float(rpm_flat[0]) # 如果是列表或其他类型 if isinstance(rpm_data, (list, tuple)): if len(rpm_data) > 0: return float(rpm_data[0]) # 如果是标量 try: return float(rpm_data) except: print(f"Warning: Could not extract RPM value from: {rpm_data}") return 0.0 def import_cwru_data(self, file_keys: list): """ 加载CWRU数据集文件 Args: file_keys (list): 文件标识符列表 Returns: tuple: (X, Y) - 时域信号和故障标签 """ base_path_obj = Path(self.base_path) for key in file_keys: # 解析文件标识符(如"105DE" -> "105", "DE") match = re.match(r'(\d+)(\w+)', key) if not match: print(f"Error: Invalid file key format: {key}") continue file_num_str, data_key = match.groups() # 查找匹配的MAT文件 glob_pattern = f'{file_num_str}_*.mat' found_files = list(base_path_obj.rglob(glob_pattern)) if not found_files: print(f"Error: No file found for pattern: {glob_pattern}") continue file_path = found_files[0] self.filename = file_path.name # 设置文件名 print(f"Loading file: {self.filename}") # 加载MATLAB数据 mat_data = loadmat(file_path) # 提取故障标签 label = self.get_label_from_path(file_path) # 查找RPM和信号数据键 rpm_key = None mat_key = None for key_name in mat_data.keys(): if not key_name.startswith('__'): # 跳过MATLAB元数据 if "RPM" in key_name.upper(): rpm_key = key_name elif data_key in key_name: mat_key = key_name if rpm_key is None: print(f"Warning: No RPM data found in {self.filename}") rpm_value = 0.0 else: # 提取RPM标量值 rpm_value = self.extract_rpm_value(mat_data[rpm_key]) if mat_key is None: print(f"Error: No data found for key '{data_key}' in {self.filename}") continue # 提取时域信号 time_series = mat_data[mat_key].flatten() # 存储数据 self.rpm = rpm_value self.X = np.array(time_series) self.Y = label # 打印加载信息 print(f"Loaded {len(self.X)} samples from '{self.filename}'") print(f"RPM: {self.rpm}, Label: {self.Y}") return self.X, self.Y return None, None

参考文章:

OrderCam-Diag:基于阶次分析和类激活映射的旋转机械可解释故障诊断(Python) - 哥廷根数学学派的文章
https://zhuanlan.zhihu.com/p/2002062403219763577

担任《Mechanical System and Signal Processing》《中国电机工程学报》《宇航学报》《控制与决策》等期刊审稿专家,擅长领域:信号滤波/降噪,机器学习/深度学习,时间序列预分析/预测,设备故障诊断/缺陷检测/异常检测。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 5:55:27

Thinkphp和Laravel框架的广告服务型互联网平台

目录ThinkPHP与Laravel框架在广告服务型互联网平台的应用对比开发效率与学习成本性能与扩展性安全与维护典型应用场景技术栈建议开发技术源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!ThinkPHP与Laravel框架在广告服务型互联网平台的应…

作者头像 李华
网站建设 2026/5/1 5:53:19

编译鸿蒙6.0release版本出错

编译bash build/build_scripts/env_setup.sh 出错Installing /home/tools/qemu-5.2.0/pc-bios/keymaps/sv to /usr/local/share/qemu/keymapsnpm ERR! code E404npm ERR! 404 Not Found - GET https://repo.harmonyos.com/npm/ohos%2fhpm-clinpm ERR! 404npm ERR! 404 ohos/hp…

作者头像 李华
网站建设 2026/5/1 5:53:05

超表面全息成像仿真全流程探索:从理论到实践

基于超表面全息成像 仿真 全流程,视频演示,代码,文献,案例 复振幅全息 纯相位全息 近场远场成像最近在研究超表面全息成像相关内容,发现这个领域真的很有意思,今天就来和大家分享一下基于超表面全息成像仿真…

作者头像 李华
网站建设 2026/5/1 7:01:34

凌晨 3 点投第 400 份简历前,AI 告诉我:你简历里有 3 个自杀式错误

深夜 3 点的屏幕光很刺眼,但比光更凉的是那 399 份石沉大海的投递记录。 在 2026 年的求职环境下,“勤奋”正在成为平庸者的遮羞布。 如果你投了 400 份简历依然全无回音,这绝不是运气问题,而是你的简历触发了大厂后台 ATS&#…

作者头像 李华
网站建设 2026/5/1 5:54:06

上线120小时,Moltbook全球瘫痪!150万AI服务器已炸?

就在刚刚,火遍全球的Moltbook,已经瘫痪了!网站无法访问,服务器账单已经涨成天文数字。刚被扒皮150万AI中大多数是人类假扮的,这个爆红的现象级网站就倒了。刚刚,Moltbook已经崩了。这个红极一时的网站&…

作者头像 李华
网站建设 2026/4/23 13:09:52

JY-KMT-LORA 微型LORA数传模块

JY-KMT-LORA 微型LORA数传模块 lora扩频数传网关 微型LORA数传模块 RS485转LORA模块 LORA无线串口模块 RS485转LORA 数传模块

作者头像 李华