当前位置:   article > 正文

Python轴承故障诊断 (六)基于EMD-Transformer的故障分类_python 故障诊断

python 故障诊断

目录

前言

1 经验模态分解EMD的Python示例

2 轴承故障数据的预处理

2.1 导入数据

2.2 制作数据集和对应标签

2.3 故障数据的EMD分解可视化

2.4 故障数据的EMD分解预处理

3 基于EMD-Transformer的轴承故障诊断分类

3.1 训练数据、测试数据分组,数据分batch

3.2 定义Transformer分类网络模型

3.3 设置参数,训练模型


往期精彩内容:

Python-凯斯西储大学(CWRU)轴承数据解读与分类处理

Python轴承故障诊断 (一)短时傅里叶变换STFT

Python轴承故障诊断 (二)连续小波变换CWT

Python轴承故障诊断 (三)经验模态分解EMD

Python轴承故障诊断 (四)基于EMD-CNN的故障分类

Python轴承故障诊断 (五)基于EMD-LSTM的故障分类

Pytorch-LSTM轴承故障一维信号分类(一)

Pytorch-CNN轴承故障一维信号分类(二)

Pytorch-Transformer轴承故障一维信号分类(三)

前言

本文基于凯斯西储大学(CWRU)轴承数据,进行经验模态分解EMD的介绍与数据预处理,最后通过Python实现EMD-Transformer对故障数据的分类。凯斯西储大学轴承数据的详细介绍可以参考下文:

Python-凯斯西储大学(CWRU)轴承数据解读与分类处理

经验模态分解EMD的原理可以参考如下:   

Python轴承故障诊断 (三)经验模态分解EMD

1 经验模态分解EMD的Python示例

第一步,Python 中 EMD包的下载安装:

  1. # 下载
  2. pip install EMD-signal
  3. # 导入
  4. from PyEMD import EMD

切记,很多同学安装失败,不是 pip install EMD,也不是pip install PyEMD, 如果 pip list 中 已经有 emd,emd-signal,pyemd包的存在,要先 pip uninstall 移除相关包,然后再进行安装。

第二步,导入相关包

  1. import numpy as np
  2. from PyEMD import EMD
  3. impor tmatplotlib.pyplot as plt
  4. import matplotlib
  5. matplotlib.rc("font", family='Microsoft YaHei')

第三步,生成一个信号示例

  1. t = np.linspace(0, 1, 1000)
  2. signal = np.sin(11*2*np.pi*t*t) + 6*t*t

第四步,创建EMD对象,进行分解

  1. emd = EMD()
  2. # 对信号进行经验模态分解
  3. IMFs = emd(signal)

第五步,绘制原始信号和每个本征模态函数(IMF)

  1. plt.figure(figsize=(15,10))
  2. plt.subplot(len(IMFs)+1, 1, 1)
  3. plt.plot(t, signal, 'r')
  4. plt.title("原始信号")
  5. for num, imf in enumerate(IMFs):
  6. plt.subplot(len(IMFs)+1, 1, num+2)
  7. plt.plot(t, imf)
  8. plt.title("IMF "+str(num+1))
  9. plt.show()

2 轴承故障数据的预处理

2.1 导入数据

参考之前的文章,进行故障10分类的预处理,凯斯西储大学轴承数据10分类数据集:

train_set、val_set、test_set 均为按照7:2:1划分训练集、验证集、测试集,最后保存数据

上图是数据的读取形式以及预处理思路

2.2 制作数据集和对应标签

第一步, 生成数据集

第二步,制作数据集和标签

  1. # 制作数据集和标签
  2. import torch
  3. # 这些转换是为了将数据和标签从Pandas数据结构转换为PyTorch可以处理的张量,
  4. # 以便在神经网络中进行训练和预测。
  5. def make_data_labels(dataframe):
  6. '''
  7. 参数 dataframe: 数据框
  8. 返回 x_data: 数据集 torch.tensor
  9. y_label: 对应标签值 torch.tensor
  10. '''
  11. # 信号值
  12. x_data = dataframe.iloc[:,0:-1]
  13. # 标签值
  14. y_label = dataframe.iloc[:,-1]
  15. x_data = torch.tensor(x_data.values).float()
  16. y_label = torch.tensor(y_label.values, dtype=torch.int64) # 指定了这些张量的数据类型为64位整数,通常用于分类任务的类别标签
  17. return x_data, y_label
  18. # 加载数据
  19. train_set = load('train_set')
  20. val_set = load('val_set')
  21. test_set = load('test_set')
  22. # 制作标签
  23. train_xdata, train_ylabel = make_data_labels(train_set)
  24. val_xdata, val_ylabel = make_data_labels(val_set)
  25. test_xdata, test_ylabel = make_data_labels(test_set)
  26. # 保存数据
  27. dump(train_xdata, 'trainX_1024_10c')
  28. dump(val_xdata, 'valX_1024_10c')
  29. dump(test_xdata, 'testX_1024_10c')
  30. dump(train_ylabel, 'trainY_1024_10c')
  31. dump(val_ylabel, 'valY_1024_10c')
  32. dump(test_ylabel, 'testY_1024_10c')

2.3 故障数据的EMD分解可视化

选择正常信号和 0.021英寸内圈、滚珠、外圈故障信号数据来做对比

第一步,导入包,读取数据

  1. import numpy as np
  2. from scipy.io import loadmat
  3. import numpy as np
  4. from scipy.signal import stft
  5. import matplotlib.pyplot as plt
  6. import matplotlib
  7. matplotlib.rc("font", family='Microsoft YaHei')
  8. # 读取MAT文件
  9. data1 = loadmat('0_0.mat') # 正常信号
  10. data2 = loadmat('21_1.mat') # 0.021英寸 内圈
  11. data3 = loadmat('21_2.mat') # 0.021英寸 滚珠
  12. data4 = loadmat('21_3.mat') # 0.021英寸 外圈
  13. # 注意,读取出来的data是字典格式,可以通过函数type(data)查看。

第二步,数据集中统一读取 驱动端加速度数据,取一个长度为1024的信号进行后续观察和实验

  1. # DE - drive end accelerometer data 驱动端加速度数据
  2. data_list1 = data1['X097_DE_time'].reshape(-1)
  3. data_list2 = data2['X209_DE_time'].reshape(-1)
  4. data_list3 = data3['X222_DE_time'].reshape(-1)
  5. data_list4 = data4['X234_DE_time'].reshape(-1)
  6. # 划窗取值(大多数窗口大小为1024)
  7. time_step= 1024
  8. data_list1 = data_list1[0:time_step]
  9. data_list2 = data_list2[0:time_step]
  10. data_list3 = data_list3[0:time_step]
  11. data_list4 = data_list4[0:time_step]

第三步,进行数据可视化

  1. plt.figure(figsize=(20,10))
  2. plt.subplot(2,2,1)
  3. plt.plot(data_list1)
  4. plt.title('正常')
  5. plt.subplot(2,2,2)
  6. plt.plot(data_list2)
  7. plt.title('内圈')
  8. plt.subplot(2,2,3)
  9. plt.plot(data_list3)
  10. plt.title('滚珠')
  11. plt.subplot(2,2,4)
  12. plt.plot(data_list4)
  13. plt.title('外圈')
  14. plt.show()

第四步,首先对正常数据进行EMD分解

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from PyEMD import EMD
  4. t = np.linspace(0, 1, time_step)
  5. data = np.array(data_list1)
  6. # 创建 EMD 对象
  7. emd = EMD()
  8. # 对信号进行经验模态分解
  9. IMFs = emd(data)
  10. # 绘制原始信号和每个本征模态函数(IMF)
  11. plt.figure(figsize=(15,10))
  12. plt.subplot(len(IMFs)+1, 1, 1)
  13. plt.plot(t, data, 'r')
  14. plt.title("Original signal", fontsize=10)
  15. for num, imf in enumerate(IMFs):
  16. plt.subplot(len(IMFs)+1, 1, num+2)
  17. plt.plot(t, imf)
  18. plt.title("IMF "+str(num+1), fontsize=10)
  19. # 增加第一排图和第二排图之间的垂直间距
  20. plt.subplots_adjust(hspace=0.4, wspace=0.2)
  21. plt.show()

其次,内圈故障EMD分解:

然后,滚珠故障EMD分解:

最后,外圈故障EMD分解:

注意,在信号的制作过程中,信号长度的选取比较重要,选择信号长度为1024,既能满足信号在时间维度上的分辨率,也能在后续的EMD分解中分解出数量相近的IMF分量,为进一步做故障模式识别打下基础。

2.4 故障数据的EMD分解预处理

对于EMD分解出的IMF分量个数,并不是所有的样本信号都能分解出8个分量,需要做一下定量分析:

  1. import numpy as np
  2. from PyEMD import EMD
  3. # 加载训练集
  4. train_xdata = load('trainX_1024_10c')
  5. data = np.array(train_xdata)
  6. # 创建 EMD 对象
  7. emd = EMD()
  8. print("测试集:", len(data))
  9. count_min = 0
  10. count_max = 0
  11. count_7 = 0
  12. # 对数据进行EMD分解
  13. for i in range(1631):
  14. imfs = emd(data[i], max_imf=8) # max_imf=8
  15. if len(imfs) > 8 :
  16. count_max += 1
  17. elif len(imfs) < 7:
  18. count_min += 1
  19. elif len(imfs) == 7:
  20. count_7 += 1
  21. print("分解结果IMF大于8:", count_max)
  22. print("分解结果IMF小于7:", count_min)
  23. print("分解结果IMF等于7:", count_7)

由结果可以看出,大部分信号样本 都分解出8个分量,将近1/3的信号分解的不是8个分量。EMD设置不了分解出模态分量的数量(函数自适应),为了使一维信号分解,达到相同维度的分量特征,有如下3种处理方式:

  • 删除分解分量不统一的样本(少量存在情况可以采用);

  • 对于分量个数少的样本采用0值或者其他方法进行特征填充,使其对齐其他样本分量的维度(向多兼容);

  • 合并分量数量多的信号(向少兼容);

本文采用第二、三条结合的方式进行预处理,即删除分量小于7的样本,对于分量大于7的样本,把多余的分量进行合并,使所有信号的分量特征保持同样的维度。

3 基于EMD-Transformer的轴承故障诊断分类

下面基于EMD分解后的轴承故障数据,通过Transformer的编码器部分进行分类来讲解:

3.1 训练数据、测试数据分组,数据分batch

  1. import torch
  2. from joblib import dump, load
  3. import torch.utils.data as Data
  4. import numpy as np
  5. import pandas as pd
  6. import torch
  7. import torch.nn as nn
  8. # 参数与配置
  9. torch.manual_seed(100) # 设置随机种子,以使实验结果具有可重复性
  10. device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 有GPU先用GPU训练
  11. # 加载数据集
  12. def dataloader(batch_size, workers=2):
  13. # 训练集
  14. train_xdata = load('trainX_1024_10c')
  15. train_ylabel = load('trainY_1024_10c')
  16. # 验证集
  17. val_xdata = load('valX_1024_10c')
  18. val_ylabel = load('valY_1024_10c')
  19. # 测试集
  20. test_xdata = load('testX_1024_10c')
  21. test_ylabel = load('testY_1024_10c')
  22. # 加载数据
  23. train_loader = Data.DataLoader(dataset=Data.TensorDataset(train_xdata, train_ylabel),
  24. batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)
  25. val_loader = Data.DataLoader(dataset=Data.TensorDataset(val_xdata, val_ylabel),
  26. batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)
  27. test_loader = Data.DataLoader(dataset=Data.TensorDataset(test_xdata, test_ylabel),
  28. batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)
  29. return train_loader, val_loader, test_loader
  30. batch_size = 32
  31. # 加载数据
  32. train_loader, val_loader, test_loader = dataloader(batch_size)

3.2 定义Transformer分类网络模型

注意:

  • 输入维度为7, 7个分量

  • 输入形状为 torch.Size([32, 1024, 7])

  • 在PyTorch中,transformer模型的性能与batch_first参数的设置相关,当batch_first为True时,输入的形状应为(batch, sequence, feature),这种设置在某些情况下可以提高推理性能。

在使用Transformer模型中的多头注意力时,输入维度必须能够被num_heads(注意力头的数量)整除。因为在多头注意力机制中,输入的嵌入向量会被分成多个头,每个头的维度是embed_dim / num_heads,因此embed_dim必须能够被num_heads整除,以确保能够均匀地分配给每个注意力头。

因为此时EMD分解分量为7个,可以事先适当改变分量个数,或者对信号进行堆叠,使调整多头注意力头数能够与之对应整除的关系。本文采用对信号进行对半切分堆叠,使输入形状为[32, 14, 512]。

3.3 设置参数,训练模型

100个epoch,准确率将近99%,基于EMD-Transformer的分类模型表现优异,分类准确率要好于EMD-CNN、EMD-LSTM模型,参数量也较少;对比单用Transformer模型,EMD对信号的分解也进一步提升了模型分类准确率,继续调参可以进一步提高模型性能。

代码、数据如下:

对数据集和代码感兴趣的,可以关注最后一行

  1. # 加载数据
  2. import torch
  3. from joblib import dump, load
  4. import torch.utils.data as Data
  5. import numpy as np
  6. import pandas as pd
  7. import torch
  8. import torch.nn as nn
  9. # 参数与配置
  10. torch.manual_seed(100) # 设置随机种子,以使实验结果具有可重复性
  11. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  12. #代码和数据集:https://mbd.pub/o/bread/ZZiTlJlt

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/413996
推荐阅读
相关标签
  

闽ICP备14008679号