1. 程式人生 > 其它 >手把手教你:基於深度學習的滾動軸承故障診斷

手把手教你:基於深度學習的滾動軸承故障診斷

系列文章

手把手教你:玩轉影象分類和目標檢測系統

手把手教你:影象識別的垃圾分類系統

手把手教你:基於粒子群優化演算法(PSO)優化卷積神經網路(CNN)的文字分類


一、專案簡介

本文主要介紹如何使用python搭建:一個基於深度學習的滾動軸承故障診斷系統

專案中涉及使用了多種方法對比檢測結果,包括:

  • 傳統機器學習方法:隨機森林
  • 深度學習方法:CNN
  • 增加殘差模組後的深度學習方法:CNN+ResBlock

如各位童鞋需要更換訓練資料,完全可以根據原始碼將影象和標註檔案更換即可直接執行。

博主也參考過網上故障檢測的相關文章,但大多是理論大於方法。很多同學肯定對原理不需要過多瞭解,只需要搭建出一個基於深度學習的軸承故障預測系統即可。

也正是因為我發現網上大多的帖子只是針對原理進行介紹,功能實現的相對很少。

如果您有以上想法,那就找對地方了!


不多廢話,直接進入正題!

二、資料介紹

本次專案的資料是使用的凱斯西儲大學(Case Western Reserve University)軸承資料中心的開源資料集。

資料檔案採用Matlab格式。每個檔案都包含風扇和驅動端振動資料以及電機轉速。對於所有檔案,變數名稱中的以下項表示:

  • DE - 驅動端加速計資料
  • FE - 風扇端加速計資料
  • BA - 基礎加速計資料
  • time - 時間序列資料
  • RPM- 測試期間的轉速

2.1 故障型別圖示

2.2 資料圖示

2.3 檢視單個數據檔案情況

2.4 資料分佈情況

博主對:

  1. 正常
  2. 內圈故障
  3. 外圈故障
  4. 滾動體故障

四種不同情況下軸承的資料分佈進行了視覺化展示,由於圖示較多,這裡只展示內圈故障的一個檔案的資料分佈情況,其他情況感興趣的同學可以下載完整程式碼執行看看。

三、資料預處理

通過視覺化觀察發現數據波長週期基本上為100-200左右,博主這邊使用1000作為取樣長度,對所有軸承資料進行取樣,並構建label。我們這次需要學習並預測的是輸入的軸承資料是為:正常、內圈故障、外圈故障、滾動體故障。中哪一類,因此是一個4分類的任務。處理後資料分佈如下:

  1. 正常樣本:1696個
  2. 內圈故障樣本:1455個
  3. 滾動體故障樣本:1457個
  4. 外圈故障樣本: 1457個

然後對資料進行取樣,保證每類資料1400個。

data_train = np.asarray(data_normal[:1400] + data_inner[:1400] + data_ball[:1400] + data_outer[:1400],dtype = 'float64')
label = np.asarray(label_normal[:1400] + label_inner[:1400] + label_ball[:1400] + label_outer[:1400],dtype = 'int64')

print("處理後樣本shape:",data_train.shape)
print("處理後資料類別分佈:",Counter(label))

# 儲存資料
np.save("train_data/train_data.npy",data_train)
np.save("train_data/label.npy",label)
print("資料儲存成功,位置:/train_data/")

四、模型訓練及評估

4.1 載入資料

def load_data():
    # 讀取資料
    x = np.load('train_data/train_data.npy')
    y = np.load('train_data/label.npy')
    num = len(Counter(y))
    print("類別數量為:", num)
    return x, y, num
    
# 讀取資料
data, label, label_count = load_data()
# 生成訓練集測試集,70%用作訓練,30%用作測試
train_data, train_label, val_data, val_label = create_train_data(data, label, 0.7)
print("*"*10)
print("訓練集數量:",len(train_label))
print("測試集數量:",len(val_label))

4.2 隨機森林

# 模型引數設定
rfc = RandomForestClassifier(n_estimators = 50,min_samples_split = 5,min_samples_leaf = 4,max_depth = 5)

# 模型準確率和損失值
acc_list = []
loss_list = []
train_acc_list = []
print("開始訓練")
for i in range(1,epoch +1):

    # 模型訓練
    rfc.fit(m_train,train_label)

    # # 訓練集
    # y_train = rfc.predict(m_train)

    # 測試集
    y_pred = np.asarray(rfc.predict(m_val),dtype = 'int64')

    # 計算準確率
    acc = round(accuracy_score(val_label, y_pred),3)
    
    # 訓練集
    y_pred = np.asarray(rfc.predict(m_train),dtype = 'int64')
    # 計算準確率
    train_acc = round(accuracy_score(train_label, y_pred),3)
    
    # print('測試集準確率:', round(accuracy_score(val_label, y_pred),3))
    acc_list.append(acc)
    train_acc_list.append(train_acc)
    
    # 計算損失值
    # 使用one-hot編碼計算損失值
    noe_hot = OneHotEncoder(sparse = False)

    y_pred_o = noe_hot.fit_transform(y_pred.reshape(1, -1))
    val_label_o = noe_hot.fit_transform(val_label.reshape(1, -1))
#     loss = round(log_loss(val_label_o,y_pred_o),3)
    # print("loss:",round(log_loss(val_label,y_pred),3))
#     loss_list.append(loss)
    print("完成第",i,"輪訓練,測試集準確率:",acc)

4.2.1 模型訓練

4.2.2 模型測試

4.3 CNN

構建一個CNN網路,結構如下:

4.3.1 模型訓練

4.3.2 模型測試


可以看到,使用原始cnn模型訓練後準確率只有83。類標2即“內圈故障”的召回率較低,無法準確有效識別。

4.4 CNN+ResBlock

模型構建:

import n_model as md
import tensorflow as tf
# 模型引數
model_param = {
    "a_shape": 1000,
    "b_shape": 2,
    "label_count": 4,
    "num_b":5
}

data_shape=(model_param['a_shape'],model_param['b_shape'])
# 模型例項化
model = md.CNN_ResNet_model(model_param['label_count'] , model_param['num_b'] , data_shape=data_shape)
# 使用學習率進行訓練
res_model = model.model_create(learning_rate = 1e-4)
# 模型網路結構
print("例項化模型成功,網路結構如下:")
print(res_model.summary())
# 設定模型log輸出地址
log_dir = os.path.join("logs/ResNet")
if not os.path.exists(log_dir):
    os.mkdir(log_dir)

4.4.1 模型訓練

4.4.2 模型測試


可以看到,增加了殘差模組的CNN網路已經能準確對不同故障型別進行分類,準確率和召回率均在95分以上。

五、完整程式碼地址

由於專案程式碼量和資料集較大,感興趣的同學可以下載完整程式碼,使用過程中如遇到任何問題可以在評論區評論或者私信我,我都會一一解答。

完整程式碼下載:
【程式碼分享】手把手教你:基於深度學習的滾動軸承故障診斷