当前位置:   article > 正文

基于连续小波变换和卷积神经网络的轴承故障诊断研究_连续小波变换能将一维数据变为二维嘛?

连续小波变换能将一维数据变为二维嘛?

摘要

       基于凯斯西厨大学的轴承数据,首先利用数据增强方法,对原始数据进行重叠采样,增加样本数量。然后,利用连续小波变换,将一维的训练样本转换为二维RGB图像。其次,将处理好的样本进行样本分割为训练集、测试集,输入到卷积神经网络训练。最后,利用T-SNE降维算法对模型指定网络层进行动态可视化显示。

数据集

        引入了由美国凯斯西储大学(CWRU)数据中心获得的轴承故障基准数据集。采用实验试验台(如图1所示)对轴承缺陷检测信号进行检测。该平台由一个 1.5W 的电动机(左)、扭矩传感器译码器(中)和一个功率测试计(右)组成。通过使用电火花加工对轴承造成损伤,损伤的位置分别为外圈、内圈和滚动体。其中轴承有两种型号,一种是放置在驱动端的轴承,型号为 SKF6205,采样频率为12Khz 和 48Khz。另一种是放置在风扇端的轴承,型号为 SKF6203,采样频率为12Khz。振动信号的采集由加速度计来完成。本文研究所使用的数据均来自采样频率为12Khz的驱动端轴承。同时,实验采用的轴承故障直径为0.007英寸、0.014英寸和0.021英寸。

图1 凯斯西储大学轴承数据

西储大学下载地址:http://csegroups.case.edu/bearingdatacenter/pages/download-data-file

         上面是官方给的数据,自己下载下来,根据自己的需要进行整理归类。下面是我自己整理的数据文件夹。07、14、21是三种轴承尺寸;0、1、2、3是4种不同负载;1797、1772、1750、1797对4种不同负载的速度。如图2所示。

 图2 数据类型数据整理

 数据预处理

        数据预处理部分,利用matlab进行数据增强、连续小波变化。

1.数据增强

        深度学习虽具有很好的学习能力,但通常也有一个弊端:需要在数据量比较大的前提下才能取到一个较好的效果。考虑到每一种轴承故障类型中振动信号的个数只有12万个多,按照1024个振动信号点作为一个样本,最多只有 120 个样本。因此为了增强模型的泛化性和鲁棒性,使用数据增强方法对数据集进行扩充。简单粗暴理解,好比切西瓜,本来一块很大的西瓜,被你按照一定距离、方向切了很多刀,成了好几块均匀的西瓜。

原理参考:基于深度学习的轴承故障识别-数据预处理_轴承故障数据预处理_zhangjiali12011的博客-CSDN博客

2.连续小波变换

        和短时傅里叶变换相比,小波变换有着窗口自适应的特点,即高频信号分辨率高(但是频率分辨率差),低频信号频率分辨率高(但是时间分辨率差),而在工程中常常比较关心低频的频率,关心高频出现的时间,所以近些年用途比较广泛。简单粗暴理解,将本来一维的数据变成二维的图像。

原理参考:https://blog.csdn.net/weixin_42943114/article/details/896032

3.效果展示

由于自己电脑配置有限,计算速度各方面还是有点不足,仅仅做了6类故障诊断。如图3所示。

 105inner数据

 

 118ball数据

 130outer数据

 

 119ball数据

  119inner数据

 131outer数据

图3 六种小波变换效果

 模型训练

         VGG16卷积神经网络结构如4所示,通过反复叠加的卷积层(convolution layer)和池化层(pooling layer),共有13层卷积层和3层全连接层(fully connected layer),而池化层不计权重故不算在总层数之内。卷积层和池化层其实就是对输入图像的一种提取过程,多层卷积池化层相互堆叠,使得网络具有更大感受野的同时又能降低网络参数,并且通过ReLU激活函数使得原本的单一线性变化变得多样化,学习能力也因此增强[10]。经由全连接层和输出层可以将样本进行分类处理,通过softmax 激活函数可以得到当前样本属于不同种类的概率分布。            

   

图4 VGG16模型

  1. db_train = tf.data.Dataset.from_tensor_slices((x_train,y_train))
  2. db_train = db_train.shuffle(1000).batch(4)
  3. db_test = tf.data.Dataset.from_tensor_slices((x_test,y_test))
  4. sample = next(iter(db_train))
  5. print("sample: ",sample[0].shape,sample[1].shape)
  6. #--------------------------------卷积神经网络-----------------------------------------
  7. conv_layers = [
  8. layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  9. layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  10. layers.MaxPool2D(pool_size=[4, 4], strides=4, padding='same'),
  11. # unit 2
  12. layers.Conv2D(128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  13. layers.Conv2D(128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  14. layers.MaxPool2D(pool_size=[4, 4], strides=4, padding='same'),
  15. # unit 3
  16. layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  17. layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  18. layers.MaxPool2D(pool_size=[4, 4], strides=4, padding='same'),
  19. # unit 4
  20. layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  21. layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  22. layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),
  23. # unit 5
  24. layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  25. layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
  26. layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same')
  27. ]
  28. def main():
  29. conv_net = Sequential(conv_layers)
  30. # 测试输出的图片尺寸
  31. conv_net.build(input_shape=[None, 128, 128, 3])
  32. x = tf.random.normal([4, 128, 128, 3])
  33. out = conv_net(x)
  34. print(out.shape)
  35. # 设置全连接层
  36. fc_net = Sequential([
  37. layers.Dense(256, activation=tf.nn.relu),
  38. layers.Dense(128, activation=tf.nn.relu),
  39. layers.Dense(6, activation=None)
  40. ])
  41. conv_net.build(input_shape=[None, 128, 128, 3])
  42. fc_net.build(input_shape=[None, 512])
  43. optimizer = optimizers.Adam(lr=0.00001)
  44. variables = conv_net.trainable_variables + fc_net.trainable_variables
  45. for epoch in range(50):
  46. for step,(x,y) in enumerate(db_train):
  47. with tf.GradientTape() as tape:
  48. out = conv_net(x)
  49. out = tf.reshape(out,[-1,512])
  50. logits = fc_net(out)
  51. y_hot = tf.one_hot(y,depth=3)
  52. # 计算loss数值
  53. loss = tf.losses.categorical_crossentropy(y_hot,logits,from_logits=True)
  54. loss = tf.reduce_mean(loss)
  55. grads = tape.gradient(loss,variables)
  56. optimizer.apply_gradients(zip(grads,variables))
  57. if step % 20 ==0:
  58. print(epoch, step, "loss ", float(loss))
  59. total_num = 0
  60. totsl_correct = 0
  61. for x,y in db_test:
  62. x = tf.expand_dims(x,axis=0)
  63. # print(x.shape)
  64. out = conv_net(x)
  65. out = tf.reshape(out,[-1,512])
  66. logits = fc_net(out)
  67. prob = tf.nn.softmax(logits,axis=1)
  68. pred = tf.argmax(prob,axis=1)
  69. pred = tf.cast(pred,dtype=tf.int32)
  70. correct = tf.cast(tf.equal(pred,y),dtype=tf.int32)
  71. correct = tf.reduce_sum(correct)
  72. total_num += x.shape[0]
  73. totsl_correct += int(correct)
  74. acc = totsl_correct/total_num
  75. print(epoch, acc)
  76. conv_net.save('weights/conv.h5')
  77. fc_net.save('weights/fc.h5')

  模型T-SNE动态显示

1.生成图片

        SNE即stochastic neighbor embedding,其基本思想为在高维空间相似的数据点,映射到低维空间距离也是相似的。SNE把这种距离关系转换为一种条件概率来表示相似性。 

        本文主要通过对全连接层的最后一层输出层进行动态可视化。第一步生成每个epoch的Figure,将其保存到指定的文件夹。最后,利用gif工具制作动态显示图片。万变不离其中,方法有很多种,能实现出效果来就是好。

原理参考:t-SNE数据降维(2维3维)及可视化_t-sne降维_小刘同学_的博客-CSDN博客

  1. #轴承数据训练
  2. for epoch in range(20):
  3. # 定义列表,data_xx存放训练数据,data_y存放训练数据标签
  4. data_xx = []
  5. data_y = []
  6. for step,(x,y) in enumerate(db_train):
  7. with tf.GradientTape() as tape:
  8. #计算一个batchsize的卷积神经网络输出
  9. out = conv_net(x)
  10. #卷积神经网络输出数据进行reshape[-1,512]
  11. out = tf.reshape(out,[-1,512])
  12. #reshape的数据输入到全连接层
  13. logits = fc_net(out)
  14. #最终输出数据进行one_hot转换
  15. y_hot = tf.one_hot(y,depth=6)
  16. # 计算loss数值
  17. loss = tf.losses.categorical_crossentropy(y_hot,logits,from_logits=True)
  18. loss = tf.reduce_mean(loss)
  19. grads = tape.gradient(loss,variables)
  20. optimizer.apply_gradients(zip(grads,variables))
  21. #每隔20个bachsize,输出一次loss数值
  22. if step % 20 ==0:
  23. print(epoch, step, "loss ", float(loss))
  24. if epoch >= 2:
  25. # 列出对应元素的标签值
  26. data_y.extend(y)
  27. # 获取所有训练后的样本数据
  28. for i in range(len(logits)):
  29. # 得到训练的样本
  30. data_xx.append(logits[i])
  31. #每次epoch将data_y和data_xx列表转换为numpy数据
  32. if epoch >= 2:
  33. data_y = np.array(data_y)
  34. data_xx = np.array(data_xx)
  35. # print("data_xx", data_xx.shape)
  36. # print("data_y", data_y.shape)
  37. # print("data_y", data_y)
  38. #进行tsne降维
  39. tsne = manifold.TSNE(n_components=2, init='pca')
  40. X_tsne = tsne.fit_transform(data_xx)
  41. #将降维数据进行可视化显示
  42. x_min, x_max = X_tsne.min(0), X_tsne.max(0)
  43. X_norm = (X_tsne - x_min) / (x_max - x_min) # 归一化
  44. for i in range(len(X_norm)):
  45. # plt.text(X_norm[i, 0], X_norm[i, 1], str(y[i]), color=plt.cm.Set1(y[i]),
  46. if data_y[i] == 0:
  47. color = 'r'
  48. if data_y[i] == 1:
  49. color = 'g'
  50. if data_y[i] == 2:
  51. color = 'b'
  52. if data_y[i] == 3:
  53. color = 'c'
  54. if data_y[i] == 4:
  55. color = 'm'
  56. if data_y[i] == 5:
  57. color = 'k'
  58. # fontdict={'weight': 'bold', 'size': 9})
  59. plt.scatter(X_norm[i][0], X_norm[i][1], c=color, cmap=plt.cm.Spectral)
  60. plt.xticks([])
  61. plt.yticks([])
  62. plt.savefig("E:/tsne_figure/" + str(epoch) + ".png")
  63. plt.close('all')

2.生成gif

  1. # 初始化图片地址文件夹途径
  2. image_path = 'E:/tsne_figure/'
  3. # 获取文件列表
  4. files = os.listdir(image_path)
  5. # 定义第一个文件的全局路径
  6. file_first_path = os.path.join(image_path, files[0])
  7. # 获取Image对象
  8. img = Image.open(file_first_path)
  9. # 初始化文件对象数组
  10. images = []
  11. for image in files[:]:
  12. # 获取当前图片全量路径
  13. img_path = os.path.join(image_path, image)
  14. # 将当前图片使用Image对象打开、然后加入到images数组
  15. images.append(Image.open(img_path))
  16. # 保存并生成gif动图
  17. img.save('beauty.gif', save_all=True, append_images=images, loop=0, duration=200)

3.效果演示

        电脑运算力不行,20个epoch足足跑了一个晚上。最后loss稳定在0.005左右,通过tsne可视化显示,基本实现对不同类型的分离。        

PS:这是本人第一次写博客,有很多不足的地方,请大家见谅。时间比较仓促,过段时间将代码完善,在第二篇文章附上全部代码和数据。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/829802
推荐阅读
相关标签
  

闽ICP备14008679号