基于卷积神经网络处理西储大学轴承数据集的故障诊断
西储大学提供了一个包含正常数据(N, Normal)、滚动体故障数据(B, Ball)、内圈故障数据(IR, InnerRace)以及外圈故障数据(OR, OuterRace)的轴承数据集,格式为mat格式。可以使用scio.loadmat函数来读取mat格式的数据。本文仅使用FE风扇端加速度数据进行故障识别,但是mat数据还包括DE驱动端加速度数据和BA基座加速度数据,如果读者有兴趣,可以自行使
网络上有许多关于Anaconda3安装的教程,因此请读者自行搜索Anaconda3的安装方法。本文不会介绍如何安装Anaconda3。
01 基于Anaconda3安装tensorflow2
在此安装的是基于CPU的TensorFlow 2。由于安装基于GPU的TensorFlow 2需要更多的显卡和驱动配置,而且此任务不需要显卡,因此只需下载CPU版本的TensorFlow即可。以下是具体的安装步骤,在命令行中(Windows系统中按Ctrl+R,输入cmd;LINUX系统中使用终端)依次执行下列操作。
# 创建一个python3.7版本的虚拟环境bear_tf
conda create -n bear_tf python=3.7
# 创建后,激活环境变量bear_tf
conda activate bear_tf
# 在环境bear_tf下,下载jupyter notebook
conda install jupyter notebook
# 安装代码运行需要的模块tensorflow, matplotlib和scipy
pip install tensorflow-cpu -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install scipy -i https://pypi.tuna.tsinghua.edu.cn/simple
测试tensorflow是否安装成功。
进入python命令行窗口,导入tensorflow模块,若能导入,基本后续没问题。
python
import tensorflow
02 代码介绍
2.1 导入数据
西储大学提供了一个包含正常数据(N, Normal)、滚动体故障数据(B, Ball)、内圈故障数据(IR, InnerRace)以及外圈故障数据(OR, OuterRace)的轴承数据集,格式为mat格式。可以使用scio.loadmat函数来读取mat格式的数据。本文仅使用FE风扇端加速度数据进行故障识别,但是mat数据还包括DE驱动端加速度数据和BA基座加速度数据,如果读者有兴趣,可以自行使用这两种数据,观察它们对模型故障识别的影响程度。此外,在本次运行中,transpose函数用来对Python中的矩阵进行转置操作,将原来的列向量转换为行向量。
Normal_DIR = "./Normal_0.mat"
B007_DIR = "./B007_0.mat"
IR007_DIR = "./IR007_0.mat"
OR007_DIR = "./OR007@6_0.mat"
Normal=scio.loadmat(Normal_DIR)['X097_FE_time'].transpose()[0]
Inner=scio.loadmat(IR007_DIR)['X105_FE_time'].transpose()[0]
Outer=scio.loadmat(OR007_DIR)['X130_FE_time'].transpose()[0]
Ball=scio.loadmat(B007_DIR)['X118_FE_time'].transpose()[0]
2.2 制作样本和数据预处理
在导入数据后,Normal包含243938个数据,Ball包含121265个数据,InnerRace包含121991个数据, OuterRace包含122571个数据,本文将500个数据作为一个样本,将最后长度小于500的样本抛弃,最后得到总样本1217个。标签采用one-hot方式,轴承存在四种情况(N,B,IR,OR),因此通过长度为4的矩阵来区分,具体情况如下表所示。
标签 | 轴承情况 |
---|---|
[1,0,0,0] | 正常, Normal |
[0,1,0,0] | 滚动体故障, Ball |
[0,0,1,0] | 内圈故障,InnerRace |
[0,0,0,1] | 外圈故障,OuterRace |
lengthNormal = len(Normal);
lengthInner = len(Inner);
lengthOuter = len(Outer);
lengthBall = len(Ball);
print(lengthNormal, lengthInner, lengthOuter, lengthBall)
# 243938 121265 121991 122571
#规范数据长度,并且是每size长度为一条数据
size = 500;
lengthNormal = lengthNormal - lengthNormal%size;
lengthInner = lengthInner - lengthInner%size;
lengthOuter = lengthOuter - lengthOuter%size;
lengthBall = lengthBall - lengthBall%size;
Normal = Normal[0:lengthNormal]
Inner = Inner[0:lengthInner]
Outer = Outer[0:lengthOuter]
Ball = Ball[0:lengthBall]
#连接数据集
data = []
data.extend(Normal);
data.extend(Inner);
data.extend(Outer);
data.extend(Ball);
lengthData = lengthNormal + lengthInner + lengthOuter + lengthBall;
data = np.array(data);
print('数据个数:',lengthData/size)
#将一维数组变成二维(lengthData/size * size)
data = data.reshape(int(lengthData/size),size);
#四种情况,因此通过长度为4的矩阵来区分
label = []
label.extend([[1,0,0,0] for i in range(0,int(lengthNormal/size))]);
label.extend([[0,1,0,0] for i in range(0,int(lengthInner/size))]);
label.extend([[0,0,1,0] for i in range(0,int(lengthOuter/size))]);
label.extend([[0,0,0,1] for i in range(0,int(lengthBall/size))]);
之后,需要对数据进行预处理操作,包括打乱样本数量、归一化,归一化将数据限制在一个很小范围,就是将数据归一化操作对模型的性能提升很大,可以帮助模型训练的时候快速收敛,本文是将数据限制到[-1,1]的范围。对未来需要接触机器学习或者深度学习的同学,可以去B站看吴恩达老师的机器学习课程,讲得真的超级好,看完虽然不会自主写代码,但是可以理解任何与模型有关的东西,这类视频有很多,可自行搜索。
#打乱顺序
index = [i for i in range(0,int(lengthData/size))];
random.shuffle(index);
randData = [];
randLabel = [];
for i in range(0,int(lengthData/size)):
randData.append(data[index[i]]);
randLabel.append(label[index[i]]);
randData = np.array(randData);
randLabel = np.array(randLabel);
#归一化,为了运算方便,减少不必要的消耗
dataMean = np.mean(randData)
dataStd = np.std(randData)
randData -= dataMean
randData /= dataStd
预处理后,需要预先将数据集划分为训练集和测试集(当然,有些时候需要再划分验证集,验证集直接交给后续模型训练。),一般是7:3的比例划分数据的,即70%的样本是训练集,剩余是测试集。
#划分训练集测试集
#按照3,7分开,0.7左右的数据作为训练集,剩余的数据作为测试集
msk = np.random.rand(len(randData))<0.7
trainData=randData[msk]
trainLabel=randLabel[msk]
testData=randData[~msk]
testLabel=randLabel[~msk]
TIME_PERIODS = size #数据个数
2.3 模型训练和测试
这里提供一个较为简单的cnn模型,笔者这里有更完善的模型以及报告,且性能极佳,可自行取舍。
Conv1D是卷积层,具体什么是卷积层,这里由于篇幅问题,就不详细介绍了,简单来说就是特征提取的一个模块。搭建模型的关键是要输入和样本尺寸匹配,输出和标签种类匹配。
#建立模型
#num_classes对应了单个标签的大小,有四种结果,因此num_classes取 4
def create_model(inputShape = (TIME_PERIODS,),numClasses = 4):
model = Sequential()
model.add(Reshape((TIME_PERIODS,1),input_shape = inputShape))
print(model)
model.add(Conv1D(16,8,strides = 2,activation = 'relu',input_shape = (TIME_PERIODS,1)))
model.add(MaxPooling1D(2))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(numClasses,activation = 'softmax'))
return(model)
使用了常用的Adam优化器,学习率为0.0002,以及categorical_crossentropy损失函数。tensorflow进行模型训练和测试很简单,官方提供了fit方法训练和evaluate方法测试。
model.fit其中的validation_split就是前面提到的验证集划分,epochs是训练次数,一般10次就够了,太多容易过拟合,这里tensorflow封装的很好。
opt = Adam(0.0002) #优化器
model.compile(loss = 'categorical_crossentropy',
optimizer = opt,metrics = ['accuracy'])
trainHistory = model.fit(
x = trainData,y = trainLabel,
validation_split = 0.2,
epochs = 10,
validation_freq = 20)
loss,accuracy = model.evaluate(testData,testLabel)
print('loss:',loss,'accuracy:',accuracy)
以下是模型训练的时候输出的日志。
<keras.engine.sequential.Sequential object at 0x7efe0d712110>
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
reshape_3 (Reshape) (None, 500, 1) 0
conv1d_4 (Conv1D) (None, 247, 16) 144
max_pooling1d_3 (MaxPooling (None, 123, 16) 0
1D)
flatten_3 (Flatten) (None, 1968) 0
dropout_6 (Dropout) (None, 1968) 0
dense_4 (Dense) (None, 4) 7876
=================================================================
Total params: 8,020
Trainable params: 8,020
Non-trainable params: 0
_________________________________________________________________
None
Epoch 1/10
25/25 [==============================] - 0s 4ms/step - loss: 1.4001 - accuracy: 0.2434
Epoch 2/10
25/25 [==============================] - 0s 4ms/step - loss: 1.2782 - accuracy: 0.3266
Epoch 3/10
25/25 [==============================] - 0s 4ms/step - loss: 1.1585 - accuracy: 0.4300
Epoch 4/10
25/25 [==============================] - 0s 4ms/step - loss: 1.0473 - accuracy: 0.4956
Epoch 5/10
25/25 [==============================] - 0s 4ms/step - loss: 0.9311 - accuracy: 0.6204
Epoch 6/10
25/25 [==============================] - 0s 4ms/step - loss: 0.8322 - accuracy: 0.6974
Epoch 7/10
25/25 [==============================] - 0s 4ms/step - loss: 0.7365 - accuracy: 0.7907
Epoch 8/10
25/25 [==============================] - 0s 4ms/step - loss: 0.6458 - accuracy: 0.8638
Epoch 9/10
25/25 [==============================] - 0s 4ms/step - loss: 0.5802 - accuracy: 0.9042
Epoch 10/10
25/25 [==============================] - 0s 4ms/step - loss: 0.5104 - accuracy: 0.9470
8/8 [==============================] - 0s 2ms/step - loss: 0.4600 - accuracy: 1.0000
loss: 0.4600314795970917 accuracy: 1.0
show_history()函数是将训练的历史数据可视化,展示10次训练模型准确率变化和损失函数变化。
def show_history(history,accuracy):
plt.plot(history.history[accuracy])
plt.title('History')
plt.ylabel(accuracy)
plt.xlabel('Epoch')
plt.show()
show_history(trainHistory,'accuracy')
show_history(trainHistory,'loss')
话不多说,直接上结果图:
我喜欢使用Ubuntu操作系统。在任何系统运行这个代码时,基本上没有任何问题。不过,我曾经试图在Windows系统上安装TensorFlow,但一直失败,一怒之下,放弃windows系统,开始学习如何使用Linux。如果你现在面临这个问题,我有空可以帮助你配置下linux虚拟机环境。笔者学业比较繁忙,且最近更多接触的是云原生,后续有空的话,会尝试下更新tensorflow、pytorch、python、docker、k8s等。
更多推荐
所有评论(0)