轴承故障诊断是工业设备预测性维护的关键环节。凯斯西储大学(CWRU)轴承数据集作为该领域最权威的基准数据,包含从正常状态到多种故障类型的完整振动信号记录。传统诊断方法通常直接对一维时序信号进行分析,但这种方法存在两个显著局限:
本项目创新性地将一维振动信号转换为二维特征图像,利用计算机视觉领域的成熟方法实现故障分类。这种技术路线具有三大优势:
实测表明,该方法在CWRU数据集上能达到98%以上的十分类准确率,且代码实现完整可复现。下面将详细解析从数据预处理到模型部署的全流程技术细节。
原始数据包含四种工况下的振动信号:
每种故障又包含不同损伤直径(0.007英寸、0.014英寸、0.021英寸),最终形成10个分类类别。采样频率为12kHz,驱动端轴承型号为SKF6205。
关键提示:实验建议使用DE(驱动端)加速度数据,其信噪比优于FE(风扇端)数据
核心转换流程采用连续小波变换(CWT):
python复制import pywt
import numpy as np
def cwt_transform(signal, scales=20):
# 使用墨西哥帽小波基
wavelet = 'mexh'
coeffs, _ = pywt.cwt(signal, scales, wavelet)
# 归一化到[0,255]图像范围
img = 255 * (coeffs - coeffs.min()) / (coeffs.max() - coeffs.min())
return img.astype(np.uint8)
参数选择依据:
转换后的图像示例:
code复制正常状态 内圈故障 外圈故障
[平稳纹理] [径向条纹] [同心圆环]
基于ResNet18进行轻量化改进:
python复制from torchvision.models import resnet18
class FaultClassifier(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.backbone = resnet18(pretrained=True)
# 修改输入通道数
self.backbone.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
# 修改分类头
self.backbone.fc = nn.Linear(512, num_classes)
def forward(self, x):
return self.backbone(x)
关键改进点:
yaml复制# 超参数设置
epochs: 100
batch_size: 32
optimizer: AdamW
lr: 1e-4
scheduler: CosineAnnealingLR
loss: LabelSmoothingCrossEntropy
创新性实践:
bash复制# 创建conda环境
conda create -n bearing python=3.8
conda install pytorch==1.12.1 torchvision==0.13.1 -c pytorch
pip install pywt scikit-learn matplotlib
python复制# data_loader.py
import os
import numpy as np
from sklearn.model_selection import train_test_split
class CWRUDataset:
def __init__(self, root_dir, segment_length=1024):
self.samples = []
# 遍历所有.mat文件
for file in os.listdir(root_dir):
if file.endswith('.mat'):
data = scipy.io.loadmat(os.path.join(root_dir, file))
signal = data['X'][:,0] # 取DE通道
# 分段采样
for i in range(0, len(signal)-segment_length, segment_length//2):
segment = signal[i:i+segment_length]
self.samples.append((segment, self._get_label(file)))
def _get_label(self, filename):
# 实现文件名到类别标签的映射逻辑
...
python复制# train.py
def main():
# 初始化
dataset = CWRUDataset('CWRU/')
model = FaultClassifier().cuda()
# 数据划分
train_idx, val_idx = train_test_split(range(len(dataset)), test_size=0.2)
train_loader = DataLoader(Subset(dataset, train_idx), batch_size=32, shuffle=True)
# 训练循环
for epoch in range(100):
model.train()
for x, y in train_loader:
x = cwt_transform(x) # 实时转换
pred = model(x.cuda())
loss = criterion(pred, y.cuda())
...
python复制transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5),
transforms.RandomRotation(10),
transforms.ColorJitter(brightness=0.2, contrast=0.2)
])
特殊处理:
通过通道剪枝实现模型压缩:
python复制from torch.nn.utils import prune
# 全局稀疏化
parameters_to_prune = [
(module, 'weight') for module in filter(
lambda m: isinstance(m, nn.Conv2d), model.modules())
]
prune.global_unstructured(parameters_to_prune, pruning_method=prune.L1Unstructured, amount=0.3)
实测效果:
可能原因:
验证集表现差时的对策:
python复制# 正则化配置
optimizer = AdamW(model.parameters(), lr=1e-4, weight_decay=1e-5)
# 早停机制
early_stopping = EarlyStopping(patience=10, delta=0.001)
边缘设备部署建议:
python复制# 导出ONNX
dummy_input = torch.randn(1, 1, 224, 224).cuda()
torch.onnx.export(model, dummy_input, "bearing.onnx", opset_version=11)
本方法可迁移到其他旋转机械故障诊断场景:
工业现场部署时,建议: