MK-MMD計量伝達学習に基づく軸受故障診断法に関する研究

概要

       前回の実験は、Case Western Kitchen Universityの方位データセットに基づいており、同じ荷重で6種類の軸受データを使用して故障診断を行いましたが、異なる荷重での軸受故障診断には使用していません。私はこれまでこの転移学習実験を行ったことがありません。主な理由は、転移学習が実施されていることを理解しておらず、どこに行けばよいかわからないためです。論文を書いている間、私はたくさんの文献を読み、転移学習について少し理解しています。転移学習には、実際には2つの概念、つまりソースドメインとターゲットドメインが含まれます。ソースドメインはモデルトレーニングに使用されるデータセットとして理解できますが、ターゲットドメインは実際には予測する必要のあるデータセットです。ただし、多くの場合、ソースドメインデータセットとターゲットドメインデータセットの間には、データ分散の程度が異なります。現在の深層学習は、このような高精度を実現できます。実際、デフォルトのデータは同じデータ分布を持っています。したがって、私自身の理解によれば、以前に収集されたリソースと組み合わせて、MK-MMD法を使用して、さまざまな負荷の下でのベアリング故障診断研究を実現します。私は、主に他の人を引き付ける効果を期待して、1つの状況でのみ移行を行ったので、何か問題があればご容赦ください。

データセット

1.データソース

        実験で使用されたデータセットは、Case Western Kitchen Universityのベアリングデータセットのままです(注:私の研究室には実験プラットフォームがないため、実際のベアリングデータセットを取得できません)。実験プラットフォームを図1に示します。

 図1ケースウエスタンリザーブ大学のベアリングデータセット

2.時間周波数画像を生成するための時間周波数変換

        前回の記事に基づいて、負荷0、負荷3の10個の故障振動信号に対して直接データエンハンスメント操作を行い、1次元振動画像を2次元時間周波数画像に変換します。連続ウェーブレット変換。変更の影響を下の図2に示します。

 図20荷重下の軸受の時間-周波数変換画像

図3荷重下の軸受の時間-周波数変換画像3

        実際、時間周波数画像を見ると、負荷1と負荷3での10個のベアリング障害の時間周波数画像に大きな違いがないことがわかります。この記事の後半では、MK-MMDを使用して次のことを確認します。 2つのデータ間の分布の違いは違いはありません。

 転移学習

1.コンセプト

       転移学習の概念については、Wang Jindongによる転移学習の紹介pdfを参照してください。これは、転移学習の概念を非常に明確に説明しています。具体的な紹介はありません。転移学習の基本的な概念を下の図4に示します。これには、ソースドメインとターゲットドメインの2つの概念が含まれます。

図4転移学習の基本概念

2.転移学習の領域適応問題

        転移学習におけるドメイン適応の問題は、ソースドメインデータとターゲットドメインデータ間の分布の違いをどのように解決し、この違いを効果的に減らす方法を使用して、ソースドメインデータとターゲットドメインデータの分布が次のようになるかです。可能な限り一貫性があります。具体的な表現を下の図5に示します。

 図5ドメイン適応の問題

       転移学習のドメイン適応問題に関しては、周辺分布と条件付き分布が関係しているはずです。ソースドメインデータとターゲットドメインデータの違いは、主に周辺分布と条件付き分布にあるためです。したがって、ソースドメインデータとターゲットドメインデータを削減する方法の本質は、周辺分布と条件付き分布を削減する方法です。

2.1周辺分布

        エッジ分布の概念を下の図6に示します。ハイエッジ分布を見ないでください。その本質は、さまざまな数学的方法を使用して、ソースドメインデータの全体的な分散センターとターゲットドメインの全体的なデータ分散センターを整列およびオーバーラップさせ、2つのデータ間の分散を狭めることです。 。周辺分布は、さまざまなドメインのデータの全体的な分布の調整を強調します。

 図6エッジ分布

2.2条件付き分布

       条件付き分布を下の図7に示します。条件付き分布の本質は、数学的な手段を使用して、異なる作業条件下で同じタイプのデータを絞り込み、データの分布の差を減らすことです。条件付き分布は、異なるフィールドの同じカテゴリのデータの整列を強調します。

 図7条件付き分布

        転移学習の条件付き分布と周辺分布の概念を理解している限り、式をロックする必要はありません。インターネット上には、呼び出すことができる既製のコードがたくさんあります。

2.3同時分布の適応

       同時分布の適応を下の図8に示します。和集合の本質は、条件付き分布と周辺分布分布を組み合わせることです。式にはプラス記号が使用されていますが、単純な加算ではありません。これを深く理解する必要はなく、同時分布の概念と原理を理解する必要があります。同時分布アルゴリズムには、TCA、JDA、BDAなどが含まれます。これらのアルゴリズムのコードは、以下のリンクからダウンロードできます。

TCA、JDA、BDAなどの分野の適応アルゴリズムのコードを見つけることができます。

https://github.com/jindongwang/transferlearning

 2.4類似度測定方法

        類似度測定は、2つのデータ分布の類似性を測定する方法です。通常、距離は2つのサンプルデータの分布の差を測定するために使用されます。2つの間の距離が大きいほど、差は大きくなり、距離は小さくなります。 、差が小さい。転移学習のドメイン適応では、より一般的に使用される類似性測度法には、最大平均差MMDとマルチカーネルMMD測度(MK-MMD)が含まれます。この実験では、移行トレーニングにMK-MMDアルゴリズムを使用します。

(1)最大平均差

       MMDは、再生核ヒルベルト空間(RKHS)におけるデータ分布のカーネル埋め込み距離の2乗として定義されます。近年、MMDは、機能のクロスドメイン適応を実行するための最適化目標として、ソースドメインとターゲットドメイン間のMMD距離を最小化するためにドメイン適応で広く使用されています。具体的な計算式は次のとおりです。

MMDの具体的なコードを以下に示します。


import numpy as np
from sklearn import metrics


def mmd_linear(X, Y):
    """MMD using linear kernel (i.e., k(x,y) = <x,y>)
    Note that this is not the original linear MMD, only the reformulated and faster version.
    The original version is:
        def mmd_linear(X, Y):
            XX = np.dot(X, X.T)
            YY = np.dot(Y, Y.T)
            XY = np.dot(X, Y.T)
            return XX.mean() + YY.mean() - 2 * XY.mean()
    Arguments:
        X {[n_sample1, dim]} -- [X matrix]
        Y {[n_sample2, dim]} -- [Y matrix]
    Returns:
        [scalar] -- [MMD value]
    """
    delta = X.mean(0) - Y.mean(0)
    return delta.dot(delta.T)


def mmd_rbf(X, Y, gamma=1.0):
    """MMD using rbf (gaussian) kernel (i.e., k(x,y) = exp(-gamma * ||x-y||^2 / 2))
    Arguments:
        X {[n_sample1, dim]} -- [X matrix]
        Y {[n_sample2, dim]} -- [Y matrix]
    Keyword Arguments:
        gamma {float} -- [kernel parameter] (default: {1.0})
    Returns:
        [scalar] -- [MMD value]
    """
    XX = metrics.pairwise.rbf_kernel(X, X, gamma)
    YY = metrics.pairwise.rbf_kernel(Y, Y, gamma)
    XY = metrics.pairwise.rbf_kernel(X, Y, gamma)
    return XX.mean() + YY.mean() - 2 * XY.mean()


def mmd_poly(X, Y, degree=2, gamma=1, coef0=0):
    """MMD using polynomial kernel (i.e., k(x,y) = (gamma <X, Y> + coef0)^degree)
    Arguments:
        X {[n_sample1, dim]} -- [X matrix]
        Y {[n_sample2, dim]} -- [Y matrix]
    Keyword Arguments:
        degree {int} -- [degree] (default: {2})
        gamma {int} -- [gamma] (default: {1})
        coef0 {int} -- [constant item] (default: {0})
    Returns:
        [scalar] -- [MMD value]
    """
    XX = metrics.pairwise.polynomial_kernel(X, X, degree, gamma, coef0)
    YY = metrics.pairwise.polynomial_kernel(Y, Y, degree, gamma, coef0)
    XY = metrics.pairwise.polynomial_kernel(X, Y, degree, gamma, coef0)
    return XX.mean() + YY.mean() - 2 * XY.mean()


if __name__ == '__main__':
    a = np.arange(1, 10).reshape(3, 3)
    b = [[7, 6, 5], [4, 3, 2], [1, 1, 8], [0, 2, 5]]
    b = np.array(b)
    print(a)
    print(b)
    print(mmd_linear(a, b))  # 6.0
    print(mmd_rbf(a, b))  # 0.5822
    print(mmd_poly(a, b))  # 2436.5

 (2)MK-MMD

       MK-MMDの具体的なコードを以下に示します。


def guassian_kernel(source, target, kernel_mul=2.0, kernel_num=5, fix_sigma=None):
    '''
    多核或单核高斯核矩阵函数,根据输入样本集x和y,计算返回对应的高斯核矩阵
    Params:
     source: (b1,n)的X分布样本数组
     target:(b2,n)的Y分布样本数组
     kernel_mul: 多核MMD,以bandwidth为中心,两边扩展的基数,比如bandwidth/kernel_mul, bandwidth, bandwidth*kernel_mul
     kernel_num: 取不同高斯核的数量
     fix_sigma: 是否固定,如果固定,则为单核MMD
    Return:
      sum(kernel_val): 多个核矩阵之和
    '''
    # 堆叠两组样本,上面是X分布样本,下面是Y分布样本,得到(b1+b2,n)组总样本
    n_samples = int(source.shape[0]) + int(target.shape[0])
    total = np.concatenate((source, target), axis=0)
    # 对总样本变换格式为(1,b1+b2,n),然后将后两维度数据复制到新拓展的维度上(b1+b2,b1+b2,n),相当于按行复制
    total0 = np.expand_dims(total, axis=0)
    total0 = np.broadcast_to(total0, [int(total.shape[0]), int(total.shape[0]), int(total.shape[1])])
    # 对总样本变换格式为(b1+b2,1,n),然后将后两维度数据复制到新拓展的维度上(b1+b2,b1+b2,n),相当于按复制
    total1 = np.expand_dims(total, axis=1)
    total1 = np.broadcast_to(total1, [int(total.shape[0]), int(total.shape[0]), int(total.shape[1])])
    # total1 - total2 得到的矩阵中坐标(i,j, :)代表total中第i行数据和第j行数据之间的差
    # sum函数,对第三维进行求和,即平方后再求和,获得高斯核指数部分的分子,是L2范数的平方
    L2_distance_square = np.cumsum(np.square(total0 - total1), axis=2)
    # 调整高斯核函数的sigma值
    if fix_sigma:
        bandwidth = fix_sigma
    else:
        bandwidth = np.sum(L2_distance_square) / (n_samples ** 2 - n_samples)
    # 多核MMD
    # 以fix_sigma为中值,以kernel_mul为倍数取kernel_num个bandwidth值(比如fix_sigma为1时,得到[0.25,0.5,1,2,4]
    bandwidth /= kernel_mul ** (kernel_num // 2)
    bandwidth_list = [bandwidth * (kernel_mul ** i) for i in range(kernel_num)]
    # print(bandwidth_list)
    # 高斯核函数的数学表达式
    kernel_val = [np.exp(-L2_distance_square / bandwidth_temp) for bandwidth_temp in bandwidth_list]
    # 得到最终的核矩阵
    return sum(kernel_val)  # 多核合并


def MK_MMD(source, target, kernel_mul=2.0, kernel_num=5, fix_sigma=None):
    '''
    计算源域数据和目标域数据的MMD距离
    Params:
     source: (b1,n)的X分布样本数组
     target:(b2,n)的Y分布样本数组
     kernel_mul: 多核MMD,以bandwidth为中心,两边扩展的基数,比如bandwidth/kernel_mul, bandwidth, bandwidth*kernel_mul
     kernel_num: 取不同高斯核的数量
     fix_sigma: 是否固定,如果固定,则为单核MMD
 Return:
     loss: MK-MMD loss
    '''
    batch_size = int(source.shape[0])  # 一般默认为源域和目标域的batchsize相同
    kernels = guassian_kernel(source, target,kernel_mul=kernel_mul, kernel_num=kernel_num, fix_sigma=fix_sigma)
    # 将核矩阵分成4部分
    loss = 0
    for i in range(batch_size):
        s1, s2 = i, (i + 1) % batch_size
        t1, t2 = s1 + batch_size, s2 + batch_size
        loss += kernels[s1, s2] + kernels[t1, t2]
        loss -= kernels[s1, t2] + kernels[s2, t1]
    # 这里计算出的n_loss是每个维度上的MK-MMD距离,一般还会做均值化处理
    n_loss = loss / float(batch_size)
    return np.mean(n_loss)

        上記の2つの測定方法は、基本原理を理解するだけでよく、数式の関係を理解する必要はありません。それでも同じ文です。既製のコードがあり、直接使用できます。

3.学習分類の転送

       転移学習の分類を理解し、各タイプの一般原理を理解するだけで十分です。一般に、機能ベースの転移学習方法は、主に論文で使用されます。実際、この方法は、ベアリングの故障診断研究において常にホットな問題となっています。そのため、この章では主に機能ベースの転移学習法を紹介します。一般的に使用される転移学習方法を下の図8に示します。

 図8転移学習の分類

3.1機能の移行

        機能転送とは、ソースドメインの教師ありトレーニングを通じてターゲットドメインの分類パフォーマンスを向上させるという目的を達成するために、ソースドメインの機能とターゲットドメインの機能の両方を表すことができる機能スペースを見つけることです。分類タスクでは、ソースドメインデータとラベル付けされたトレーニングデータが多数あり、関連フィールドのさまざまなシナリオのデータであるラベル付きまたはラベルなしのターゲットドメインデータが少量あると想定されています。機能転送学習は、ラベル付きソースドメインデータとラベルなしターゲットドメインデータをトレーニングすることで、ソースドメインとターゲットドメイン間のデータ分散の違いを減らし、ソースドメインの分類精度を向上させ、ネットワークパラメータを最適化してより良い結果を得ることができます。 。ターゲットドメインの分類。本論文は主に特徴伝達学習に基づく軸受のクロスドメイン故障診断を完了する。 

3.2転移学習の微調整

       特徴の転送に加えて、転送学習の微調整と呼ばれる一般的に使用される転送学習方法もあります。転送学習の微調整とは、パラメータの転送です。これは、ソースドメインでトレーニングされたモデルパラメータをターゲットドメインに転送して、トレーニングモデルパラメータの微調整を継続し、ソースドメインからへの知識の転送を実現することを意味します。ターゲットドメイン。また、画像分類では転送学習の微調整が広く利用されており、既存の多数の画像トレーニングを通じてネットワークの初期化パラメータを取得し、初期化されたネットワークをターゲットドメインに転送してターゲットを使用するというプロセスが具体化されています。ネットワークの重みパラメータをさらに微調整および最適化して、最終的にターゲットドメインイメージの分類を完了するためのトレーニング用のドメインイメージ。 

王金東の転校学習マニュアルのダウンロードリンク:

リンク:https 
://pan.baidu.com/s/1f7VpJI7LaSXDP5EHV5CPRA抽出コード:jxu3 
--BaiduNetdiskスーパーメンバーV5からの共有

 実験分析

       上記の知識に基づいて、次のステップは実験的分析を実行することです。具体的な実験は以下のブログを参考にしています。80元近くで購入したブログは、購入してから後悔し、実用的ではないと感じました。しかし、このため、後で比較的良いブログも見つけました。

購入に80元近くかかるブログは次のとおりです。

Deep Convolutional Transfer Learning Networksを使用したラベルなしデータの分類ネットワークは、別のデータセットからのラベルなしデータを分類します。https://blog.csdn.net/qq_36758914/article/details/107946869     内容は次のとおりです。

 

 

        実際、上記のブログから重要なのは損失関数です。この損失関数は、ソースドメインの分類損失関数、ドメインディスクリミネーターの損失関数、最後の3つの部分で構成されています。ソースドメインとターゲットドメインです。分布の違い。

        これを理解した後、実際、残りはこれら3つの部分の損失関数を計算する方法であり、最後に3つの損失関数は、一般にドメイン弁別子損失関数の2つの部分、ソースドメインとターゲットドメインで線形に結合されます。分布差値係数λ、uは前に追加されます。もう1つのポイントは、ドメイン弁別子損失関数を差し引く必要があるということです。

         損失関数の部分が明確でない場合は、次の推奨ブログを参照してください。

https://blog.csdn.net/Goodlick/article/details/121095838 icon-default.png?t = M276https://blog.csdn.net/Goodlick/article/details/121095838

別の素晴らしいブログ

        上記の内容を理解した上で、次のように良いと思うブログを提供します。

移行学習-ドメイン分類損失関数-Pythonコードの       このブログ実装は、上記のブログのテストケースとして理解できます。重要なのは、ドメイン識別子の損失関数コードです。ベアリング移行の学習を行うには、この記事は実際には良いスタートであり、勉強する価値があります。

次のように、ドメイン弁別子損失関数の記事       の主要な内容と、それがニューラルネットワークにどのように組み込まれているかを簡単に引用します。

ドメイン弁別器損失関数コード:

import torch
import torch.nn as nn
from torch.autograd import Function
import torch.nn.functional as F
import numpy as np

class LambdaSheduler(nn.Module):
    def __init__(self, gamma=1.0, max_iter=1000, **kwargs):
        super(LambdaSheduler, self).__init__()
        self.gamma = gamma
        self.max_iter = max_iter
        self.curr_iter = 0

    def lamb(self):
        p = self.curr_iter / self.max_iter
        lamb = 2. / (1. + np.exp(-self.gamma * p)) - 1
        return lamb
    
    def step(self):
        self.curr_iter = min(self.curr_iter + 1, self.max_iter)

class AdversarialLoss(nn.Module):
    '''
    Acknowledgement: The adversarial loss implementation is inspired by http://transfer.thuml.ai/
    '''
    def __init__(self, gamma=1.0, max_iter=1000, use_lambda_scheduler=True, **kwargs):
        super(AdversarialLoss, self).__init__()
        self.domain_classifier = Discriminator()
        self.use_lambda_scheduler = use_lambda_scheduler
        if self.use_lambda_scheduler:
            self.lambda_scheduler = LambdaSheduler(gamma, max_iter)
        
    def forward(self, source, target):
        lamb = 1.0
        if self.use_lambda_scheduler:
            lamb = self.lambda_scheduler.lamb()
            self.lambda_scheduler.step()
        source_loss = self.get_adversarial_result(source, True, lamb)
        target_loss = self.get_adversarial_result(target, False, lamb)
        adv_loss = 0.5 * (source_loss + target_loss)
        return adv_loss
    
    def get_adversarial_result(self, x, source=True, lamb=1.0):
        x = ReverseLayerF.apply(x, lamb)
        domain_pred = self.domain_classifier(x)
        device = domain_pred.device
        if source:
            domain_label = torch.ones(len(x), 1).long()
        else:
            domain_label = torch.zeros(len(x), 1).long()
        loss_fn = nn.BCELoss()
        loss_adv = loss_fn(domain_pred, domain_label.float().to(device))
        return loss_adv

class ReverseLayerF(Function):
    @staticmethod
    def forward(ctx, x, alpha):
        ctx.alpha = alpha
        return x.view_as(x)
    
    @staticmethod
    def backward(ctx, grad_output):
        output = grad_output.neg() * ctx.alpha
        return output, None

class Discriminator(nn.Module):
    def __init__(self, input_dim=256, hidden_dim=256): #256是根据你的输入维度来修改的
        super(Discriminator, self).__init__()
        self.input_dim = input_dim
        self.hidden_dim = hidden_dim
        layers = [
            nn.Linear(input_dim, hidden_dim),
            nn.BatchNorm1d(hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.BatchNorm1d(hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, 1),
            nn.Sigmoid()
        ]
        self.layers = torch.nn.Sequential(*layers)
    
    def forward(self, x):
        return self.layers(x)

      パーツの1つを変更する必要があります:

        他の畳み込みニューラルネットワークでトレーニングする場合は、ネットワークの最終出力の次元がいくつあるかを確認し、それに応じて上記の256をネットワークの出力の次元に変更する必要があります。たとえば、VGG16モデルを使用してトレーニングすると、モデルの入力イメージは(16、512、512、3)になります。10の障害カテゴリによると、モデル出力の結果は(16、10)、つまりつまり、出力の次元は10です。ドメイン弁別子損失関数の256を10に変更する必要があります。訓練中、私はまた、誰もが迂回するのを避けるために雷を踏んだ。

      原作者はこの方法を使用して簡単なテストを実施しました。結果は次のとおりです。

モデルトレーニングのプロセス:

        上記のモデルの考え方によると、モデルの全体的なトレーニングは次のとおりです。

        上記のフローチャートには定義域弁別器の損失関数部分が描かれておらず、時間が厳しいときに描くのを忘れてしまったので、次の記事は書かれていません。実際の実験で追加されます。トレーニングセットとテストセットを2つの部分に分割します。負荷が0、負荷が3のデータセットには、合計1000枚の画像があり、4:1の比率で除算され、トレーニング用の各データセットの数は800、テスト用のデータセットの数は200です。

研修結果は以下のとおりです。

       tsne次元削減アルゴリズムを使用して、MK-MMDを使用する場合と使用しない場合の違いを比較します。

 

 

おすすめ

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