轴承故障诊断一直是工业设备健康管理中的关键难题。传统方法主要依赖振动信号的频谱分析,就像医生用听诊器判断病情一样,需要工程师具备丰富的经验才能从复杂的噪声中识别出微弱的故障特征。而近年来,随着深度学习技术的发展,基于信号转图像+视觉模型的方法正在彻底改变这一领域的工作范式。
这个项目提出了一种创新的轴承故障诊断框架,核心思路是将一维振动信号通过格拉姆角场(GADF)等变换转换为二维图像,然后使用我们设计的Swin-CNN-GAM混合模型进行特征学习和分类。相比传统方法,这种"信号转图像+深度学习"的方案具有三大优势:
格拉姆角场(Gramian Angular Field)是一种将时间序列转换为图像的有效方法。其核心思想是通过将一维信号映射到极坐标系,然后计算角度之间的三角函数值来构建格拉姆矩阵。具体步骤如下:
python复制from pyts.image import GramianAngularField
import matplotlib.pyplot as plt
# 示例信号 (实际应用中替换为真实的振动信号)
signal = np.random.randn(1024)
# GADF转换
gadf = GramianAngularField(image_size=64, method='difference')
image_data = gadf.fit_transform(signal.reshape(1, -1))
# 可视化
plt.figure(figsize=(10,5))
plt.subplot(121)
plt.plot(signal)
plt.title("原始振动信号")
plt.subplot(122)
plt.imshow(image_data[0], cmap='jet', origin='lower')
plt.title("GADF转换结果")
plt.colorbar()
plt.show()
注意:GADF对信号的幅度变化比较敏感,建议在转换前先对信号进行归一化处理。对于非平稳信号,可以先用小波变换进行预处理。
除了GADF,我们还实现了小波变换(DWT)和短时傅里叶变换(STFT)的转换接口,方便研究者对比不同方法的优劣:
| 转换方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| GADF | 保留时序相关性,对周期性特征敏感 | 计算量较大,对噪声敏感 | 稳态振动信号 |
| DWT | 多分辨率分析,适合瞬态特征 | 需要选择合适的小波基 | 冲击型故障 |
| STFT | 直观的时频表示,实现简单 | 时频分辨率受限 | 宽频带分析 |
实际应用中,可以根据信号特性灵活选择转换方法。我们的测试表明,对于轴承故障诊断,GADF在大多数情况下表现最优,特别是当故障特征表现为周期性的冲击信号时。
我们的Swin-CNN-GAM模型是一个创新的混合架构,结合了Swin Transformer的全局建模能力、CNN的局部特征提取优势以及GAM(门控注意力机制)的特征选择能力。模型的主要组件包括:
python复制import torch
import torch.nn as nn
from einops import rearrange
class SwinCNN_GAM(nn.Module):
def __init__(self, in_channels=1, num_classes=10):
super().__init__()
self.stem = nn.Sequential(
nn.Conv2d(in_channels, 64, kernel_size=7, stride=2, padding=3),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
self.stage1 = self._make_layer(64, 64, num_blocks=2)
self.stage2 = self._make_layer(64, 128, num_blocks=2)
self.stage3 = self._make_layer(128, 256, num_blocks=6)
self.stage4 = self._make_layer(256, 512, num_blocks=2)
self.avgpool = nn.AdaptiveAvgPool2d((1,1))
self.fc = nn.Linear(512, num_classes)
def _make_layer(self, in_dim, out_dim, num_blocks):
layers = [SwinBlock(in_dim, out_dim)] if in_dim != out_dim else []
for _ in range(num_blocks - (0 if in_dim != out_dim else 1)):
layers.append(SwinBlock(out_dim, out_dim))
return nn.Sequential(*layers)
def forward(self, x):
x = self.stem(x)
x = self.stage1(x)
x = self.stage2(x)
x = self.stage3(x)
x = self.stage4(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.fc(x)
return x
Swin Transformer通过引入窗口多头自注意力(W-MSA)和移位窗口多头自注意力(SW-MSA)机制,在保持全局建模能力的同时大幅降低了计算复杂度。在我们的实现中,对标准Swin Block做了适当简化:
python复制class SwinTransformerBlock(nn.Module):
def __init__(self, dim, num_heads, window_size=7):
super().__init__()
self.norm1 = nn.LayerNorm(dim)
self.attn = WindowAttention(dim, num_heads, window_size)
self.norm2 = nn.LayerNorm(dim)
self.mlp = nn.Sequential(
nn.Linear(dim, dim*4),
nn.GELU(),
nn.Linear(dim*4, dim)
)
def forward(self, x):
B, C, H, W = x.shape
x = rearrange(x, 'b c h w -> b (h w) c')
x = x + self.attn(self.norm1(x))
x = x + self.mlp(self.norm2(x))
x = rearrange(x, 'b (h w) c -> b c h w', h=H, w=W)
return x
GAM模块通过全通道注意力机制动态调整各通道的重要性,相比传统的SE注意力,GAM不做空间维度的压缩,更适合故障诊断任务中对通道间关系的建模:
python复制class GAM(nn.Module):
def __init__(self, channel, reduction=8):
super().__init__()
self.channel_att = nn.Sequential(
nn.Linear(channel, channel//reduction),
nn.ReLU(inplace=True),
nn.Linear(channel//reduction, channel),
nn.Sigmoid()
)
def forward(self, x):
b, c, _, _ = x.shape
# 通道注意力
channel_att = self.channel_att(x.mean(dim=[2,3])).view(b, c, 1, 1)
return x * channel_att
针对振动信号的特点,我们设计了专门的数据增强策略:
python复制def augment_signal(signal, max_shift=500, noise_level=0.05):
# 随机循环平移
shift = np.random.randint(0, max_shift)
signal = np.roll(signal, shift)
# 添加高斯噪声
noise = np.random.normal(0, noise_level*np.std(signal), len(signal))
signal = signal + noise
# 时间扭曲
if np.random.rand() > 0.5:
scale = 0.8 + 0.4*np.random.rand()
new_length = int(len(signal)*scale)
signal = np.interp(np.linspace(0,len(signal)-1,new_length),
np.arange(len(signal)), signal)
signal = signal[:len(signal)] if len(signal) < new_length else signal[:new_length]
return signal
我们采用标签平滑交叉熵损失(Label Smoothing Cross Entropy)来缓解类别不平衡问题:
python复制class LabelSmoothingCE(nn.Module):
def __init__(self, smoothing=0.1):
super().__init__()
self.smoothing = smoothing
def forward(self, pred, target):
log_prob = F.log_softmax(pred, dim=-1)
nll_loss = -log_prob.gather(dim=-1, index=target.unsqueeze(1))
nll_loss = nll_loss.squeeze(1)
smooth_loss = -log_prob.mean(dim=-1)
loss = (1.0 - self.smoothing) * nll_loss + self.smoothing * smooth_loss
return loss.mean()
我们在CWRU轴承数据集上评估模型性能,该数据集包含四种轴承状态(正常、内圈故障、外圈故障、滚动体故障),每种故障有三种损伤程度(0.007英寸、0.014英寸、0.021英寸)。实验设置如下:
我们对比了几种主流方法在相同测试集上的表现:
| 模型 | 准确率(%) | 参数量(M) | 推理时间(ms) |
|---|---|---|---|
| ResNet50 | 96.2 | 23.5 | 15.2 |
| ViT-Small | 97.1 | 22.1 | 18.7 |
| CNN-LSTM | 95.8 | 12.3 | 21.4 |
| 我们的方法 | 98.7 | 19.8 | 16.5 |
从结果可以看出,我们的Swin-CNN-GAM模型在准确率上显著优于其他方法,同时保持了合理的计算复杂度。特别是在小损伤程度(0.007英寸)的故障识别上,我们的模型比第二名高出2.3个百分点。
为了验证各模块的贡献,我们进行了系统的消融研究:
| 模型变体 | 准确率(%) | ΔAcc |
|---|---|---|
| 完整模型 | 98.7 | - |
| w/o Swin | 97.1 | -1.6 |
| w/o CNN | 96.8 | -1.9 |
| w/o GAM | 97.9 | -0.8 |
| 仅Swin | 96.5 | -2.2 |
| 仅CNN | 95.7 | -3.0 |
结果表明,Swin Transformer和CNN的协同作用对性能提升至关重要,而GAM模块进一步提高了模型的判别能力。
对于资源受限的嵌入式设备,可以采用以下优化策略:
python复制# 量化示例
model = SwinCNN_GAM(num_classes=10)
model.eval()
quantized_model = torch.quantization.quantize_dynamic(
model, {nn.Linear, nn.Conv2d}, dtype=torch.qint8
)
在实际工业场景中,建议采用以下部署架构:
这种分层架构可以在保证实时性的同时,实现高精度的故障诊断。
在实际应用中,可能会遇到以下典型问题:
准确率波动大
模型收敛慢
过拟合
提示:当遇到难以解释的性能下降时,建议可视化GADF图像,检查信号转换过程是否引入了异常模式。