ARTICLE DETAIL

资讯详情

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

CWRU轴承数据集故障诊断实战:从数据解析到机器学习建模

CWRU轴承数据集故障诊断实战:从数据解析到机器学习建模 简介本资源是面向机械故障诊断与智能运维领域的科研人员及研究生的凯斯西储大学CWRU轴承数据集完整处理方案解决原始.mat数据加载繁琐、标签映射不清、训练/测试划分不统一等实际建模痛点。压缩包含172个文件165个故障信号mat文件、3个核心Python工具脚本、2个说明文档总大小240.31MB其中cwru.py封装了标准化加载接口支持按采样频率如12DriveEndFault、转速如1797rpm、信号长度如384点一键生成X_train/y_train等结构化数据并内置16类故障类型名称映射与类别数自动识别功能。已有1029人学习下载配套txt使用说明详述参数含义、样本统计方法及典型长度选择建议300–700点适用预览可见Ball、InnerRace、OuterRace等多工况故障样本覆盖0.007mm–0.021mm不同损伤尺寸及3种负载工况开箱即用于深度学习模型训练与对比实验。1. 项目概述为什么CWRU轴承数据集是故障诊断的“金标准”如果你正在研究旋转机械的故障诊断、预测性维护或者想入门机器学习在工业领域的应用那么凯斯西储大学Case Western Reserve University简称CWRU的轴承数据集几乎是你绕不开的起点。我第一次接触这个数据集是在做一个电机早期故障预警的项目当时找遍了公开数据要么信号质量差要么工况单一直到用上CWRU的数据才真正把模型跑出了有说服力的结果。这个数据集之所以被学术界和工业界奉为“金标准”不是因为它数据量最大而是因为它设计科学、标注清晰、场景典型为算法验证提供了一个近乎完美的“试验场”。简单来说CWRU轴承数据集记录了一台实验台电机驱动端和风扇端轴承在不同健康状况正常、内圈故障、外圈故障、滚动体故障和不同故障尺寸从0.007英寸到0.021英寸下运行时的振动信号。数据采集自真实的实验环境包含了驱动电机在四种不同负载0马力、1马力、2马力、3马力下的运行状态这使得数据具有高度的现实参考价值。你拿到的通常是一个数据包里面是.mat格式的MATLAB数据文件每个文件对应一个具体的实验工况。对于研究者或工程师这个数据集的核心价值在于它允许你抛开数据获取和标注的烦恼直接聚焦于核心问题——如何从一段振动信号中准确、鲁棒地识别出故障类型和严重程度。无论是做传统的信号处理如傅里叶变换、小波分析还是应用现代的深度学习模型如CNN、LSTMCWRU数据集都是一个公平、可靠的基准。接下来我将结合我处理这个数据集的完整经验从数据理解、程序整理、到特征工程和模型搭建的完整链路手把手带你用好这个宝藏资源。2. 数据包深度解析文件命名规则与工况映射拿到CWRU数据包第一眼可能会被一堆类似97.mat、105.mat、130.mat的文件名搞懵。这些数字并非随意编排而是包含了轴承位置、故障类型、故障尺寸和负载信息的“密码”。理解这套命名规则是正确使用数据的第一步。原始数据通常按采集的物理通道和采样频率分文件夹存放但经过社区整理一个更常用的版本是已经按工况归类的文件集合。2.1 关键命名规则解密最常见的命名约定如下以驱动端轴承数据为例正常轴承数据通常以97.mat、98.mat、99.mat、100.mat为代表分别对应0, 1, 2, 3马力负载下的正常运行状态。故障轴承数据文件名一般由“轴承位置代码 故障类型代码 故障尺寸代码”构成。轴承位置驱动端Drive End通常用1XX系列风扇端Fan End用2XX系列。故障类型内圈故障Inner Race Fault常用代码7外圈故障Outer Race Fault常用代码14位于6点钟方向即负载区滚动体故障Ball Fault常用代码21故障尺寸通常用故障直径英寸表示如7代表0.007英寸14代表0.014英寸21代表0.021英寸。负载信息隐含在文件名中需要对照官方文档或整理好的映射表。例如105.mat可能表示驱动端1、滚动体故障21、故障尺寸0.014英寸等等这里数字对不上。这正是容易混淆的地方。实际上更可靠的映射需要参考官方文档或社区公认的对照表。一个广泛使用的映射关系示例如下文件名轴承位置故障类型故障直径(英寸)电机负载(马力)近似转速(RPM)97.mat驱动端正常无0179798.mat驱动端正常无1177299.mat驱动-风扇端正常无21750100.mat风扇端正常无31730105.mat驱动端滚动体0.01401797118.mat驱动端内圈0.00701797130.mat驱动端外圈(6点)0.00701797169.mat驱动端内圈0.02101797185.mat驱动端外圈(6点)0.02101797197.mat驱动端滚动体0.02101797注意上表仅为部分示例且不同来源的数据包命名和包含的文件可能略有差异。最关键的一步是找到或自己整理一份与你手头数据包完全对应的“文件名-工况”映射表。没有这个表后续的所有分析都是空中楼阁。2.2 数据内容与结构每个.mat文件通常包含以下关键变量DE驱动端轴承的振动加速度信号单位g。这是最常用的一维时间序列数据。FE风扇端轴承的振动加速度信号。BA基座加速度信号。RPM电机转速每分钟转数。注意负载变化时转速会有微小波动。time时间轴向量。对于大多数故障诊断研究我们主要使用DE信号。数据采样频率通常为12 kHz或48 kHz有不同版本每个文件的数据长度约为10秒即包含约120,000或480,000个数据点。这个长度足够进行各种时频分析和深度学习样本制作。3. Python数据处理全流程从.mat文件到模型输入理解了数据含义下一步就是用Python把它“盘活”。这里会遇到几个典型问题如何读取.mat文件如何根据文件名自动提取标签如何将长序列切割成适合模型训练的小样本下面是我整理并优化过的一套完整程序流程。3.1 环境准备与核心库安装首先确保你的Python环境已安装必要的科学计算和信号处理库。如果你使用pip可以一次性安装pip install numpy scipy matplotlib pandas scikit-learn如果你计划使用深度学习如PyTorch或TensorFlow也需要相应安装。对于信号处理scipy用于读取.mat文件numpy进行数值计算matplotlib用于可视化scikit-learn用于数据划分和评估。3.2 数据加载与解析函数创建一个数据加载模块是高效工作的基础。以下是一个健壮的加载函数示例import os import numpy as np from scipy.io import loadmat import pandas as pd def load_cwru_data(data_path, file_name): 加载单个CWRU数据文件。 参数: data_path: 数据文件夹路径 file_name: 文件名如 105.mat 返回: data_dict: 包含信号、转速等信息的字典 file_path os.path.join(data_path, file_name) try: mat_data loadmat(file_path) except Exception as e: print(f加载文件 {file_path} 失败: {e}) return None # 不同版本的数据文件内部变量名可能不同这里做兼容性处理 # 常见的关键词有 DE, X097_DE_time, drv_DE 等 data_dict {} for key in mat_data.keys(): if not key.startswith(__): # 排除系统变量 # 寻找包含振动信号的变量通常与DE相关 if DE in key.upper() and mat_data[key].size 1000: data_dict[vibration_signal] mat_data[key].flatten() # 展平为一维数组 elif RPM in key.upper(): data_dict[rpm] mat_data[key].flatten()[0] elif time in key.lower(): data_dict[time] mat_data[key].flatten() # 如果没找到标准的DE尝试其他常见命名 if vibration_signal not in data_dict: for key in [X097_DE_time, drv_DE, fe_DE]: if key in mat_data: data_dict[vibration_signal] mat_data[key].flatten() break if vibration_signal not in data_dict: print(f警告: 在文件 {file_name} 中未找到振动信号。) return None data_dict[file_name] file_name return data_dict def parse_label_from_filename(file_name, label_map): 根据文件名和标签映射表解析故障标签。 参数: file_name: 文件名 label_map: 字典键为文件名不含后缀值为标签如 Normal, IR007, OR014等 返回: label: 字符串形式的标签 base_name os.path.splitext(file_name)[0] # 去掉 .mat return label_map.get(base_name, Unknown)3.3 构建标签映射表这是整个流程中最需要耐心但至关重要的一步。你需要根据数据包的文档或社区资料手动创建一个将文件名映射到具体工况的字典或CSV文件。例如# 示例手动构建一个标签映射字典 # 键: 文件名不含.mat 值: 你定义的标签可以是字符串或数字编码 label_mapping { 97: Normal_0hp, 98: Normal_1hp, 99: Normal_2hp, 100: Normal_3hp, 105: B014_0hp, # 滚动体故障0.014英寸0马力 118: IR007_0hp, # 内圈故障0.007英寸0马力 130: OR007_0hp, # 外圈故障0.007英寸0马力 169: IR021_0hp, 185: OR021_0hp, 197: B021_0hp, # ... 根据你的数据包补充完整 } # 更精细的标签适用于多分类任务 detailed_label_mapping { 97: {health: normal, fault_type: normal, fault_size: 0, load: 0}, 105: {health: faulty, fault_type: ball, fault_size: 0.014, load: 0}, # ... }实操心得我强烈建议将label_mapping保存为一个独立的config.py文件或labels.csv。这样当你的数据处理脚本需要分享或复用时别人只需修改这个映射文件而无需改动核心代码。同时在映射表中记录下数据来源如官网链接或论文引用便于追溯。4. 特征工程与样本制作为机器学习模型准备“食粮”原始振动信号是长达数十万点的时间序列直接扔进模型尤其是传统机器学习模型效果通常不好。我们需要从中提取有区分度的特征或将其转化为适合深度学习模型输入的格式。4.1 时域特征提取时域特征计算简单物理意义明确是入门首选。以下是一些经典特征的计算方法def extract_time_features(signal): 从一维振动信号中提取常用时域特征。 features {} features[mean] np.mean(signal) features[std] np.std(signal) # 标准差反映振动能量 features[rms] np.sqrt(np.mean(signal**2)) # 均方根值经典振动指标 features[peak] np.max(np.abs(signal)) # 峰值 features[p2p] np.ptp(signal) # 峰峰值 features[skewness] pd.Series(signal).skew() # 偏度反映分布不对称性 features[kurtosis] pd.Series(signal).kurtosis() # 峭度对冲击敏感故障诊断常用 # 波形指标 features[crest_factor] features[peak] / features[rms] if features[rms]!0 else 0 features[impulse_factor] features[peak] / np.mean(np.abs(signal)) if np.mean(np.abs(signal))!0 else 0 features[shape_factor] features[rms] / np.mean(np.abs(signal)) if np.mean(np.abs(signal))!0 else 0 return features4.2 频域特征提取FFT轴承故障会在振动频谱上产生特定的特征频率如内圈故障频率BPFI、外圈故障频率BPFO等。通过快速傅里叶变换FFT将信号转换到频域是关键一步。def extract_freq_features(signal, fs12000): 从振动信号中提取频域特征。 参数: signal: 时域信号 fs: 采样频率 (Hz) n len(signal) # 计算FFT fft_vals np.fft.fft(signal) fft_freq np.fft.fftfreq(n, 1/fs) # 取单边频谱 half_n n // 2 abs_fft np.abs(fft_vals[:half_n]) freq fft_freq[:half_n] features {} # 频谱重心 features[fc] np.sum(freq * abs_fft) / np.sum(abs_fft) if np.sum(abs_fft)!0 else 0 # 均方频率 features[msf] np.sum((freq**2) * abs_fft) / np.sum(abs_fft) if np.sum(abs_fft)!0 else 0 # 频率方差 features[vf] np.sum(((freq - features[fc])**2) * abs_fft) / np.sum(abs_fft) if np.sum(abs_fft)!0 else 0 # 寻找前N个主要频率成分的幅值和频率 top_n 5 top_indices np.argsort(abs_fft)[-top_n:][::-1] for i in range(top_n): features[ffreq_{i}] freq[top_indices[i]] features[famp_{i}] abs_fft[top_indices[i]] return features, freq, abs_fft # 返回特征和原始频谱用于绘图4.3 为深度学习制作样本滑动窗口切割对于CNN、LSTM等模型我们通常将长序列切割成固定长度的小样本每个样本作为一个训练实例。def create_samples(signal, label, window_size1024, step_size512): 将长序列信号切割成重叠的小样本。 参数: signal: 一维振动信号数组 label: 该信号对应的标签 window_size: 每个样本的长度如1024点 step_size: 滑动步长如512点步长小于窗口大小时会产生重叠样本可以增加数据量。 返回: samples: 样本数组形状为 (n_samples, window_size) labels: 标签数组形状为 (n_samples,) n_samples (len(signal) - window_size) // step_size 1 samples np.zeros((n_samples, window_size)) labels np.full(n_samples, label) for i in range(n_samples): start i * step_size end start window_size samples[i] signal[start:end] return samples, labels注意事项窗口大小window_size的选择至关重要。太小可能无法包含一个完整的故障冲击周期太大则样本数量减少且可能包含过多无关信息。对于CWRU的12kHz数据一个经验值是选择8192约0.68秒或4096点。步长step_size通常设为窗口大小的1/2或1/4以增加样本多样性。务必确保同一个.mat文件切割出来的所有样本共享同一个标签。4.4 构建完整的数据集将上述步骤组合起来构建一个可以用于训练的数据集特征矩阵和标签向量。def build_dataset(data_path, label_mapping, feature_typetime, window_size1024, step_size512): 构建完整的数据集。 参数: data_path: 数据文件夹路径 label_mapping: 标签映射字典 feature_type: time, freq, 或 raw原始信号样本 window_size, step_size: 仅当feature_typeraw时有效 返回: X: 特征矩阵 (n_samples, n_features) 或 (n_samples, window_size) y: 标签向量 (n_samples,) label_encoder: 用于将字符串标签编码为数字的LabelEncoder对象 from sklearn.preprocessing import LabelEncoder all_features [] all_labels [] file_list [f for f in os.listdir(data_path) if f.endswith(.mat)] for file_name in file_list: print(f处理文件: {file_name}) data_dict load_cwru_data(data_path, file_name) if data_dict is None: continue signal data_dict[vibration_signal] label_str parse_label_from_filename(file_name, label_mapping) if feature_type raw: # 深度学习样本 samples, labels create_samples(signal, label_str, window_size, step_size) all_features.append(samples) all_labels.append(labels) else: # 传统机器学习特征 if feature_type time: features extract_time_features(signal) elif feature_type freq: features, _, _ extract_freq_features(signal) else: # 可以组合时域和频域特征 time_feat extract_time_features(signal) freq_feat, _, _ extract_freq_features(signal) features {**time_feat, **freq_feat} all_features.append(list(features.values())) all_labels.append(label_str) # 合并数据 if feature_type raw: X np.vstack(all_features) y np.hstack(all_labels) else: X np.array(all_features) y np.array(all_labels) # 将字符串标签编码为数字 le LabelEncoder() y_encoded le.fit_transform(y) return X, y_encoded, le5. 从特征到模型一个完整的故障分类实战案例假设我们已经通过build_dataset函数得到了时域特征矩阵X和编码后的标签y。现在我们用一个简单的机器学习流程演示如何进行分类。5.1 数据划分与标准化from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 划分训练集和测试集注意 stratify 参数可以保持各类别比例一致 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42, stratifyy) # 标准化特征减去均值除以标准差。这对基于距离的模型如SVM至关重要。 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 注意使用训练集的均值和标准差来转换测试集5.2 训练与评估分类器我们以支持向量机SVM和随机森林Random Forest为例它们在小样本的故障诊断中表现通常不错。from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, confusion_matrix, accuracy_score import seaborn as sns import matplotlib.pyplot as plt # 初始化模型 svm_model SVC(kernelrbf, C10, gammascale, random_state42) # RBF核适合非线性问题 rf_model RandomForestClassifier(n_estimators100, max_depth10, random_state42) # 训练SVM svm_model.fit(X_train_scaled, y_train) y_pred_svm svm_model.predict(X_test_scaled) print(SVM分类报告:) print(classification_report(y_test, y_pred_svm, target_nameslabel_encoder.classes_)) print(fSVM准确率: {accuracy_score(y_test, y_pred_svm):.4f}) # 训练随机森林 rf_model.fit(X_train_scaled, y_train) y_pred_rf rf_model.predict(X_test_scaled) print(\n随机森林分类报告:) print(classification_report(y_test, y_pred_rf, target_nameslabel_encoder.classes_)) print(f随机森林准确率: {accuracy_score(y_test, y_pred_rf):.4f}) # 绘制混淆矩阵以随机森林为例 cm confusion_matrix(y_test, y_pred_rf) plt.figure(figsize(10,8)) sns.heatmap(cm, annotTrue, fmtd, cmapBlues, xticklabelslabel_encoder.classes_, yticklabelslabel_encoder.classes_) plt.ylabel(真实标签) plt.xlabel(预测标签) plt.title(混淆矩阵 - 随机森林) plt.tight_layout() plt.show()5.3 深度学习模型示例1D CNN对于原始信号样本feature_typeraw1D卷积神经网络CNN是自然的选择。以下是一个简单的PyTorch模型定义示例import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset class Simple1DCNN(nn.Module): def __init__(self, input_length1024, num_classes10): super(Simple1DCNN, self).__init__() self.conv1 nn.Conv1d(in_channels1, out_channels32, kernel_size7, stride2, padding3) self.bn1 nn.BatchNorm1d(32) self.relu nn.ReLU() self.pool1 nn.MaxPool1d(kernel_size3, stride2, padding1) self.conv2 nn.Conv1d(32, 64, kernel_size5, stride1, padding2) self.bn2 nn.BatchNorm1d(64) self.pool2 nn.MaxPool1d(3, 2, 1) self.conv3 nn.Conv1d(64, 128, kernel_size3, stride1, padding1) self.bn3 nn.BatchNorm1d(128) self.pool3 nn.AdaptiveAvgPool1d(1) # 全局平均池化 self.fc nn.Linear(128, num_classes) def forward(self, x): # x shape: (batch, 1, seq_len) x self.relu(self.bn1(self.conv1(x))) x self.pool1(x) x self.relu(self.bn2(self.conv2(x))) x self.pool2(x) x self.relu(self.bn3(self.conv3(x))) x self.pool3(x) # (batch, 128, 1) x x.view(x.size(0), -1) # (batch, 128) x self.fc(x) return x # 假设我们已经有了样本数据 X_raw (n_samples, window_size) 和标签 y_encoded # 需要将数据转换为PyTorch张量并增加一个通道维度 X_tensor torch.FloatTensor(X_raw).unsqueeze(1) # 形状变为 (n_samples, 1, window_size) y_tensor torch.LongTensor(y_encoded) # 划分数据集 dataset TensorDataset(X_tensor, y_tensor) train_size int(0.8 * len(dataset)) test_size len(dataset) - train_size train_dataset, test_dataset torch.utils.data.random_split(dataset, [train_size, test_size]) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue) test_loader DataLoader(test_dataset, batch_size32, shuffleFalse) # 初始化模型、损失函数和优化器 model Simple1DCNN(input_lengthwindow_size, num_classeslen(np.unique(y_encoded))) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) # 训练循环简化版 num_epochs 20 for epoch in range(num_epochs): model.train() running_loss 0.0 for batch_x, batch_y in train_loader: optimizer.zero_grad() outputs model(batch_x) loss criterion(outputs, batch_y) loss.backward() optimizer.step() running_loss loss.item() print(fEpoch [{epoch1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}) # 测试评估 model.eval() correct 0 total 0 with torch.no_grad(): for batch_x, batch_y in test_loader: outputs model(batch_x) _, predicted torch.max(outputs.data, 1) total batch_y.size(0) correct (predicted batch_y).sum().item() print(f测试集准确率: {100 * correct / total:.2f}%)6. 高级话题与避坑指南6.1 不同负载下的数据使用策略CWRU数据包含了0-3马力四种负载。这既是挑战也是机遇。挑战负载变化会导致振动信号的基线、能量分布发生变化。一个在0马力下训练的模型在3马力数据上可能表现不佳。这就是“域适应”或“迁移学习”要解决的问题。策略1简单在划分训练集和测试集时确保同一负载工况的数据同时出现在训练集和测试集中。例如不要用所有0马力的数据训练去测试所有3马力的数据除非你专门研究跨负载泛化能力。策略2进阶将负载作为一个特征输入模型或者使用对负载变化不敏感的特征如频谱的归一化幅值、包络谱等。6.2 数据不平衡问题正常状态的数据通常远多于故障数据尤其是严重故障。直接训练会导致模型偏向于多数类。解决方法重采样对少数类样本进行过采样如SMOTE算法或对多数类进行欠采样。类别权重在损失函数中为少数类赋予更高的权重。在sklearn的SVC或RandomForestClassifier中设置class_weightbalanced在PyTorch的CrossEntropyLoss中传入weight参数。数据增强对故障信号进行轻微的加噪、时移、缩放生成新的样本。6.3 特征选择与降维当提取了大量时域、频域特征后可能存在冗余。使用特征选择方法如基于树模型的特征重要性、递归特征消除RFE或降维方法如主成分分析PCA可以提升模型效率和泛化能力。from sklearn.feature_selection import SelectFromModel from sklearn.decomposition import PCA # 基于随机森林的特征选择 selector SelectFromModel(RandomForestClassifier(n_estimators100, random_state42), thresholdmedian) X_train_selected selector.fit_transform(X_train_scaled, y_train) X_test_selected selector.transform(X_test_scaled) # 然后使用 X_train_selected 和 X_test_selected 训练模型 # 使用PCA降维 pca PCA(n_components0.95) # 保留95%的方差 X_train_pca pca.fit_transform(X_train_scaled) X_test_pca pca.transform(X_test_scaled) print(f原始特征数: {X_train_scaled.shape[1]}, PCA后特征数: {X_train_pca.shape[1]})6.4 关于采样频率和信号长度的坑CWRU数据集有12 kHz和48 kHz两个版本。务必确认你使用的数据采样频率这直接影响频谱分析的最高频率奈奎斯特频率和故障特征频率的计算。错误设定fs参数会导致整个频域分析失效。另外在切割样本时要确保样本长度window_size能覆盖至少几个故障冲击周期。轴承故障特征频率通常为转频的几倍到几十倍。例如电机转速约1800 RPM30 Hz内圈故障频率BPFI约为5.4倍转频162 Hz。那么故障周期约为1/162 ≈ 0.0062秒。在12 kHz下一个周期约74个采样点。因此窗口大小至少应为几百到几千个点才能捕捉到重复模式。7. 项目组织与代码管理建议一个清晰的项目结构能让你的工作可复现、易分享。我推荐如下目录结构cwru_bearing_analysis/ ├── data/ │ ├── raw/ # 存放原始的 .mat 文件 │ └── processed/ # 存放处理后的 .npy 或 .pkl 文件 ├── src/ │ ├── config.py # 存放标签映射、文件路径等配置 │ ├── data_loader.py # 数据加载和解析函数 │ ├── feature_extractor.py # 特征提取函数 │ ├── models.py # 机器学习/深度学习模型定义 │ └── utils.py # 工具函数绘图、评估等 ├── notebooks/ │ └── exploratory_analysis.ipynb # Jupyter notebook用于探索性分析 ├── scripts/ │ ├── 01_preprocess_data.py │ ├── 02_train_ml_model.py │ └── 03_train_dl_model.py ├── results/ │ ├── figures/ # 保存生成的图表 │ └── models/ # 保存训练好的模型 ├── requirements.txt # 项目依赖 └── README.md # 项目说明文档在README.md中详细记录数据来源CWRU官网链接。数据包的具体版本和包含的文件列表。你整理的文件名-工况映射表。如何安装依赖 (pip install -r requirements.txt)。如何运行代码复现结果。处理CWRU数据集是一个典型的“数据驱动”项目起点。它麻雀虽小五脏俱全涵盖了从数据理解、预处理、特征工程到建模评估的完整机器学习流程。我个人的体会是不要急于追求复杂的模型先把数据本身“吃透”用简单的模型如SVM、随机森林结合扎实的特征工程跑通基线理解不同故障在信号上的表现差异。这个基础打牢了再去尝试深度学习等更复杂的方法你会对结果有更强的解释力和掌控感。最后这个数据集社区资源丰富多看看相关论文在Google Scholar搜索“CWRU bearing dataset”了解别人是怎么处理负载变化、小样本等问题的能让你少走很多弯路。本文还有配套的精品资源点击获取
返回列表