[深度應用]·DC競賽軸承故障檢測開源Baseline(基於Keras 1D卷積 val_acc:0.99780)


[深度應用]·DC競賽軸承故障檢測開源Baseline(基於Keras1D卷積 val_acc:0.99780)

個人網站--> http://www.yansongsong.cn/

Github項目地址--> https://github.com/xiaosongshine/bearing_detection_by_conv1d

 

大賽簡介

軸承是在機械設備中具有廣泛應用的關鍵部件之一。由於過載,疲勞,磨損,腐蝕等原因,軸承在機器操作過程中容易損壞。事實上,超過50%的旋轉機器故障與軸承故障有關。實際上,滾動軸承故障可能導致設備劇烈搖晃,設備停機,停止生產,甚至造成人員傷亡。一般來說,早期的軸承弱故障是復雜的,難以檢測。因此,軸承狀態的監測和分析非常重要,它可以發現軸承的早期弱故障,防止故障造成損失。 最近,軸承的故障檢測和診斷一直備受關注。在所有類型的軸承故障診斷方法中,振動信號分析是最主要和有用的工具之一。 在這次比賽中,我們提供一個真實的軸承振動信號數據集,選手需要使用機器學習技術判斷軸承的工作狀態。

競賽網站

 

數據介紹

軸承有3種故障:外圈故障,內圈故障,滾珠故障,外加正常的工作狀態。如表1所示,結合軸承的3種直徑(直徑1,直徑2,直徑3),軸承的工作狀態有10類:

參賽選手需要設計模型根據軸承運行中的振動信號對軸承的工作狀態進行分類。

 

1.train.csv,訓練集數據,1到6000為按時間序列連續采樣的振動信號數值,每行數據是一個樣本,共792條數據,第一列id字段為樣本編號,最后一列label字段為標簽數據,即軸承的工作狀態,用數字0到9表示。

2.test_data.csv,測試集數據,共528條數據,除無label字段外,其他字段同訓練集。 總的來說,每行數據除去id和label后是軸承一段時間的振動信號數據,選手需要用這些振動信號去判定軸承的工作狀態label。

注意:同一列的數據不一定是同一個時間點的采樣數據,即不要把每一列當作一個特征

 

點擊下載數據

 

 *數據下載具體操作:

ps:注冊登陸后方可下載

 


評分標准

評分算法
binary-classification

采用各個品類F1指標的算術平均值,它是Precision 和 Recall 的調和平均數。

其中,Pi是表示第i個種類對應的Precision, Ri是表示第i個種類對應Recall。

 

賽題分析

簡單分析一下,這個比賽大家可以簡單的理解為一個10分類的問題,輸入的形狀為(-1,6000),網絡輸出的結果為(-1,10)(此處采用onehot形式)

賽題就是一個十分類預測問題,解題思路應該包括以下內容

  1. 數據讀取與處理
  2. 網絡模型搭建
  3. 模型的訓練
  4. 模型應用與提交預測結果

 

實戰應用

經過對賽題的分析,我們把任務分成四個小任務,首先第一步是:

1.數據讀取與處理

數據是CSV文件,1到6000為按時間序列連續采樣的振動信號數值,每行數據是一個樣本,共792條數據,第一列id字段為樣本編號,最后一列label字段為標簽數據,即軸承的工作狀態,用數字0到9表示。

數據處理函數定義:


import keras from scipy.io import loadmat import matplotlib.pyplot as plt import glob import numpy as np import pandas as pd import math import os from keras.layers import * from keras.models import * from keras.optimizers import * import numpy as np MANIFEST_DIR = "Bear_data/train.csv" Batch_size = 20 Long = 792 Lens = 640 #把標簽轉成oneHot def convert2oneHot(index,Lens): hot = np.zeros((Lens,)) hot[int(index)] = 1 return(hot) def xs_gen(path=MANIFEST_DIR,batch_size = Batch_size,train=True,Lens=Lens): img_list = pd.read_csv(path) if train: img_list = np.array(img_list)[:Lens] print("Found %s train items."%len(img_list)) print("list 1 is",img_list[0,-1]) steps = math.ceil(len(img_list) / batch_size) # 確定每輪有多少個batch else: img_list = np.array(img_list)[Lens:] print("Found %s test items."%len(img_list)) print("list 1 is",img_list[0,-1]) steps = math.ceil(len(img_list) / batch_size) # 確定每輪有多少個batch while True: for i in range(steps): batch_list = img_list[i * batch_size : i * batch_size + batch_size] np.random.shuffle(batch_list) batch_x = np.array([file for file in batch_list[:,1:-1]]) batch_y = np.array([convert2oneHot(label,10) for label in batch_list[:,-1]]) yield batch_x, batch_y TEST_MANIFEST_DIR = "Bear_data/test_data.csv" def ts_gen(path=TEST_MANIFEST_DIR,batch_size = Batch_size): img_list = pd.read_csv(path) img_list = np.array(img_list)[:Lens] print("Found %s train items."%len(img_list)) print("list 1 is",img_list[0,-1]) steps = math.ceil(len(img_list) / batch_size) # 確定每輪有多少個batch while True: for i in range(steps): batch_list = img_list[i * batch_size : i * batch_size + batch_size] #np.random.shuffle(batch_list) batch_x = np.array([file for file in batch_list[:,1:]]) #batch_y = np.array([convert2oneHot(label,10) for label in batch_list[:,-1]]) yield batch_x

讀取一條數據進行顯示

if __name__ == "__main__": if Show_one == True: show_iter = xs_gen() for x,y in show_iter: x1 = x[0] y1 = y[0] break print(y) print(x1.shape) plt.plot(x1) plt.show()

 


我們由上述信息可以看出每種導聯都是由6000個點組成的列表,大家可以理解為mnist展開為一維后的形狀

 

標簽處理方式

def create_csv(TXT_DIR=TXT_DIR): lists = pd.read_csv(TXT_DIR,sep=r"\t",header=None) lists = lists.sample(frac=1) lists.to_csv(MANIFEST_DIR,index=None) print("Finish save csv")

 

數據讀取的方式我采用的是生成器的方式,這樣可以按batch讀取,加快訓練速度,大家也可以采用一下全部讀取,看個人的習慣了。關於生成器介紹,大家可以參考我的這篇博文

[開發技巧]·深度學習使用生成器加速數據讀取與訓練簡明教程(TensorFlow,pytorch,keras)

 

2.網絡模型搭建

數據我們處理好了,后面就是模型的搭建了,我使用keras搭建的,操作簡單便捷,tf,pytorch,sklearn大家可以按照自己喜好來。

網絡模型可以選擇CNN,RNN,Attention結構,或者多模型的融合,拋磚引玉,此Baseline采用的一維CNN方式,一維CNN學習地址

模型搭建

TIME_PERIODS = 6000 def build_model(input_shape=(TIME_PERIODS,),num_classes=10): model = Sequential() model.add(Reshape((TIME_PERIODS, 1), input_shape=input_shape)) model.add(Conv1D(16, 8,strides=2, activation='relu',input_shape=(TIME_PERIODS,1))) model.add(Conv1D(16, 8,strides=2, activation='relu',padding="same")) model.add(MaxPooling1D(2)) model.add(Conv1D(64, 4,strides=2, activation='relu',padding="same")) model.add(Conv1D(64, 4,strides=2, activation='relu',padding="same")) model.add(MaxPooling1D(2)) model.add(Conv1D(256, 4,strides=2, activation='relu',padding="same")) model.add(Conv1D(256, 4,strides=2, activation='relu',padding="same")) model.add(MaxPooling1D(2)) model.add(Conv1D(512, 2,strides=1, activation='relu',padding="same")) model.add(Conv1D(512, 2,strides=1, activation='relu',padding="same")) model.add(MaxPooling1D(2)) model.add(GlobalAveragePooling1D()) model.add(Dropout(0.3)) model.add(Dense(num_classes, activation='softmax')) return(model) 

用model.summary()輸出的網絡模型為

_________________________________________________________________
Layer (type) Output Shape Param # ================================================================= reshape_1 (Reshape) (None, 6000, 1) 0 _________________________________________________________________ conv1d_1 (Conv1D) (None, 2997, 16) 144 _________________________________________________________________ conv1d_2 (Conv1D) (None, 1499, 16) 2064 _________________________________________________________________ max_pooling1d_1 (MaxPooling1 (None, 749, 16) 0 _________________________________________________________________ conv1d_3 (Conv1D) (None, 375, 64) 4160 _________________________________________________________________ conv1d_4 (Conv1D) (None, 188, 64) 16448 _________________________________________________________________ max_pooling1d_2 (MaxPooling1 (None, 94, 64) 0 _________________________________________________________________ conv1d_5 (Conv1D) (None, 47, 256) 65792 _________________________________________________________________ conv1d_6 (Conv1D) (None, 24, 256) 262400 _________________________________________________________________ max_pooling1d_3 (MaxPooling1 (None, 12, 256) 0 _________________________________________________________________ conv1d_7 (Conv1D) (None, 12, 512) 262656 _________________________________________________________________ conv1d_8 (Conv1D) (None, 12, 512) 524800 _________________________________________________________________ max_pooling1d_4 (MaxPooling1 (None, 6, 512) 0 _________________________________________________________________ global_average_pooling1d_1 ( (None, 512) 0 _________________________________________________________________ dropout_1 (Dropout) (None, 512) 0 _________________________________________________________________ dense_1 (Dense) (None, 10) 5130 ================================================================= Total params: 1,143,594 Trainable params: 1,143,594 Non-trainable params: 0 _________________________________________________________________ None

訓練參數比較少,大家可以根據自己想法更改。

3.網絡模型訓練

模型訓練

Show_one = True Train = True if __name__ == "__main__": if Show_one == True: show_iter = xs_gen() for x,y in show_iter: x1 = x[0] y1 = y[0] break print(y) print(x1.shape) plt.plot(x1) plt.show() if Train == True: train_iter = xs_gen() val_iter = xs_gen(train=False) ckpt = keras.callbacks.ModelCheckpoint( filepath='best_model.{epoch:02d}-{val_loss:.4f}.h5', monitor='val_loss', save_best_only=True,verbose=1) model = build_model() opt = Adam(0.0002) model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy']) print(model.summary()) model.fit_generator( generator=train_iter, steps_per_epoch=Lens//Batch_size, epochs=50, initial_epoch=0, validation_data = val_iter, nb_val_samples = (Long - Lens)//Batch_size, callbacks=[ckpt], ) model.save("finishModel.h5") else: test_iter = ts_gen() model = load_model("best_model.49-0.00.h5") pres = model.predict_generator(generator=test_iter,steps=math.ceil(528/Batch_size),verbose=1) print(pres.shape) ohpres = np.argmax(pres,axis=1) print(ohpres.shape) #img_list = pd.read_csv(TEST_MANIFEST_DIR) df = pd.DataFrame() df["id"] = np.arange(1,len(ohpres)+1) df["label"] = ohpres df.to_csv("submmit.csv",index=None) 

訓練過程輸出(最優結果:32/32 [==============================] - 1s 33ms/step - loss: 0.0098 - acc: 0.9969 - val_loss: 0.0172 - val_acc: 0.9924)

Epoch 46/50
32/32 [==============================] - 1s 33ms/step - loss: 0.0638 - acc: 0.9766 - val_loss: 0.2460 - val_acc: 0.9242

Epoch 00046: val_loss did not improve from 0.00354
Epoch 47/50
32/32 [==============================] - 1s 33ms/step - loss: 0.0426 - acc: 0.9859 - val_loss: 0.0641 - val_acc: 0.9848

Epoch 00047: val_loss did not improve from 0.00354
Epoch 48/50
32/32 [==============================] - 1s 33ms/step - loss: 0.0148 - acc: 0.9969 - val_loss: 0.0072 - val_acc: 1.0000

Epoch 00048: val_loss did not improve from 0.00354
Epoch 49/50
32/32 [==============================] - 1s 34ms/step - loss: 0.0061 - acc: 0.9984 - val_loss: 0.0404 - val_acc: 0.9857

Epoch 00049: val_loss did not improve from 0.00354
Epoch 50/50
32/32 [==============================] - 1s 33ms/step - loss: 0.0098 - acc: 0.9969 - val_loss: 0.0172 - val_acc: 0.9924

 

最后是進行預測與提交,代碼在上面大家可以自己運行一下。

預測結果

排行榜:第24名


 

 

 

展望

此Baseline采用最簡單的一維卷積達到了99.8%測試准確率,這體現了一維卷積在一維時序序列的應用效果。

hope this helps

個人網站--> http://www.yansongsong.cn/

Github項目地址--> https://github.com/xiaosongshine/bearing_detection_by_conv1d

歡迎Fork+Star,覺得有用的話,麻煩小小鼓勵一下 ><


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM