目錄
前言
1?數據集制作與加載
1.1 導入數據
第一步,導入十分類數據
第二步,讀取MAT文件驅動端數據
第三步,制作數據集
第四步,制作訓練集和標簽
1.2 數據加載,訓練數據、測試數據分組,數據分batch
2 Transformer分類模型和超參數選取
2.1 定義Transformer分類模型,采用Transformer架構中的編碼器:
2.2 定義模型參數
2.3 模型結構
3 Transformer模型訓練與評估
3.1?模型訓練
3.2 模型評估
往期精彩內容:
Python-凱斯西儲大學(CWRU)軸承數據解讀與分類處理
Python軸承故障診斷 (一)短時傅里葉變換STFT
Python軸承故障診斷 (二)連續小波變換CWT
Python軸承故障診斷 (三)經驗模態分解EMD
Python軸承故障診斷 (四)基于EMD-CNN的故障分類
Python軸承故障診斷 (五)基于EMD-LSTM的故障分類
Pytorch-LSTM軸承故障一維信號分類(一)
Pytorch-CNN軸承故障一維信號分類(二)
前言
本文基于凱斯西儲大學(CWRU)軸承數據,先經過數據預處理進行數據集的制作和加載,最后通過Pytorch實現Transformer模型對故障數據的分類,并介紹Transformer模型的超參數。凱斯西儲大學軸承數據的詳細介紹可以參考下文:
Python-凱斯西儲大學(CWRU)軸承數據解讀與分類處理
1?數據集制作與加載
1.1 導入數據
參考之前的文章,進行故障10分類的預處理,凱斯西儲大學軸承數據10分類數據集:
第一步,導入十分類數據
import numpy as np
import pandas as pd
from scipy.io import loadmatfile_names = ['0_0.mat','7_1.mat','7_2.mat','7_3.mat','14_1.mat','14_2.mat','14_3.mat','21_1.mat','21_2.mat','21_3.mat']for file in file_names:# 讀取MAT文件data = loadmat(f'matfiles\\{file}')print(list(data.keys()))
第二步,讀取MAT文件驅動端數據
# 采用驅動端數據
data_columns = ['X097_DE_time', 'X105_DE_time', 'X118_DE_time', 'X130_DE_time', 'X169_DE_time','X185_DE_time','X197_DE_time','X209_DE_time','X222_DE_time','X234_DE_time']
columns_name = ['de_normal','de_7_inner','de_7_ball','de_7_outer','de_14_inner','de_14_ball','de_14_outer','de_21_inner','de_21_ball','de_21_outer']
data_12k_10c = pd.DataFrame()
for index in range(10):# 讀取MAT文件data = loadmat(f'matfiles\\{file_names[index]}')dataList = data[data_columns[index]].reshape(-1)data_12k_10c[columns_name[index]] = dataList[:119808] # 121048 min: 121265
print(data_12k_10c.shape)
data_12k_10c
第三步,制作數據集
train_set、val_set、test_set 均為按照7:2:1劃分訓練集、驗證集、測試集,最后保存數據
第四步,制作訓練集和標簽
# 制作數據集和標簽
import torch# 這些轉換是為了將數據和標簽從Pandas數據結構轉換為PyTorch可以處理的張量,
# 以便在神經網絡中進行訓練和預測。def make_data_labels(dataframe):'''參數 dataframe: 數據框返回 x_data: 數據集 torch.tensory_label: 對應標簽值 torch.tensor'''# 信號值x_data = dataframe.iloc[:,0:-1]# 標簽值y_label = dataframe.iloc[:,-1]x_data = torch.tensor(x_data.values).float()y_label = torch.tensor(y_label.values.astype('int64')) # 指定了這些張量的數據類型為64位整數,通常用于分類任務的類別標簽return x_data, y_label# 加載數據
train_set = load('train_set')
val_set = load('val_set')
test_set = load('test_set')# 制作標簽
train_xdata, train_ylabel = make_data_labels(train_set)
val_xdata, val_ylabel = make_data_labels(val_set)
test_xdata, test_ylabel = make_data_labels(test_set)
# 保存數據
dump(train_xdata, 'trainX_1024_10c')
dump(val_xdata, 'valX_1024_10c')
dump(test_xdata, 'testX_1024_10c')
dump(train_ylabel, 'trainY_1024_10c')
dump(val_ylabel, 'valY_1024_10c')
dump(test_ylabel, 'testY_1024_10c')
1.2 數據加載,訓練數據、測試數據分組,數據分batch
import torch
from joblib import dump, load
import torch.utils.data as Data
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
# 參數與配置
torch.manual_seed(100) # 設置隨機種子,以使實驗結果具有可重復性
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 有GPU先用GPU訓練# 加載數據集
def dataloader(batch_size, workers=2):# 訓練集train_xdata = load('trainX_1024_10c')train_ylabel = load('trainY_1024_10c')# 驗證集val_xdata = load('valX_1024_10c')val_ylabel = load('valY_1024_10c')# 測試集test_xdata = load('testX_1024_10c')test_ylabel = load('testY_1024_10c')# 加載數據train_loader = Data.DataLoader(dataset=Data.TensorDataset(train_xdata, train_ylabel),batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)val_loader = Data.DataLoader(dataset=Data.TensorDataset(val_xdata, val_ylabel),batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)test_loader = Data.DataLoader(dataset=Data.TensorDataset(test_xdata, test_ylabel),batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)return train_loader, val_loader, test_loaderbatch_size = 32
# 加載數據
train_loader, val_loader, test_loader = dataloader(batch_size)
2 Transformer分類模型和超參數選取
2.1 定義Transformer分類模型,采用Transformer架構中的編碼器:
注意:輸入數據進行了堆疊 ,把一個1*1024 的序列 進行劃分堆疊成形狀為 32 * 32, 就使輸入序列的長度降下來了
2.2 定義模型參數
# 模型參數
input_dim = 32 # 輸入維度
hidden_dim = 512 # 注意力維度
output_dim = 10 # 輸出維度
num_layers = 4 # 編碼器層數
num_heads = 8 # 多頭注意力頭數
batch_size = 32
# 模型
model = TransformerModel(input_dim, output_dim, hidden_dim, num_layers, num_heads, batch_size)
model = model.to(device)
loss_function = nn.CrossEntropyLoss(reduction='sum') # loss
learn_rate = 0.0003
optimizer = torch.optim.Adam(model.parameters(), lr=learn_rate) # 優化器
2.3 模型結構
3 Transformer模型訓練與評估
3.1?模型訓練
訓練結果
100個epoch,準確率將近90%,Transformer模型分類效果良好,參數過擬合了,適當調整模型參數,降低模型復雜度,還可以進一步提高分類準確率。
注意調整參數:
-
可以適當增加 Transforme編碼器層數 和隱藏層的維度,微調學習率;
-
調整多頭注意力的頭數,增加更多的 epoch (注意防止過擬合)
-
可以改變一維信號堆疊的形狀(設置合適的長度和維度)
3.2 模型評估
# 模型 測試集 驗證
import torch.nn.functional as F# 加載模型
model =torch.load('best_model_transformer.pt')
# model = torch.load('best_model_cnn2d.pt', map_location=torch.device('cpu'))# 將模型設置為評估模式
model.eval()
# 使用測試集數據進行推斷
with torch.no_grad():correct_test = 0test_loss = 0for test_data, test_label in test_loader:test_data, test_label = test_data.to(device), test_label.to(device)test_output = model(test_data)probabilities = F.softmax(test_output, dim=1)predicted_labels = torch.argmax(probabilities, dim=1)correct_test += (predicted_labels == test_label).sum().item()loss = loss_function(test_output, test_label)test_loss += loss.item()test_accuracy = correct_test / len(test_loader.dataset)
test_loss = test_loss / len(test_loader.dataset)
print(f'Test Accuracy: {test_accuracy:4.4f} Test Loss: {test_loss:10.8f}')Test Accuracy: 0.9570 Test Loss: 0.12100271