CNNネットワークの故障診断(ベアリングの多重故障タイプ分類+Pythonコード)

1. 背景知識: 畳み込みニューラル ネットワーク

        深層学習の古典的なアルゴリズムの 1 つである畳み込みニューラル ネットワークは、ローカル接続と重み共有の利点により、従来のニューラル ネットワークの複雑さを効果的に軽減します。畳み込みニューラル ネットワークの構造は、入力層、畳み込み層、プーリング層、全結合層、出力層で構成されます。

グラフ畳み込みニューラル ネットワーク 

        畳み込み層は、複数の畳み込みカーネルのセットを使用して入力層との畳み込み演算を実行し、入力層の元のデータから新しい特徴情報を抽出します。

        プーリング層は、畳み込み層によって抽出された特徴情報のサイズを削減し、抽出された特徴の深さ情報をマイニングし、特徴情報の次元削減を実現します。

        全結合層は畳み込みネットワークの「分類器」として機能し、全結合層内のすべてのニューロンによって学習された対象オブジェクトの特徴を対象オブジェクトのラベル空間にマッピングして、分類の目的を達成します。

2. データセット: 軸受データセット

データ セットは、ADAMS シミュレーションと 4 つのベアリング故障データ セットを通じて作成されています。故障タイプは摩耗、孔食、歯の破損、正常の 4 つで、シミュレーション データは 6000 ポイントの振動信号です。

トレーニング セット: データ セットは、同じ作業条件下で収集された実際のベアリング振動データです。

テスト セット: データ セットは、動作条件と構造データに対応する模擬軸受シミュレーション データです。

以下の図は、シミュレーションされたデータのグラフと実際のデータのグラフを示しています。

 図軸受振動データ(左がシミュレーションデータ、右が実データ)

注: このデータのデータセット振幅は、シミュレーション出力で調整されたデータです。したがって、シミュレートされたデータと実際のデータの振幅は互いに近似します。

 データセットの数: トレーニング セットは 720 グループ (各障害タイプごとに 180 グループ)、テスト セットは 180 グループ (各障害タイプごとに 45 グループ) です。

3. 畳み込みニューラルネットワークの構築

3.1 データベースのロード

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 マットの軸受データセットをロードする

# 确保结果尽可能重现
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 モデル アーキテクチャと T-SNE 視覚化コード

# 实例化序贯模型
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 トレーニング結果の可視化

トレーニングセットの損失率と精度

グラフトレーニングセットの損失率と精度

グラフ混同行列

4. 結果の分析

注: シミュレーションを設定するとき、シミュレートされた故障の摩耗と孔食の違いが明らかになるように設計されていないためです。このデータセットは、摩耗と孔食に関して大きな違いはありません。したがって、テストセットでは、3 番目 (摩耗) および 4 番目 (孔食) の故障タイプの故障診断効果は明ら​​かではありません。

実際、彼らは決して切り離せないものであり、私も彼らと絡み合っています。

失敗の理由: 大きく 2 つの部分があります

1. トレーニング セットでは、実際のデータ内のさまざまなノイズ信号が互いに混乱するのを効果的に回避できる、より高品質のシミュレーション データを使用する必要があると思います。ただし、実際のデータは実際の障害の対応するマッピングであり、最も現実的な障害情報が含まれています。シミュレーション データにはこの利点がなく、シミュレーションでは完全な障害信号を 1 つずつマッピングできない場合があります。

2. CNN モデルの耐ノイズ能力はあまり高くありません。モデルを設計するときに効果的なノイズ対策を考慮していませんでした。モデルの耐ノイズ能力をさらに向上させると、故障診断効果が効果的に向上する可能性があります。

したがって、T-SNE クラスタリング図は含めません。(クラスタリング効果がすごい!)

おすすめ

転載: blog.csdn.net/weixin_49890890/article/details/131710212