連続ウェーブレット変換と畳み込みニューラルネットワークに基づく軸受故障診断に関する研究

概要

       ケースウエスタンキッチン大学の方位データに基づいて、まず、データ拡張法を使用して元のデータをオーバーサンプリングし、サンプル数を増やします。次に、連続ウェーブレット変換を使用して、1次元のトレーニングサンプルが2次元のRGB画像に変換されます。次に、処理されたサンプルはトレーニングセットとテストセットに分割され、畳み込みニューラルネットワークトレーニングに入力されます。最後に、T-SNE次元削減アルゴリズムを使用して、モデルで指定されたネットワーク層を動的に視覚化します。

データセット

        米国のケースウエスタンリザーブ大学(CWRU)データセンターによって取得されたベアリング故障ベンチマークデータセットが紹介されています。実験的なテストベンチ(図1に示す)を使用して、ベアリングの欠陥検出信号を検出します。プラットフォームは、1.5Wの電気モーター(左)、トルクセンサーデコーダー(中央)、および電力テストメーター(右)で構成されています。軸受はEDMの使用により損傷し、損傷位置は外輪、内輪、転動体です。ベアリングには2種類あります。1つはドライブ側に配置されたベアリング、モデルはSKF6205、サンプリング周波数は12Khzと48Khzです。もう1つはファン側に配置されたベアリングで、モデルはSKF6203、サンプリング周波数は12Khzです。振動信号の取得は、加速度計によって行われます。この調査で使用されたデータはすべて、12Khzのサンプリング周波数のドライブエンドベアリングからのものです。一方、実験で使用した軸受破損径は、0.007インチ、0.014インチ、0.021インチでした。

図1ケースウエスタンリザーブ大学の方位データ

ウエスタンリザーブ大学のダウンロードアドレス:http ://csegroups.case.edu/bearingdatacenter/pages/download-data-file

         上記は公式データであり、ご自身でダウンロードし、ご自身のニーズに合わせて整理・分類してください。以下は私が自分で整理したデータフォルダです。07、14、21は3つのベアリングサイズ、0、1、2、3は4つの異なる荷重、1797、1772、1750、1797は4つの異なる荷重の速度です。写真2に示すように。

 図2データ型のデータ編成

 データ前処理

        データ前処理の部分では、データの拡張と連続ウェーブレットの変更にmatlabを使用します。

1.データ拡張

        深層学習には優れた学習能力がありますが、通常は欠点があります。より良い効果を得るには、比較的大量のデータが必要です。各軸受故障タイプの振動信号の数が120,000を超えるだけであることを考慮すると、サンプルとしての1024の振動信号ポイントによると、最大で120のサンプルしかありません。したがって、モデルの一般化と堅牢性を強化するために、データ拡張メソッドを使用してデータセットを拡張します。シンプルで大まかな理解は、スイカを切るようなものです。元々は大きなスイカでしたが、一定の距離と方向に合わせてたくさんのナイフを切り、いくつかの均一なスイカに変えました。

原則参照:https ://blog.csdn.net/zhangjiali12011/article/details/98039748

2.連続ウェーブレット変換

        短時間フーリエ変換と比較して、ウェーブレット変換はウィンドウ適応の特性を持っています。つまり、高周波信号は高分解能(ただし周波数分解能は低い)であり、低周波信号は高周波分解能(ただし低周波数)です。時間分解能)エンジニアリングでは、低周波数の周波数と高周波数が現れる時間を気にすることが多いため、近年広く使用されています。シンプルで失礼な理解、元の1次元データを2次元画像に変換します。

原則リファレンス:https ://blog.csdn.net/weixin_42943114/article/details/896032

3.エフェクト表示

私のコンピュータの構成が限られているため、計算速度はすべての面でまだ少し不十分であり、6種類の障害診断しか行われていません。図3に示すように。

 105内部データ

 

 118ボールデータ

 130外部データ

 

 119ボールデータ

  119内部データ

 131外部データ

図36つのウェーブレット変換効果

 モデルトレーニング

         VGG16畳み込みニューラルネットワークの構造を4に示します。畳み込み層プーリング繰り返し積み重ねることにより、13畳み込み層と3個の完全に接続された層があります。プーリング層は重みをカウントしないため、含まれていません。レイヤーの総数で。畳み込み層とプーリング層は、実際には入力画像の抽出プロセスです。多層畳み込みプーリング層は互いに積み重ねられているため、ネットワークの、ネットワークパラメータが減少します。受容野ます[10] サンプルは、完全に接続されたレイヤーと出力レイヤーを介して分類でき、異なるカテゴリに属する​​現在のサンプルの確率分布は、softmax活性化関数を介して取得できます。            

   

図4VGG16モデル

db_train = tf.data.Dataset.from_tensor_slices((x_train,y_train))
db_train = db_train.shuffle(1000).batch(4)

db_test = tf.data.Dataset.from_tensor_slices((x_test,y_test))

sample = next(iter(db_train))
print("sample: ",sample[0].shape,sample[1].shape)

#--------------------------------卷积神经网络-----------------------------------------
conv_layers = [
    layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[4, 4], strides=4, padding='same'),

    # unit 2
    layers.Conv2D(128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.Conv2D(128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[4, 4], strides=4, padding='same'),

    # unit 3
    layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[4, 4], strides=4, padding='same'),

    # unit 4
    layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same'),

    # unit 5
    layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),
    layers.MaxPool2D(pool_size=[2, 2], strides=2, padding='same')
]

def main():
    conv_net = Sequential(conv_layers)
    # 测试输出的图片尺寸
    conv_net.build(input_shape=[None, 128, 128, 3])
    x = tf.random.normal([4, 128, 128, 3])
    out = conv_net(x)
    print(out.shape)

    # 设置全连接层
    fc_net = Sequential([
        layers.Dense(256, activation=tf.nn.relu),
        layers.Dense(128, activation=tf.nn.relu),
        layers.Dense(6, activation=None)
    ])

    conv_net.build(input_shape=[None, 128, 128, 3])
    fc_net.build(input_shape=[None, 512])
    optimizer = optimizers.Adam(lr=0.00001)

    variables = conv_net.trainable_variables + fc_net.trainable_variables

    for epoch in range(50):
        for step,(x,y) in enumerate(db_train):
            with tf.GradientTape() as tape:
             
                out = conv_net(x)
             
                out = tf.reshape(out,[-1,512])
                
                logits = fc_net(out)

                y_hot = tf.one_hot(y,depth=3)
                # 计算loss数值
                loss = tf.losses.categorical_crossentropy(y_hot,logits,from_logits=True)
                loss = tf.reduce_mean(loss)

            grads = tape.gradient(loss,variables)
            optimizer.apply_gradients(zip(grads,variables))

            if step % 20 ==0:
                print(epoch, step, "loss ", float(loss))

        total_num = 0
        totsl_correct = 0
        for x,y in db_test:
            x = tf.expand_dims(x,axis=0)
            # print(x.shape)
            out = conv_net(x)
            out = tf.reshape(out,[-1,512])
            logits = fc_net(out)
            prob = tf.nn.softmax(logits,axis=1)

            pred = tf.argmax(prob,axis=1)
            pred = tf.cast(pred,dtype=tf.int32)

            correct = tf.cast(tf.equal(pred,y),dtype=tf.int32)
            correct = tf.reduce_sum(correct)

            total_num += x.shape[0]
            totsl_correct += int(correct)
        acc = totsl_correct/total_num
        print(epoch, acc)
        conv_net.save('weights/conv.h5')
        fc_net.save('weights/fc.h5')

 モデルテスト

import tensorflow as tf
from tensorflow.keras import layers,optimizers,datasets,Sequential
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

os.environ['CUDA_VISIBLE_DEVICES'] = '/gpu:0'
tf.random.set_seed(2345)

from PIL import Image
import numpy as np

#-------------------------------读取待预测图片------------------------------------
ima1 = os.listdir('E:/prediction/')
def read_image1(filename):
    img = Image.open('E:/prediction/'+filename).convert('RGB')
    return np.array(img)

x_train = []
for i in ima1:
    x_train.append(read_image1(i))
x_train = np.array(x_train)

#-------------------------------加载神经网络模型-----------------------------------
conv_net = tf.keras.models.load_model('weights/conv.h5')
fc_net = tf.keras.models.load_model('weights/fc.h5')

#-----------------------------------图片识别--------------------------------------
out = conv_net(x_train)
out = tf.reshape(out,[-1,512])
logits = fc_net(out)

prob = tf.nn.softmax(logits,axis=1)
prob = np.array(prob)

pred = tf.argmax(prob,axis=1)
pred = np.array(pred)
print(pred)

  モデルT-SNEダイナミックディスプレイ

1.画像を生成します

        SNEは確率的隣接埋め込みであり、基本的な考え方は、高次元空間内の同様のデータポイントが、同様の距離を持つ低次元空間にマッピングされることです。SNEは、この距離関係を条件付き確率に変換して、類似性を表します。 

        このホワイトペーパーでは、完全に接続されたレイヤーの最後の出力レイヤーの動的な視覚化に焦点を当てます。最初のステップは、エポックごとに図を生成し、指定されたフォルダーに保存することです。最後に、gifツールを使用して動的表示画像を作成します。それを行うには多くの方法があり、効果を達成できるのは良いことです。

原則リファレンス:https ://blog.csdn.net/SweetSeven_/article/details/108010565

    #轴承数据训练
    for epoch in range(20):
        # 定义列表,data_xx存放训练数据,data_y存放训练数据标签
        data_xx = []
        data_y = []

        for step,(x,y) in enumerate(db_train):
            with tf.GradientTape() as tape:
                #计算一个batchsize的卷积神经网络输出
                out = conv_net(x)
                #卷积神经网络输出数据进行reshape[-1,512]
                out = tf.reshape(out,[-1,512])
                #reshape的数据输入到全连接层
                logits = fc_net(out)
                #最终输出数据进行one_hot转换
                y_hot = tf.one_hot(y,depth=6)
                # 计算loss数值
                loss = tf.losses.categorical_crossentropy(y_hot,logits,from_logits=True)
                loss = tf.reduce_mean(loss)

            grads = tape.gradient(loss,variables)
            optimizer.apply_gradients(zip(grads,variables))

            #每隔20个bachsize,输出一次loss数值
            if step % 20 ==0:
                print(epoch, step, "loss ", float(loss))

            if epoch >= 2:
                # 列出对应元素的标签值
                data_y.extend(y)
                # 获取所有训练后的样本数据
                for i in range(len(logits)):
                    # 得到训练的样本
                    data_xx.append(logits[i])
                #每次epoch将data_y和data_xx列表转换为numpy数据


        if epoch >= 2:
            data_y = np.array(data_y)
            data_xx = np.array(data_xx)
            # print("data_xx", data_xx.shape)
            # print("data_y", data_y.shape)
            # print("data_y", data_y)
            #进行tsne降维
            tsne = manifold.TSNE(n_components=2, init='pca')
            X_tsne = tsne.fit_transform(data_xx)

            #将降维数据进行可视化显示
            x_min, x_max = X_tsne.min(0), X_tsne.max(0)
            X_norm = (X_tsne - x_min) / (x_max - x_min)  # 归一化

            for i in range(len(X_norm)):
                # plt.text(X_norm[i, 0], X_norm[i, 1], str(y[i]), color=plt.cm.Set1(y[i]),
                if data_y[i] == 0:
                    color = 'r'
                if data_y[i] == 1:
                    color = 'g'
                if data_y[i] == 2:
                    color = 'b'
                if data_y[i] == 3:
                    color = 'c'
                if data_y[i] == 4:
                    color = 'm'
                if data_y[i] == 5:
                    color = 'k'
                #          fontdict={'weight': 'bold', 'size': 9})
                plt.scatter(X_norm[i][0], X_norm[i][1], c=color, cmap=plt.cm.Spectral)

            plt.xticks([])
            plt.yticks([])
            plt.savefig("E:/tsne_figure/" + str(epoch) + ".png")
            plt.close('all')

2.gifを生成します

# 初始化图片地址文件夹途径

image_path = 'E:/tsne_figure/'

# 获取文件列表

files = os.listdir(image_path)

# 定义第一个文件的全局路径

file_first_path = os.path.join(image_path, files[0])

# 获取Image对象

img = Image.open(file_first_path)

# 初始化文件对象数组

images = []

for image in files[:]:
    # 获取当前图片全量路径

    img_path = os.path.join(image_path, image)

    # 将当前图片使用Image对象打开、然后加入到images数组

    images.append(Image.open(img_path))

# 保存并生成gif动图

img.save('beauty.gif', save_all=True, append_images=images, loop=0, duration=200)

3.効果のデモンストレーション

        コンピューターの計算能力は十分ではなく、20エポックが一晩中実行されます。最後に、損失は約0.005で安定しています。これは、基本的に異なるタイプの分離を実現するtsneによって視覚化されます。        

PS:ブログを書くのはこれが初めてですが、多くの欠点があります。ご容赦ください。時間は比較的短く、しばらくするとコードが改善され、すべてのコードとデータが2番目の記事に添付されます。

おすすめ

転載: blog.csdn.net/qq_36865346/article/details/120053869