ARTICLE DETAIL

资讯详情

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

工业故障检测数据集预处理:校验、对齐与阶段感知增强

工业故障检测数据集预处理:校验、对齐与阶段感知增强 简介本资源是面向工业AI算法工程师与计算机视觉研究者的高质量故障检测数据集专为YOLO系列模型训练优化解决工业设备预测性维护、产线质量监控及设备健康评估中的多类别异常定位难题。压缩包共1506个文件含752张真实工业场景JPG图像、对应YOLO格式TXT标注文件、类别定义YAML配置及使用说明DOCX文档整体36.09MB结构规范、开箱即用。已有232人学习下载覆盖腐蚀、软管磨损、活塞故障、受潮四类典型工业缺陷每张图像均经人工精标边界框支持端到端目标检测模型训练与泛化能力验证。资源直接对接智能制造落地场景提供完整数据—标注—配置闭环显著降低工业视觉项目的数据准备与 baseline 构建成本。1. 工业设备故障检测数据集.zip不是“拿来就能训”的压缩包而是需要拆解、校验、适配的故障信号入口你双击打开工业设备故障检测数据集.zip看到一堆.csv、.mat、.txt文件和模糊的README.md第一反应是“终于有现成数据了”——结果跑完第一个 baseline 模型F1-score 卡在 0.42远低于论文里宣称的 0.91。这不是数据不行而是你没意识到这个 zip 包本质是一个工业现场故障信号的原始快照集合它不承诺格式统一、不保证标签可信、不内置设备型号与传感器拓扑映射关系。它服务的对象不是“想试试深度学习的新手”而是熟悉旋转机械振动原理、能看懂加速度时域波形是否含冲击成分、知道轴承故障特征频率怎么算、且手头已有部署 pipeline 的一线算法工程师。它真正价值在于提供真实产线停机前数小时的多源同步采集数据振动电流温度、包含早期微弱故障5%损伤程度样本、保留原始采样率与时间戳对齐信息——这些恰恰是公开学术数据集如 CWRU、PU最缺的“工业味”。如果你正为模型在实验室训得好、上线就失效发愁这个 zip 包值得你花 3 小时做三件事解压后先验校验文件完整性、用脚本批量检查标签一致性、按设备工况分组重切训练/验证集。别急着train.py先让数据开口说话。2. 解压后第一件事用校验脚本筛出“带病文件”避免后续全盘翻车工业现场采集环境复杂USB 掉线、存储卡写满、传感器接触不良都会导致文件损坏或截断。直接用损坏文件训练模型会学到错误模式比如把截断后的零值段当成正常稳态这种错误无法通过调参修复。必须在数据加载前完成二进制级校验。2.1 校验逻辑从文件头到校验和的三层过滤我们不依赖文件后缀名判断类型而是逐个文件执行层1文件头魔数识别检查.mat文件是否以MATLAB字符串开头0x4D 0x41 0x54 0x4C 0x41 0x42.csv是否含合法 CSV 头逗号分隔且首行非空.txt是否为 ASCII 可读文本排除二进制乱码。层2结构完整性验证对.mat文件用scipy.io.loadmat(..., struct_as_recordFalse)尝试加载捕获ValueError如Cannot read compressed MAT files对.csv用pandas.read_csv(..., nrows10)读前10行检查列数是否一致、是否存在全 NaN 列。层3业务逻辑校验验证时间戳连续性相邻行时间差应在采样周期 ±5% 内、振动幅值是否超出传感器量程如 ±50g 的加速度计出现 200g 峰值即可疑、标签文件中故障类型是否在预定义枚举内如[normal, inner_race, outer_race, ball]。2.2 执行脚本Python 实现一键扫描# validate_dataset.py import os import numpy as np import pandas as pd from scipy.io import loadmat import hashlib def check_file_header(filepath): 检查文件头魔数 with open(filepath, rb) as f: header f.read(8) if filepath.endswith(.mat): return header.startswith(bMATLAB) elif filepath.endswith(.csv): try: # 读取前100字节检查是否为可打印ASCII f.seek(0) sample f.read(100).decode(ascii) return , in sample and len(sample.strip()) 0 except (UnicodeDecodeError, OSError): return False return True def check_mat_integrity(filepath): 验证.mat文件可加载且含预期字段 try: data loadmat(filepath, struct_as_recordFalse, squeeze_meTrue) # 检查是否含 vibration 和 label 字段根据实际数据结构调整 required_keys [vibration, label, timestamp] return all(key in data for key in required_keys) except Exception as e: print(f[ERROR] {filepath} load failed: {e}) return False def check_csv_integrity(filepath): 验证.csv时间戳连续性与列一致性 try: df pd.read_csv(filepath, nrows1000) # 仅读前1000行加速 if timestamp not in df.columns or vibration_x not in df.columns: return False # 检查时间戳是否单调递增且间隔合理假设采样率10kHz → 0.0001s间隔 ts_diff np.diff(df[timestamp].values) valid_interval (ts_diff 0) (ts_diff 0.0002) # 允许±100%误差 return valid_interval.all() and len(df.columns) 5 except Exception as e: print(f[ERROR] {filepath} CSV parse failed: {e}) return False def main(dataset_root): bad_files [] for root, _, files in os.walk(dataset_root): for f in files: if f.lower().endswith((.mat, .csv, .txt)): filepath os.path.join(root, f) if not check_file_header(filepath): bad_files.append(f{filepath} - invalid header) continue if f.endswith(.mat) and not check_mat_integrity(filepath): bad_files.append(f{filepath} - mat load failed) elif f.endswith(.csv) and not check_csv_integrity(filepath): bad_files.append(f{filepath} - csv structure invalid) if bad_files: print( 发现异常文件 ) for item in bad_files: print(item) with open(os.path.join(dataset_root, corrupted_files.log), w) as log: log.write(\n.join(bad_files)) print(f\n已记录至 corrupted_files.log建议隔离处理) else: print(✅ 所有文件通过基础校验) if __name__ __main__: main(./industrial_fault_dataset) # 替换为你的解压路径参数说明脚本中nrows1000是为加速校验设的阈值实际生产环境建议设为nrows5000ts_diff 0.0002对应 10kHz 采样率下的容错范围若你的数据是 50kHz请改为0.000025required_keys列表需根据你数据集的README.md中字段名实际修改常见字段包括acc_x,current_rms,temp_bearing等。2.3 校验后必做建立文件健康度索引表校验不是目的而是为了构建可追溯的数据质量档案。运行脚本后生成health_index.csv包含每文件的校验状态、采样率、有效数据点数、标签分布熵衡量标签混乱度filenamefile_typeis_validsampling_rate_hzvalid_pointslabel_entropynotesmotor_01_normal_20230501.matmatTrue1000012800000.0正常工况无噪声motor_02_inner_race_20230502.csvcsvFalse-0-timestamp 断续跳变超阈值该表将成为后续数据清洗、采样策略、模型 debug 的黄金依据——当模型在某类故障上表现差可直接查表定位是否对应文件本身质量偏低。3. 标签对齐为什么你的“故障类型”标签可能全是错的工业数据集的标签陷阱比想象中深同一台电机在不同负载下发生内圈故障其振动频谱形态差异巨大但原始标签只写inner_race更隐蔽的是时间戳漂移——振动传感器与电流传感器由不同采集卡触发存在毫秒级不同步导致标注的“故障起始时刻”在两个信号上指向不同物理状态。若直接按标签切片训练模型学到的可能是“电流突变前100ms的振动波形”而非真正的故障征兆。3.1 三步对齐法从物理意义出发修正标签第一步确认故障物理起点查阅设备维护日志通常随数据集提供maintenance_log.xlsx找到每次故障的首次异常报告时间如巡检员听到异响、PLC 报警代码ERR-702。这是最可靠的故障起点优于人工标注的“波形目视判断点”。第二步跨传感器时间戳校准对齐振动与电流信号的关键是找到共同事件——通常是启动/停机瞬态。编写脚本提取各信号的启动上升沿振动幅值超过均值3σ持续50ms电流RMS跃升200%计算各通道间的时间偏移量# align_sensors.py import numpy as np import pandas as pd def find_startup_edge(signal, threshold_ratio3, min_duration50): 检测信号启动边沿上升沿 mean_val np.mean(signal[:1000]) # 前1000点估算基线 std_val np.std(signal[:1000]) trigger_threshold mean_val threshold_ratio * std_val # 找到首次超过阈值且持续 min_duration 点的位置 above_th signal trigger_threshold for i in range(len(above_th) - min_duration): if above_th[i:imin_duration].all(): return i return -1 def calibrate_timestamps(vib_df, current_df, fs_vib10000, fs_curr1000): 计算振动与电流信号的时间偏移单位秒 vib_edge find_startup_edge(vib_df[vibration_x].values) curr_edge find_startup_edge(current_df[current_rms].values) if vib_edge -1 or curr_edge -1: return 0.0 # 转换为秒振动边沿时间 vib_edge / fs_vib电流边沿时间 curr_edge / fs_curr time_vib vib_edge / fs_vib time_curr curr_edge / fs_curr return time_vib - time_curr # 振动相对于电流的偏移量 # 示例对 motor_01 故障文件执行 vib_data pd.read_csv(motor_01_vib.csv) curr_data pd.read_csv(motor_01_current.csv) offset_sec calibrate_timestamps(vib_data, curr_data) print(f振动信号需向前偏移 {offset_sec:.4f} 秒以对齐电流信号)第三步重标注故障窗口以维护日志时间为基准结合校准后的偏移量在各信号上截取[t_fault - 2.0, t_fault 5.0]秒窗口2秒前置征兆 5秒发展期并用滑动窗口如 0.5秒步长生成细粒度标签序列替代原始单点标签。3.2 标签一致性检查用统计学揪出矛盾标注即使完成对齐仍需验证标签逻辑自洽。例如轴承外圈故障时外圈特征频率f_out (n/2)*(1-d/D*cosα)*frn为滚子数d/D为滚子/节径比α为接触角fr为转速应出现在频谱中若某样本标为outer_race但 FFT 主峰在inner_race频率处则标签极可能错误。编写快速频谱验证脚本from scipy.fft import fft import numpy as np def verify_label_by_spectrum(signal, fs, label, fr_rpm1500): 用频谱主峰验证标签合理性 fr fr_rpm / 60 # 转速 Hz # 预定义各故障特征频率公式以SKF深沟球轴承为例 freq_map { normal: [0], inner_race: [fr * 5.0], # 近似倍频 outer_race: [fr * 3.5], # 近似倍频 ball: [fr * 4.2] # 近似倍频 } if label not in freq_map: return True # 未知标签跳过 # 计算FFT n len(signal) freqs np.fft.fftfreq(n, 1/fs)[:n//2] mag np.abs(fft(signal))[:n//2] # 找主峰频率排除0Hz直流分量 peak_idx np.argmax(mag[1:]) 1 peak_freq freqs[peak_idx] # 检查主峰是否落在目标频带内±10%容差 target_freqs freq_map[label] in_band any(abs(peak_freq - f) 0.1*f for f in target_freqs) return in_band # 对每个样本执行 for file in healthy_files: sig pd.read_csv(file)[vibration_x].values if not verify_label_by_spectrum(sig, fs10000, labelnormal): print(f⚠️ {file} 标为 normal 但频谱主峰异常建议复核)提示特征频率计算需根据实际轴承型号查手册脚本中5.0,3.5,4.2是经验值务必替换为你设备的真实参数。若无手册可用scipy.signal.find_peaks在已知故障样本频谱中手动标定。4. 数据增强不是加噪声而是模拟产线真实退化过程学术数据增强如随机裁剪、高斯噪声在工业场景极易失效真实故障演化是确定性退化过程——轴承裂纹从萌生→扩展→剥落振动冲击脉冲的幅值、周期、衰减特性严格遵循材料力学规律。简单加噪只会让模型学到“噪声鲁棒性”而非“故障演化感知能力”。4.1 退化轨迹建模用 Weibull 分布生成故障阶段标签真实设备故障不是突然发生的而是经历“潜伏期→发展期→劣化期→失效期”四阶段。Weibull 分布能精准描述此过程。对每个故障样本按其采集时间戳t计算所处阶段概率from scipy.stats import weibull_min import numpy as np def weibull_stage_prob(t, shape1.8, scale3600): # shape: 故障增长陡峭度, scale: 特征寿命秒 计算时间t处处于各阶段的概率 # 四阶段划分潜伏(0-0.3), 发展(0.3-0.6), 劣化(0.6-0.9), 失效(0.9-1.0) cdf_t weibull_min.cdf(t, shape, scalescale) stages [latent, developing, deteriorating, failure] probs np.zeros(4) # 潜伏期概率 CDF(t) - CDF(0) 但需归一化到阶段区间 probs[0] np.clip(cdf_t - 0.0, 0, 0.3) / 0.3 if cdf_t 0.3 else 1.0 probs[1] np.clip(cdf_t - 0.3, 0, 0.3) / 0.3 if 0.3 cdf_t 0.6 else (1.0 if cdf_t 0.6 else 0) probs[2] np.clip(cdf_t - 0.6, 0, 0.3) / 0.3 if 0.6 cdf_t 0.9 else (1.0 if cdf_t 0.9 else 0) probs[3] np.clip(cdf_t - 0.9, 0, 0.1) / 0.1 if cdf_t 0.9 else 0 return stages[np.argmax(probs)], probs # 示例某故障样本采集于停机前1200秒 stage, prob_vec weibull_stage_prob(t1200, shape1.5, scale7200) # scale2小时 print(f停机前1200秒处于 {stage} 阶段概率分布 {prob_vec})4.2 阶段感知增强按退化阶段注入不同物理噪声潜伏期注入微弱谐波干扰模拟装配应力释放幅值 5% 基线发展期叠加周期性冲击模拟裂纹扩展撞击冲击间隔 特征频率倒数劣化期添加宽带噪声 幅值调制模拟表面剥落导致的随机撞击失效期引入瞬态削波模拟金属碎屑卡滞def stage_aware_augment(signal, stage, fs10000): 按故障阶段注入物理意义噪声 if stage latent: # 加入 2x, 3x 基频谐波幅值0.03倍 t np.arange(len(signal)) / fs fund_freq 50 # 基频示例 harm_noise 0.03 * (np.sin(2*np.pi*2*fund_freq*t) np.sin(2*np.pi*3*fund_freq*t)) return signal harm_noise elif stage developing: # 周期性冲击每0.01秒100Hz一个冲击符合外圈故障特征频率 impulse_train np.zeros_like(signal) impulse_period int(0.01 * fs) for i in range(0, len(signal), impulse_period): if i len(signal): impulse_train[i] 0.15 # 冲击幅值 return signal impulse_train elif stage deteriorating: # 宽带噪声 幅值调制用轴承转频fr调制噪声包络 fr 25 # 1500rpm 25Hz t np.arange(len(signal)) / fs envelope 0.2 * (1 np.sin(2*np.pi*fr*t)) # 调制包络 noise np.random.normal(0, 0.1, len(signal)) return signal envelope * noise else: # failure # 瞬态削波随机位置将信号截断至±0.8倍幅值 clipped signal.copy() num_clips np.random.randint(3, 8) for _ in range(num_clips): pos np.random.randint(0, len(signal)-100) clipped[pos:pos100] np.clip(clipped[pos:pos100], -0.8, 0.8) return clipped # 对发展期样本增强 dev_signal stage_aware_augment(original_signal, stagedeveloping)注意fund_freq,impulse_period,fr等参数必须来自你设备的实际运行参数不可随意设定。若无实测数据宁可不用增强也别用错误物理模型污染数据。5. 避坑指南工业故障检测数据集的5个血泪经验工业数据集的坑不在代码里而在你忽略的物理细节和现场约束中。以下是我踩过的、导致模型上线后准确率暴跌的5个典型问题按发生频率排序5.1 现象模型在测试集上 AUC0.95部署到边缘设备后 F10.6原因训练时用的是.mat文件中的vibration_x字段已去趋势、滤波但边缘设备 SDK 输出的是原始 ADC 值含直流偏置、50Hz 工频干扰。未做信号预处理链路对齐。解决在训练 pipeline 中强制使用与边缘设备完全一致的预处理代码包括滤波器系数、去趋势方法、量化位宽。用numpy.testing.assert_array_almost_equal对比训练数据与设备输出的前1000点误差 1e-5 即需修正。5.2 现象同一故障类型不同电机上的模型预测结果方差极大原因数据集未提供设备个体差异补偿信息。例如电机A与电机B虽型号相同但轴承安装预紧力不同导致相同故障的冲击响应频率偏移±15%。模型未学习到设备指纹。解决在特征工程中加入设备 ID embedding用 one-hot 或 learnable embedding或对每台设备单独训练轻量模型1MB 参数量。不要强行用单一模型泛化所有设备。5.3 现象标签为normal的样本模型给出高置信度inner_race预测原因normal标签混入了亚健康状态如润滑不足、轻微不对中其振动频谱与早期故障高度相似但被错误归为正常。原始标签未区分“绝对正常”与“允许带病运行”。解决重新定义标签体系增加sub_health类别并用设备维护记录中的油液分析报告、红外热图作为辅助标签来源。宁可减少normal样本量也要保证其纯度。5.4 现象训练时 loss 下降平缓但 validation loss 在第30 epoch 后剧烈震荡原因数据集中存在重复样本同一故障在不同日期采集但未去重导致 validation set 中出现训练集已见样本loss 伪下降。解决用imagehash思路计算信号哈希——对振动信号做 STFT 得到时频图再用cv2.img_hash.pHash计算感知哈希值哈希距离 5 的样本视为重复保留时间戳最早的。5.5 现象模型能检测出故障但报警时间比实际停机晚8小时原因训练目标函数只优化分类准确率未考虑时间敏感性。模型学会在故障晚期冲击明显时才报警错过早期干预窗口。解决改用Time-to-Failure Regression任务将标签从class改为hours_to_failure用 Huber Loss 训练回归模型或在分类损失中加入 Early-warning Penalty —— 若模型在故障前 T 小时未报警则施加额外 loss。6. 终极技巧用“故障可解释性热图”反向验证数据质量当你做完所有清洗、对齐、增强最后一步不是训练而是用模型自身当质检员。我坚持的做法是训练一个轻量 CNNResNet18 修改版最后一层输出 4 类 1 时间回归然后对每个验证样本生成 Grad-CAM 热图观察模型关注区域是否符合物理直觉。6.1 构建可解释性验证流水线import torch import torch.nn as nn from torchvision.models import resnet18 import numpy as np class FaultResNet(nn.Module): def __init__(self, num_classes4): super().__init__() self.backbone resnet18(pretrainedFalse, num_classesnum_classes) # 修改第一层以接受1通道振动信号原为3通道RGB self.backbone.conv1 nn.Conv2d(1, 64, kernel_size7, stride2, padding3, biasFalse) def forward(self, x): return self.backbone(x) # 加载训练好的模型 model FaultResNet(num_classes4) model.load_state_dict(torch.load(best_model.pth)) model.eval() # 生成Grad-CAM热图简化版仅示意 def generate_cam(model, input_tensor, target_class): model.zero_grad() output model(input_tensor) output[0, target_class].backward() gradients model.backbone.layer4[1].conv2.weight.grad pooled_gradients torch.mean(gradients, dim[0, 2, 3]) activations model.backbone.layer4[1].conv2(input_tensor).detach() for i in range(len(pooled_gradients)): activations[:, i, :, :] * pooled_gradients[i] cam torch.mean(activations, dim1).squeeze() cam np.maximum(cam.cpu().numpy(), 0) cam cv2.resize(cam, (input_tensor.shape[2], input_tensor.shape[3])) return cam / np.max(cam) # 对验证集每个样本生成热图并保存 val_loader get_val_dataloader() # 返回 (batch, 1, 224, 224) 形状张量 for i, (x, y_true) in enumerate(val_loader): cam generate_cam(model, x, y_true.item()) # 保存热图与原始信号叠加图 plt.figure(figsize(12,4)) plt.subplot(1,2,1) plt.imshow(x[0,0].cpu().numpy(), cmapjet) plt.title(fOriginal STFT) plt.subplot(1,2,2) plt.imshow(x[0,0].cpu().numpy(), cmapgray, alpha0.6) plt.imshow(cam, cmapjet, alpha0.4) plt.title(fGrad-CAM for class {y_true.item()}) plt.savefig(fcam_debug/sample_{i}.png) plt.close()6.2 热图质量判据3条物理红线生成热图后用以下标准快速评估数据质量热图特征合格表现不合格表现后续动作空间聚焦性热区集中在 STFT 图的特定频带如外圈故障热区在 3.5×fr 附近热区弥散、覆盖全频段检查该样本标签是否错误或信号是否被强干扰污染时间一致性同一故障类型的不同样本热区在 STFT 图上的位置高度一致±2 pixel热区位置随机漂移检查时间戳对齐是否失效或设备工况未标准化如负载波动强度梯度热区强度随故障严重程度单调递增早期故障热区弱且窄晚期热区强且宽强度与故障阶段无相关性检查 Weibull 阶段标注是否准确或增强策略是否破坏物理规律我的习惯每周固定用这个流程跑一次验证集热图存档对比。当发现某类故障的热图一致性在两周内下降 15%立即暂停模型迭代回溯数据清洗脚本——90% 的性能滑坡根源都在数据质量悄然退化。这比任何指标监控都早 3 天预警。希望帮到你。本文还有配套的精品资源点击获取
返回列表