赞
踩
卷积神经网络作为深度学习的经典算法之一,凭借局部连接和权值共享的优点,有效地降低了传统神经网络的复杂度。卷积神经网络结构由输入层、卷积层、池化层、全连接层和输出层等构成。
图 卷积神经网络
卷积层采用多组卷积核与输入层进行卷积运算,从输入层的原始数据中提取出新的特征信息。
池化层通过缩小卷积层提取出的特征信息的大小,挖掘提取特征的深度信息,实现特征信息的降维。
全连接层在卷积网络中充当着“分类器”的作用,将全连接层全部神经元学到的目标对象特征,映射到目标对象的标记空间,实现分类的目的。
数据集为通过ADAMS仿真,做了四种轴承故障数据集。四种故障类型为磨损、点蚀、断齿、正常,仿真数据为6000点的振动信号。
训练集:数据集为同一工况下采集的真实轴承振动数据。
测试集: 数据集为对应工况及结构数据,仿真出来的轴承仿真数据。
下图为仿真数据图和真实数据图。
图 轴承振动数据(左为仿真数据,右为真实数据)
注释:该数据的数据集幅值在仿真输出时进行了数据对齐。所以仿真数据和真实数据的幅值相互近似。
数据集数目:训练集为720组(每种故障数目为180组),测试集为180组(每种故障类型为45组)。
- from tensorflow.keras.layers import Dense, Conv1D, BatchNormalization, MaxPooling1D, Activation, Flatten,Dropout
- from tensorflow.keras.models import Sequential
- import numpy as np
- import tensorflow as tf
- from sklearn.manifold import TSNE
- import matplotlib.pyplot as plt
- import scipy.io as scio
- plt.rcParams['font.sans-serif'] = ['kaiti']
- plt.rcParams['axes.unicode_minus'] = False
- import pandas as pd
- # 确保结果尽可能重现
- from numpy.random import seed
- seed(1)
- tf.random.set_seed(1)
-
- # 测试集验证集划分比例
- # 加载mat数据集
- dataFile = r'E:\matlab程序\data.mat'
-
- data = scio.loadmat(dataFile)
-
-
- #训练集
- x_train = data['train_data']
- y_train= data['train_label']
-
- x_test =data['test_data']
- y_test =data['test_label']
-
-
- x_train, x_test = x_train[:,:,np.newaxis], x_test[:,:,np.newaxis]
- y_train = np.array(y_train, dtype='float64')
- y_test = np.array(y_test, dtype='float64')
-
-
- print(x_train.shape)
- print(x_test.shape)
- print(y_train.shape)
- print(y_test.shape)

- # 实例化序贯模型
- model = Sequential()
- # 搭建输入层,第一层卷积。
- model.add(Conv1D(filters=32, kernel_size=16, strides=1, padding='same', input_shape=(6000,1)))
- model.add(BatchNormalization())
- model.add(Activation('relu'))
- model.add(MaxPooling1D(pool_size=2,strides=1,padding='valid'))
-
- # 第二层卷积
- model.add(Conv1D(filters=32, kernel_size=3, strides=1, padding='same'))
- model.add(BatchNormalization())
- model.add(Activation('relu'))
- model.add(MaxPooling1D(pool_size=2,strides=1, padding='valid'))
-
- # 从卷积到全连接需要展平
- model.add(Flatten())
- # 添加全连接层
- model.add(Dense(units=128))
- model.add(Dense(units=64))
- model.add(Dense(units=32))
- model.add(Dense(units=16))
- model.add(Dense(units=8))
- # 增加输出层
- model.add(Dense(units=4, activation='softmax'))
-
-
- # 查看定义的模型
- model.summary()
-
- # 编译模型 评价函数和损失函数相似,不过评价函数的结果不会用于训练过程中
- model.compile(optimizer='Adam', loss='categorical_crossentropy',
- metrics=['acc'])
-
- # 该模型的最优参数为:训练迭代次数10次,训练批次为16,同时规定了随机种子数.
- # 开始模型训练
- history=model.fit(x_train, y_train,
- batch_size=4,
- epochs=20,
- verbose=1,
- shuffle=True)
-
- #测试集的x_test
- predict= model.predict(x_test, batch_size=32, verbose=1,)
-
- test_label = np.argmax(y_test,axis=-1) #将one-hot标签转为一维标签
-
- predict_label = np.argmax(predict,axis=-1) #将one-hot标签转为一维标签
- print(predict_label.shape)
- print(test_label.shape)
-
-
-
- #评估精确度
- import numpy as np
- predicitons = (test_label == predict_label)
- acc1 = np.sum(predicitons == True) / len(predict_label)
- print(acc1)
-
-
-
-
- #混淆矩阵可视化
- import matplotlib.pyplot as plt
- from sklearn.metrics import confusion_matrix
-
- def cm_plot(original_label, predict_label, pic=None):
- cm = confusion_matrix(original_label, predict_label) # 由原标签和预测标签生成混淆矩阵
- plt.matshow(cm,cmap=plt.cm.Blues) # 画混淆矩阵,配色风格使用cm.Blues
- plt.colorbar() # 颜色标签
- for x in range(len(cm)):
- for y in range(len(cm)):
- plt.annotate(cm[x, y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
- # annotate主要在图形中添加注释
- # 第一个参数添加注释
- # 第二个参数是注释的内容
- # xy设置箭头尖的坐标
- # horizontalalignment水平对齐
- # verticalalignment垂直对齐
- # 其余常用参数如下:
- # xytext设置注释内容显示的起始位置
- # arrowprops 用来设置箭头
- # facecolor 设置箭头的颜色
- # headlength 箭头的头的长度
- # headwidth 箭头的宽度
- # width 箭身的宽度
- plt.ylabel('真实标签') # 坐标轴标签
- plt.xlabel('预测标签') # 坐标轴标签
- plt.title('混淆矩阵')
- if pic is not None:
- plt.savefig(str(pic) + '.jpg')
- plt.show()
-
- cm_plot(test_label,predict_label,pic=None)#
-
-
-
- # # # 创建一个绘图窗口
- plt.figure()
- acc = history.history['acc']
- loss = history.history['loss']
-
-
- epochs = range(len(acc))
-
- plt.plot(epochs, acc,'r*-', linewidth=2.5, alpha = 0.8, label='训练集准确率') # 'bo'为画蓝色圆点,不连线
- plt.title('训练集准确率')
- plt.legend() # 绘制图例,默认在右上角
- plt.figure()
- plt.plot(epochs, loss,'r*-',linewidth=2.5, alpha = 0.8, label='训练集损失率')
- plt.title('训练集损失率')
- plt.legend()
- plt.show()
-
- # # #输出训练历史数据 loss acc
- print(loss)
- print(acc)
- pd.DataFrame(history.history).to_csv('training_log4.csv', index=False)
-
-
-
- # # -------------------------------获取模型最后一层的数据--------------------------------
- # # 获取model.add(layers.Flatten())数据
- def create_truncated_model(trained_model):
- model = Sequential()
- # 搭建输入层,第一层卷积。
- model.add(Conv1D(filters=32, kernel_size=16, strides=1, padding='same', input_shape=(6000, 1)))
- model.add(BatchNormalization())
- model.add(Activation('relu'))
- model.add(MaxPooling1D(pool_size=2, strides=1, padding='valid'))
-
- # 第二层卷积
- model.add(Conv1D(filters=32, kernel_size=3, strides=1, padding='same'))
- model.add(BatchNormalization())
- model.add(Activation('relu'))
- model.add(MaxPooling1D(pool_size=2, strides=1, padding='valid'))
-
- # 从卷积到全连接需要展平
- model.add(Flatten())
- # 添加全连接层
- model.add(Dense(units=128))
- model.add(Dense(units=64))
- model.add(Dense(units=32))
- model.add(Dense(units=16))
- model.add(Dense(units=8))
- # 增加输出层
- model.add(Dense(units=4, activation='softmax'))
-
- for i, layer in enumerate(model.layers):
- layer.set_weights(trained_model.layers[i].get_weights())
- model.compile(optimizer='Adam',
- loss='categorical_crossentropy',
- metrics=['acc'])
- return model
-
- truncated_model = create_truncated_model(model)
- hidden_features = truncated_model.predict(x_test)
- print(hidden_features.shape)
- color_map = y_test.argmax(axis=-1) #将one-hot标签转为一维标签
-
- #-------------------------------tSNE降维分析--------------------------------
- tsne = TSNE(n_components=2, init='pca',verbose = 1,random_state=0)
- tsne_results = tsne.fit_transform(hidden_features)
- print(tsne_results.shape)
-
- marker1 = ["^", "o", "+", "*", ]
- #-------------------------------可视化--------------------------------
- for cl in range(4):# 总的类别
- indices = np.where(color_map==cl)
- indices = indices[0]
- plt.scatter(tsne_results[indices,0], tsne_results[indices, 1],s=30, marker=marker1[cl], label=cl)
- plt.legend(loc=1,bbox_to_anchor=(1, 1.03))
- #plt.axis('off')
- plt.show()

训练集的损失率和精确度
图 训练集的损失率和精确度
图 混淆矩阵
注释:因为设置仿真时,仿真故障的磨损和点蚀的差异性设计的不太明显。该数据集对于磨损和点蚀的差异性就不明显。所以测试集中,第三种(磨损)和第四种(点蚀)故障类型的故障诊断效果不太明显。
其实是根本分不开,我也跟纠结。
失败原因:主要有两部分
1、我认为训练集应该采用更高质量的仿真数据,可以有效得避免真实数据中的不同噪声信号相互混淆干扰。但是真实数据是对真实故障的对应映射,包含了最真实的故障信息;仿真数据不具备该方面的优势,仿真可能无法一一映射完整的故障信号。
2、该CNN模型的抗噪能力不太行,我设计模型没有考虑到有效的抗噪措施,进一步对模型的抗噪能力进行提升,可能是对故障诊断效果有效得提升。
所以就不放T-SNE的聚类图啦!!!(聚类效果太辣鸡啦!)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。