1、文章概括

本文利用凯斯西储大学轴承中心数据,采用了连续小波变换(Continue Wavelet Transform,CWT)提取振动信号的时频特征,并将其时频图整理,作为卷积神经网络的输入。然后,划分训练集和测试集,搭建卷积神经网络(Convolutional Neural Network,CNN),学习不同失效模式下的时频图。最后,根据测试集,通过TSNE可视化和混淆矩阵,分析CNN神经网络的智能诊断效果。

1.1 技术路线

1.2 结果展示

上述结果分别为测试集的混淆矩阵和训练集的TSNE可视化结果。

从混淆矩阵中能发现,CNN网络对滚动轴承不同故障的识别精度达到了100%。

从TSNE可视化结果也能发现,经过CNN网络的特征提取和映射,不同故障类别的特征得到了有效的区分。

以上这些结果表明了卷积神经网络在特征提取和映射方面的卓越性能。

代码采用了Matlab 2023a进行运行,欢迎大家测试和提出问题!

2、基于CNN和CWT的滚动轴承智能诊断方法

第一步:利用连续小波变换方法(CWT),分析不同故障模式信号的时频域波形,观察信号的频率分布差异情况。

第二步:设置样本长度,并依次保存不同故障模式的时频图像,用作后续卷积神经网络的输入。

第三步:搭建卷积神经网络模型,设置网络参数,并划分样本为训练集和测试集(比例为8:2)。利用训练集训练CNN模型。

第四步:利用测试集,借助TSNE可视化和混淆矩阵,评估CNN模型的故障识别效果。

2.1 连续小波变换理论

连续小波变换(Continuous Wavelet Transform,CWT)是一种用于信号分析的数学工具,它通过将一个信号与不同尺度和位置的小波函数进行卷积,来获取信号的时频信息

连续小波变换的核心思想是使用可变尺寸的窗口来适应信号的不同频率成分,从而实现信号的局部化分析。

关于连续小波变换的科普文章,挺多的,这里就不再介绍,后期可能会推出其相关的代码案例。

在Matlab中有连续小波变换的函数:cwt.m,它较老版本有些修改,不需要提供尺度向量,能自适应地生成时频图像。、

值得注意是,采用新版本的cwt获得小波时频图像,在设置频率纵轴时,需要转换为对数坐标,即以下代码:

      set(gca,'yscale','log');

否则,cwt画出的时频图像有误。

2.2 卷积神经网络

卷积神经网络(Convolutional Neural Networks,CNNs)是一种深度学习模型,它在图像处理、语音识别、自然语言处理等多个领域都有着广泛的应用。

CNNs的设计灵感来源于人类视觉系统的工作原理,它特别适合处理具有网格状拓扑结构的数据,如图像。著名的卷积神经网络模型有AlexNet、InceptionNet、VGGNet和ResNet等。

3、实验分析

实验数据采用凯斯西楚大学(CWRU)的轴承数据,相关数据说明可参考如下软文:

            CWRU(凯斯西储大学)轴承数据

本文选择了97.mat(正常)、105.mat(内圈)、118.mat(滚动体)、130.mat(外圈)四组数据,该信号的采样频率为12000Hz。

第一步:利用连续小波变换方法(CWT),分析不同故障模式信号的时域波形。同时,将图片自动保存,生成以故障类别为名称、图片编号为名字的png格式图片。代码如下

%% 基于卷积神经网络的滚动轴承智能诊断方法
%% 作者:冷漠
%% 时间:2024年4月16日
%% 关注公众号 :"故障诊断与寿命预测工具箱",每天进步一点点
%% 第一个主程序  读取信号并开展连续小波变换分析,保存时频图用于后续作卷积神经网络的输入
clc
clear all
close all
%%  提取特征并保存图片
file_path =  ['D:\我的文档\硕士\信息\副业\公众号\公众号\' ...
    '20240416基于卷积神经网络的滚动轴承智能诊断方法' ...
    '\20240416基于卷积神经网络的滚动轴承智能诊断方法\data\'];% 文件夹路径
mat_acc_path_list = dir(strcat(file_path,'*.mat'));%获取该文件夹中所有csv格式的文件
mat_order_name= sort_nat({mat_acc_path_list.name}); 
mat_acc_num = length(mat_acc_path_list);%获取文件总数量
feature_all=cell(mat_acc_num,2);   %所有特征
Fs=12*10^3;           %采样频率
sample_length=2048;   %单个样本的长度
count=150;            %每种故障类型的样本总量
for i = 1:mat_acc_num
    variable=load(strcat(file_path,mat_order_name{1,i}));
    names = fieldnames(variable); % 获取mat中所有变量的名字
    sub_index = find(contains(names,'time'));     %每种mat内数据变量的索引
    sub_l=count/length(sub_index)*sample_length;  %要求每个变量采集的数据的长度
    photo_number=1;
    for j=1:length(sub_index)
        data = variable.(names{sub_index(j)}); % 取出第一个变量
        data = data(1:sub_l,1);
        data = reshape(data,sample_length,[]);
        %连续小波变换
        for jj=1:size(data,2)
            sub_data=data(:,jj);
            [w,fre]=cwt(sub_data,'morse',Fs);
            t=0:1/Fs:(length(sub_data)-1)/Fs;
            figure;imagesc(t,fre,abs(w));axis tight;axis xy; %  连续小波图像
            set(gca,'yscale','log');
            xlabel('Time (s)');ylabel('Frequency (Hz)');colormap('jet'); 
            axis off;
            set(gcf,'Position',[100 200 150 100]);
            set(gca,'looseInset',[0 0 0.08 0.08]);
            F=getframe(gcf);
            if ~exist(['data\',num2str(i)], 'dir')   %创建子文件夹
                mkdir(['data\',num2str(i)]);
            end
            imwrite(F.cdata,['data\',num2str(i),'\',num2str(photo_number),'.png']);
            fprintf('已生成 %s数据的第 %d图片,该图片属于 %s数据的 %s变量\n', ...
                mat_order_name{1,i},photo_number,mat_order_name{1,i},names{sub_index(j)});
            photo_number= photo_number+1;
            close all
        end
    end
end

参数设置和注意

1、单个连续小波变换样本长度为2048;

2、每种故障类型样本总量为150个,四种即600个;

3、代码自动拾取每个mat文件中含有time的变量个数,并且平均从中抽取等量等样本,以97.mat文件为例,含有变量X097_DE_time和X097_FE_time两个变量,所以每个变量分别提取150/2=75个样本。值得注意是,需要预先根据不同mat内数据情况,选择合适的count值,在105.mat、118.mat、130.mat中分别含有3个带time的变量,这导致count的数量需要为3的整倍数,同时也是要2的整倍数(97.mat的缘故),请各位读者理解一下哈!

4、如果想看每一步的连续小波图像,可以在38行(axis off;)设置断点。

5、如果运行测试,请一定注意修改路径,即file_path变量。

上图为97.mat的X097_DE_time的一个样本的连续小波变换的图像。从图像中能发现,在1000Hz出有周期性的频率成分出现。

为了加速后续CNN的训练过程,降低CNN网络参数的规模,方便大家快速地理解这个流程。我将CWT的图像进行了缩放,上图为缩小后的图片。虽然丢失了一些信息,但图片从原先560*420*3变为了150*100*3,大小缩小了94%,这个能简省大量时间,我也是在调试代码时发现了。而且从后续智能诊断结果看出,压缩后的信息依然能用于区分不同故障模式。

第二步:搭建神经网络模型,并训练CNN网络。并划分样本为训练集和测试集(比例为8:2)

%% 基于卷积神经网络的滚动轴承智能诊断方法
%% 作者:冷漠
%% 时间:2024年4月16日
%% 关注公众号 :"故障诊断与寿命预测工具箱",每天进步一点点
%% 第二个主程序  利用已时频图,搭建卷积神经网络,识别滚动轴承的失效模式
clc
clear all
close all
%% 读取数据
digitDatasetPath = ['D:\我的文档\硕士\信息\副业\公众号\公众号\' ...
    '20240416基于卷积神经网络的滚动轴承智能诊断方法\' ...
    '20240416基于卷积神经网络的滚动轴承智能诊断方法\data'];   %不同失效模式的根文件夹路径
imds = imageDatastore(digitDatasetPath,'IncludeSubfolders',true,'LabelSource','foldernames');
%% 展示一些图片
figure;
perm = randperm(600,20);
for i = 1:20
    subplot(4,5,i);
    imshow(imds.Files{perm(i)});
end
% 计算每个类别的图像数量
labelCount = countEachLabel(imds)
% 计算每个图片的大小
img = readimage(imds,1);
size(img)
% 划分数据集为训练集和测试集
[imdsTrain,imdsTest] = splitEachLabel(imds,0.8,'randomized');  %训练集和测试集按照8:2的方式随机划分 随机抽取
​
%% 卷积神经网络
inputSize = size(img);   %根据size(img)的打印结果确定
numOutput = size(labelCount,1);
​
layers = [
    imageInputLayer(inputSize,'Normalization','zscore','Name','input')
    
    convolution2dLayer([3,3],32,'Padding','same','Name','conv1')
    batchNormalizationLayer('Name','BN1')
    reluLayer('Name','relu1')
    
    maxPooling2dLayer(2,'Stride',2,'Name','maxpool1')
    
    convolution2dLayer([3,3],64,'Padding','same','Name','conv2')
    batchNormalizationLayer('Name','BN2')
    reluLayer('Name','relu2')
    
    maxPooling2dLayer(2,'Stride',2,'Name','maxpool2')
    
    convolution2dLayer([3,3],128,'Padding','same','Name','conv3')
    batchNormalizationLayer('Name','BN3')
    reluLayer('Name','relu3')
    maxPooling2dLayer(2,'Stride',2,'Name','maxpool3')
​
    fullyConnectedLayer(128,'Name','fc1')
    fullyConnectedLayer(64,'Name','fc2')
    fullyConnectedLayer(numOutput,'Name','output')
    softmaxLayer('Name','softmaxLayer')
    classificationLayer];
​
maxEpochs = 20;
miniBatchSize_test = 1;
MiniBatchSize= 32;
figure
plot(layerGraph(layers));  %网络结构
​
options = trainingOptions('adam', ...
    'InitialLearnRate',0.01, ...
    'MaxEpochs',maxEpochs, ...
    'MiniBatchSize',MiniBatchSize,...
    'Shuffle','every-epoch', ...
    'ValidationData',imdsTest, ...           %我这里没有划分验证集,直接用测试集,时刻关注识别结果
    'ValidationFrequency',20, ...
    'Verbose',false, ...
    'Plots','training-progress');
​
net = trainNetwork(imdsTrain,layers,options);

​CNN网络的训练过程:

上图为展示的一些图片样本。下图为CNN神经网络的结构:

具体为:图片输入层input→卷积层conv1→批量归一化层BN1→激活层relu1→最大池化层maxpool1→卷积层conv2→批量归一化层BN2→激活层relu2→最大池化层maxpool2→卷积层conv3→批量归一化层BN3→激活层relu3→最大池化层maxpool3→全连接层fc1→全连接层fc2→全连接层output→softmax层→分类层。

第三步:利用测试集,分析已训练CNN网络的分类效果。代码如下:

​%% 测试
YPred = classify(net,imdsTest);
YTest = imdsTest.Labels;
​
accuracy = sum(YPred == YTest)/numel(YTest);  %识别准确率
figure
confusionchart(YTest,YPred,'ColumnSummary','column-normalized', ...
    'RowSummary','row-normalized')  %混淆矩阵

​从图中能所搭建的CNN网络的分类效果达到了100%。其中,根据第一步中的mat_order_name变量可知,1、2、3、4分别对应着97.mat、105.mat、118.mat、130.mat,即正常、内圈故障、滚动体故障、外圈。

第四步:利用TSNE可可视化分析方法,分析训练集的聚类聚类效果。一般情况下,看测试集的聚类效果,这个大家根据自己的理解,修改代码就行。具体代码如下

%% 网络聚类结果可视化
rng default
LayerName1 = "maxpool1";
LayerName2 = "maxpool2";
LayerName3 = "maxpool3";
LayerName4 = "softmaxLayer";
LayerActivations1 = activations(net,imdsTrain,LayerName1,"OutputAs","rows");
LayerActivations2 = activations(net,imdsTrain,LayerName2,"OutputAs","rows");
LayerActivations3 = activations(net,imdsTrain,LayerName3,"OutputAs","rows");
LayerActivations4 = activations(net,imdsTrain,LayerName4,"OutputAs","rows");
layer_tsne1 = tsne(LayerActivations1,'Distance','euclidean');
layer_tsne2 = tsne(LayerActivations2,'Distance','euclidean');
layer_tsne3 = tsne(LayerActivations3,'Distance','euclidean');
layer_tsne4 = tsne(LayerActivations4,'Distance','euclidean');
​
​
markerSize = 7;
figure(Position=[100 100 900 600]);
​
subplot(2,2,1);
gscatter(layer_tsne1(:,1),layer_tsne1(:,2),imdsTrain.Labels, [],'.',markerSize);
title("maxpool1 layer");
legend('Location','eastoutside');
​
subplot(2,2,2);
gscatter(layer_tsne2(:,1),layer_tsne2(:,2),imdsTrain.Labels, [],'.',markerSize);
title("maxpool2 layer");
legend('Location','eastoutside');
​
subplot(2,2,3);
gscatter(layer_tsne3(:,1),layer_tsne3(:,2),imdsTrain.Labels, [],'.',markerSize);
title("maxpool3 layer");
legend('Location','eastoutside');
​
subplot(2,2,4);
gscatter(layer_tsne4(:,1),layer_tsne4(:,2),imdsTrain.Labels, [],'.',markerSize);
title("softmax layer");
legend('Location','eastoutside');

上图分别展示了已训练的网络,分别在maxpool1层、maxpool2层、maxpool3层和softmaxLayer层的TSNE可视化结果。从图中能发现,随着网络的不断加深,不同类别的特征之间距离变大,同类别特征之间距离减小,这表明了CNN网络分类的可行性。

(有兴趣的效果伙伴可以试一试直接用CNN网络进行端(采集端,不进行信号处理和分析)到端(诊断端)的智能诊断,后续根据大家情况写一期。)

总结

上述是一个基于连续小波变换卷积神经网络的滚动轴承智能诊断方法例子。首先,采用连续小波变换,获取信号的时频图。然后,利用这些时频图,训练神经网络。最后,利用测试集,借助混淆矩阵和TSNE可视化,分析神经网络的分类效果。

代码和参考文献

附件

源码及其数据文件

b3rt

1、上述源码及其数据文件

     ①97.mat、105.mat、118.mat、130.mat

     ②代码文件:maintf.m(读取mat数据,进行连续小波分析,自动保存图片);network_CNN.m(读取时频图像,并训练神经网络,评价分类效果);sort_nat.m(排序函数,用于maintf.m,可忽略)

    ③数据文件:data文件夹,它为maintf.m的运行结果。

2、相关参考

    ①https://ww2.mathworks.cn/help/deeplearning/ug/create-simple-deep-learning-network-for-classification.html (Mathwork的一个深度学习例子)

   ②https://ww2.mathworks.cn/help/wavelet/ref/cwt.html?searchHighlight=cwt&s_tid=srchtitle_support_results_1_cwt(Mathwork的cwt函数)

    ③https://ww2.mathworks.cn/help/deeplearning/ug/view-network-behavior-using-tsne.html?searchHighlight=tsne&s_tid=srchtitle_support_results_4_tsne(Mathwork的TSNE例子,不同版本的matlab好像tsne可视化函数有差异,最好看看自己的版本matlab的例子)

关注公众号“故障诊断与寿命预测工具箱”,每天进步一点点。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐