心音信号(PCG)是人体重要的生理信号,携带大量生理特征,但这些微弱信号的提取极易受到外界的干扰,关于心音信号处理相关的文章,可参考下面几篇博士论文,讲的非常详细,因此,不再赘述。
[1]陈尧. 心音心电信号处理的神经网络方法[D].四川大学,2021.
[2]李婷. 基于循环平稳信号理论的心音信号处理方法研究[D].大连理工大学,2015.
[3]韩威. 小样本心音分类方法研究[D].广东工业大学,2020.
首先进行心音信号2分类,即正常与异常分类,首先看一下本次试验用的GoogLeNet网络结构信息
看一下Layers结构
看下输入层信息
看一下两类PCG样本的时域波形
然后定义连续小波变换的滤波器组
fb = cwtfilterbank('SignalLength',signalLength,'VoicesPerOctave',12)
将生成的时频图像导入数据文件夹中
allImages = imageDatastore(fullfile(tempdir,dataDir),...
'IncludeSubfolders',true,'LabelSource','foldernames');
80%的样本用于训练,20%的样本用于测试
rng default
[imgsTrain,imgsValidation] = splitEachLabel(allImages,0.8,'randomized');
disp(['Number of training images: ',num2str(numel(imgsTrain.Files))]);
disp(['Number of validation images: ',num2str(numel(imgsValidation.Files))]);
Number of training images: 1673
Number of validation images: 419
看一下PCG信号CWT时频谱图的样子,首先看一下异常样本
再看一下正常常样本
设置GoogleNet网络的训练参数,采用sgdm优化算法,小批量尺寸MiniBatchSize=15,最大迭代次数MaxEpochs=20,初始学习率InitialLearnRate=1e-4。
options = trainingOptions('sgdm',...
'MiniBatchSize',15,...
'MaxEpochs',20,...
'InitialLearnRate',1e-4,...
'ValidationData',imgsValidation,...
'ValidationFrequency',10,...
'Verbose',false,...
'ExecutionEnvironment','gpu',...
'Plots','training-progress');
开始训练网络
trainedGN = trainNetwork(imgsTrain,lgraph_2,options);
进行网络测试
[YPred,probs] = classify(trainedGN,imgsValidation);
accuracy = mean(YPred==imgsValidation.Labels);
display(['GoogLeNet Accuracy: ',num2str(accuracy)])
GoogLeNet Accuracy: 0.89948,GoogLeNet的准确率达到了90%左右,不是很高,因为样本并不是很多。
看一下混淆矩阵
计算一下各个类别的分类指标
%"异常”类别分类指标
RecallAbnormal = Matrice_confusione.NormalizedValues(1,1)/sum(Matrice_confusione.NormalizedValues(1,:));
PrecisionAbnormal = Matrice_confusione.NormalizedValues(1,1)/sum(Matrice_confusione.NormalizedValues(:,1));
F1Abnormal = harmmean([RecallAbnormal PrecisionAbnormal]);
fprintf('RecallAbnormal = %2.3f\nPrecisionAbnormal = %2.3f\nF1Abnormal = %2.3f\n',100*RecallAbnormal,100*PrecisionAbnormal,100*F1Abnormal);
%"正常"类别分类指标
RecallNormal = Matrice_confusione.NormalizedValues(2,2)/sum(Matrice_confusione.NormalizedValues(2,:));
PrecisionNormal = Matrice_confusione.NormalizedValues(2,2)/sum(Matrice_confusione.NormalizedValues(:,2));
F1Normal = harmmean([RecallNormal PrecisionNormal]);
fprintf('RecallNormal = %2.3f\nPrecisionNormal = %2.3f\nF1Normal = %2.3f\n',100*RecallNormal,100*PrecisionNormal,100*F1Normal);
RecallAbnormal = 82.470
PrecisionAbnormal = 86.250
F1Abnormal = 84.318
RecallNormal = 93.592
PrecisionNormal = 91.635
F1Normal = 92.603
因为本例只是个示范,所用的样本相对于GoogleNet结构并不多,所以分类准确率并不高。
下面进行心音信号5分类,即正常normal,主动脉瓣反流 AR,主动脉瓣狭窄AS,二尖瓣反流MR,二尖瓣狭窄MS五类,同样本例只是个示范,所用的样本较少,所以分类准确率并不高。看一下5类PCG样本的时域波形
然后定义连续小波变换的滤波器组
fb = cwtfilterbank('SignalLength',signalLength,'VoicesPerOctave',12)
看一下生成的CWT时频谱图
将生成的时频图像导入数据文件夹中
allImages = imageDatastore(fullfile(tempdir,dataDir),...
'IncludeSubfolders',true,'LabelSource','foldernames');
70%的样本用于训练,30%的样本用于测试
rng default
[imgsTrain,imgsValidation] = splitEachLabel(allImages,0.7,'randomized');
disp(['Number of training images: ',num2str(numel(imgsTrain.Files))]);
disp(['Number of validation images: ',num2str(numel(imgsValidation.Files))]);
设置GoogleNet网络的训练参数
options = trainingOptions('sgdm',...
'MiniBatchSize',15,...
'MaxEpochs',20,...
'InitialLearnRate',1e-4,...
'ValidationData',imgsValidation,...
'ValidationFrequency',10,...
'Verbose',false,...
'ExecutionEnvironment','gpu',...
'Plots','training-progress');
开始训练
trainedGN = trainNetwork(imgsTrain,lgraph_2,options);
进行图像样本分类
[YPred,probs] = classify(trainedGN,imgsValidation);
accuracy = mean(YPred==imgsValidation.Labels);
display(['GoogLeNet Accuracy: ',num2str(accuracy)])
GoogLeNet Accuracy: 0.9
看一下各类别的分类指标
%"normal" 类别分类指标
RecallNormal = Matrice_confusione.NormalizedValues(5,5)/sum(Matrice_confusione.NormalizedValues(5,:));
PrecisionNormal = Matrice_confusione.NormalizedValues(5,5)/sum(Matrice_confusione.NormalizedValues(:,5));
F1Normal = harmmean([RecallNormal PrecisionNormal]);
fprintf('RecallNormal = %2.3f\nPrecisionNormal = %2.3f\nF1Normal = %2.3f\n',100*RecallNormal,100*PrecisionNormal,100*F1Normal);
%"AR"类别分类指标
RecallAR = Matrice_confusione.NormalizedValues(1,1)/sum(Matrice_confusione.NormalizedValues(1,:));
PrecisionAR = Matrice_confusione.NormalizedValues(1,1)/sum(Matrice_confusione.NormalizedValues(:,1));
F1AR = harmmean([RecallAR PrecisionAR]);
fprintf('RecallAR = %2.3f\nPrecisionAR = %2.3f\nF1AR = %2.3f\n',100*RecallAR,100*PrecisionAR,100*F1AR);
% "AS"类别分类指标
RecallAS = Matrice_confusione.NormalizedValues(2,2)/sum(Matrice_confusione.NormalizedValues(2,:));
PrecisionAS = Matrice_confusione.NormalizedValues(2,2)/sum(Matrice_confusione.NormalizedValues(:,2));
F1AS = harmmean([RecallAS PrecisionAS]);
fprintf('RecallAS = %2.3f\nPrecisionAS = %2.3f\nF1AS = %2.3f\n',100*RecallAS,100*PrecisionAS,100*F1AS);
%"MR"类别分类指标
RecallMR = Matrice_confusione.NormalizedValues(3,3)/sum(Matrice_confusione.NormalizedValues(3,:));
PrecisionMR = Matrice_confusione.NormalizedValues(3,3)/sum(Matrice_confusione.NormalizedValues(:,3));
F1MR = harmmean([RecallMR PrecisionMR]);
fprintf('RecallMR = %2.3f\nPrecisionMR = %2.3f\nF1MR = %2.3f\n',100*RecallMR,100*PrecisionMR,100*F1MR);
%"MS"类别分类指标
RecallMS = Matrice_confusione.NormalizedValues(4,4)/sum(Matrice_confusione.NormalizedValues(4,:));
PrecisionMS = Matrice_confusione.NormalizedValues(4,4)/sum(Matrice_confusione.NormalizedValues(:,4));
F1MS = harmmean([RecallMS PrecisionMS]);
fprintf('RecallMS = %2.3f\nPrecisionMS = %2.3f\nF1MS = %2.3f\n',100*RecallMS,100*PrecisionMS,100*F1MS);
RecallNormal = 100.000
PrecisionNormal = 100.000
F1Normal = 100.000
RecallAR = 100.000
PrecisionAR = 75.000
F1AR = 85.714
RecallAS = 83.333
PrecisionAS = 100.000
F1AS = 90.909
RecallMR = 80.000
PrecisionMR = 100.000
F1MR = 88.889
RecallMS = 83.333
PrecisionMS = 83.333
F1MS = 83.333
由于小样本原因,准确率不是很高。重点来了,更重要的是看看如何进行改进
改进方向:信号前处理
1.可以使用合适的信号降噪方法,移不变小波去噪方法对于PCG,ECG等信号来说还是不错的
基于Cycle Spinning的移不变小波去噪 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/539089086
2.根据PCG信号的波形,可以自适应的构造更合适的小波
利用机器学习模型设计正交小波滤波器 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/537254014
为连续小波变换CWT构造新小波 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/534682868
3.使用时频谱图更加集中的同步压缩变换
同步压缩变换初探 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/543569766
高阶同步压缩变换--占坑 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/544716722
在网络选取方面
GoogLeNet相对于本文样本来说太大了,同时我并不推荐迁移学习和样本生成方法,不要问我为什么
基于小波时间散射网络的ECG 信号分类 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/539001673
基于小波散射算法的空气压缩机异常噪声诊断 - 哥廷根数学学派的文章 - 知乎 https://zhuanlan.zhihu.com/p/531077421
码字不易,且行且珍惜
详细代码
正在为您运送作品详情