Fault diagnosis of CNN network (multi-fault type classification of bearings + Python code)

1. Background knowledge: convolutional neural network

        As one of the classic algorithms of deep learning, convolutional neural network effectively reduces the complexity of traditional neural networks by virtue of its advantages of local connections and weight sharing. The convolutional neural network structure consists of input layer, convolution layer, pooling layer, fully connected layer and output layer.

Graph convolutional neural network 

        The convolution layer uses multiple sets of convolution kernels to perform convolution operations with the input layer to extract new feature information from the original data of the input layer.

        The pooling layer reduces the size of the feature information extracted by the convolution layer, mines the depth information of the extracted features, and achieves dimensionality reduction of the feature information.

        The fully connected layer acts as a "classifier" in the convolutional network. It maps the target object features learned by all the neurons in the fully connected layer to the label space of the target object to achieve the purpose of classification.

2. Data set: Bearing data set

The data set is made through ADAMS simulation and four bearing failure data sets. The four fault types are wear, pitting, broken teeth, and normal, and the simulation data is a vibration signal of 6000 points.

Training set: The data set is real bearing vibration data collected under the same working conditions.

Test set: The data set is the simulated bearing simulation data corresponding to the working conditions and structural data.

The figure below shows the simulated data graph and the real data graph.

 Figure bearing vibration data (left is simulated data, right is real data)

Note: The data set amplitudes for this data are data aligned at simulation output. Therefore, the amplitudes of simulated data and real data approximate each other.

 Number of data sets: The training set is 720 groups (180 groups for each fault type), and the test set is 180 groups (45 groups for each fault type).

3. Construction of convolutional neural network

3.1 Database loading

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

3.2 Load the bearing data set of mat

# 确保结果尽可能重现
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)

3.3 Model architecture and T-SNE visualization code

# 实例化序贯模型
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()

3.4 Visualization of training results

Loss rate and accuracy on training set

Loss rate and accuracy on graph training set

graph confusion matrix

4. Result analysis

Note: Because when setting up the simulation, the differences in wear and pitting of simulated faults are not designed to be obvious. This data set is not significantly different for wear and pitting. Therefore, in the test set, the fault diagnosis effect of the third (wear) and fourth (pitting corrosion) fault types is not obvious.

In fact, they are inseparable at all, and I am also entangled with them.

Reasons for failure: There are two main parts

1. I think the training set should use higher quality simulation data, which can effectively avoid different noise signals in real data from confusing each other. However, real data is a corresponding mapping of real faults and contains the most realistic fault information; simulation data does not have this advantage, and simulation may not be able to map complete fault signals one by one.

2. The anti-noise ability of the CNN model is not very good. I did not consider effective anti-noise measures when designing the model. Further improving the anti-noise ability of the model may effectively improve the fault diagnosis effect.

So I won’t include the T-SNE clustering diagram! ! ! (The clustering effect is so awesome!)

Guess you like

Origin blog.csdn.net/weixin_49890890/article/details/131710212