【MATLAB第5期】源码分享#基于小波时间散射网络(WTSN)和长短期记忆网络 (LSTM) 的ECG信号分类模型,含源代码+中文注释,保姆级教学
引言
1.小波散射网络
关于小波散射网络,可参考一篇文章:
小波散射网络初级探索 - 哥廷根数学学派的文章 - 知乎 哥廷根数学学派:小波散射网络初级探索
本文讲解如何使用小波时间散射网络(WTSN)和长短期记忆网络(LSTM) 对人体心电图 (ECG)信号进行分类。在小波散射中,数据通过一系列的小波变换、非线性化和平均化过程,以产生时间序列的低方差表示。小波时间散射产生了对输入信号微小变化不敏感的信号表示,而几乎不会影响到分类准确率。本文中使用的数据公开,在github网站可以下载。
代码免费下载链接:←←←点击即可下载,整理不易,求个关注~
2.数据描述
本文使用3种 ECG 数据:心律失常数据ARR、充血性心力衰竭数据CHF和正常窦性心律数据NSR,共使用来自3个 PhysioNet 数据库的162条ECG 记录:MIT-BIH心律失常数据库、MIT-BIH正常窦性心律数据库和BIDMC充血性心力衰竭数据库。 共有96个心律失常患者的信号,30个充血性心力衰竭患者的信号,以及36个正常窦性心律患者的信号,目标就是训练分类器来区分心律失常 (ARR)、充血性心力衰竭 (CHF)和正常窦性心律 (NSR)3类信号。
本示例说明如何使用小波时间散射和LSTM对人心电图(ECG)信号进行分类。 我们将训练一个长期短期记忆网络来识别以上心律。
一、加载和预处理数据
数据是162个采样信号,以128Hz的频率(Fs)采样。
load(fullfile(pwd, "ECGData.mat"))%导入数据 Fs = 128;
ECGData是一个结构数组,包含两个字段:Data 和 Labels。数据是一个 162×65536的矩阵,其中每一行是以128Hz采样的ECG信号。每个ECG时间序列的总持续时间为512秒。标签是一个 162×1 的标签元胞数组,每行1个数据。
这些信号分为三类:
unique(ECGData.Labels)
%ans = 3×1 cell 数组
%{‘ARR’}
%{‘CHF’}
%{‘NSR’}
其中ARR是指心律异常(心律失常)的信号,CHF是指充血性心力衰竭,NSR是指心律正常(正常窦性心律)
让我们看看其中一些信号是什么样的。
M = size(ECGData.Data, 1);%提取数据样本行数 idxsel = randperm(M, 4);%随机选取其中4个样本编号 tiledlayout(2, 2, "Padding", "compact")%建立2*2的图像窗口 %依次画出这4个样本的信号数据特征(提取前3000个序列数据) for numplot = 1:4 nexttile plot(ECGData.Data(idxsel(numplot),1:3000)) ylabel('Volts') xlabel('Samples') title(string(ECGData.Labels(idxsel(numplot)))) end
二、使用小波散射自动特征提取
1.小波散射特征提取
小波散射是一种可用于自动提取低方差,紧凑特征的技术,该方法可以最大程度地减少类内的差异,同时保留各个类之间的可区分性。我们可以提供这些功能,而不是将原始表示提供给LSTM,以便网络可以快速学习模式并随后对信号进行分类。
sampleSig = ECGData.Data(1,:);%选取第一行样本 sf = waveletScattering('SignalLength',numel(sampleSig),'SamplingFrequency',Fs) feat = featureMatrix(sf,sampleSig);%自动提取特征
sf = waveletScattering - 属性:
SignalLength: 65536
InvarianceScale: 256
QualityFactors: [8 1]
Boundary: “periodic”
SamplingFrequency: 128
Precision: “double”
OversamplingFactor: 0
2.提取特征前后特征尺寸对比
变量 feat 包含从信号中自动提取的特征。 在此示例中,我们使用2层网络提取所有要素。
提取特征前sampleSig包含要素:
提取特征后 feat包含要素:
与原始信号的长度相比,特征尺寸减少了95%
3.可视化提取的特征
我们可以独立检查来自每一层的特征
lev = 1; [S1,U1] = scatteringTransform(sf,ECGData.Data(find(ECGData.Labels=="ARR",1),:)); [S2,U2] = scatteringTransform(sf,ECGData.Data(find(ECGData.Labels=="NSR",1),:)); scattergram(sf,S1,'FilterBank',lev); title(sprintf('Scattering Level %d: Class I sample',lev));
scattergram(sf,S2,‘FilterBank’,lev);
title(sprintf(‘Scattering Level %d: Class II sample’,lev));
注意:上面显示的只是一种可视化提取了哪些特征的方法。 为每个信号提取一个499x8特征矩阵。
三、提取训练和测试集中所有信号的特征
让我们将数据集随机划分为训练数据集和测试数据集。
1.提取训练和测试集中所有信号的特征
让我们将数据集随机划分为训练数据集和测试数据集。
%load(fullfile(pwd, "data", "PartitionedData.mat")) idxRandomized = randperm(M);%样本顺序打乱 trainSize = 113;%113个样本训练 testSize = M-trainSize;%162-113=49个样本测试 trainData = zeros(trainSize, size(ECGData.Data,2));%113*65536 double数据格式 trainLabels = cell(trainSize,1);%113*1 cell数据格式 testData = zeros(testSize, size(ECGData.Data,2));%49*65536 double数据格式 testLabels = cell(testSize,1);%49*1 cell数据格式
使用我们现有的小波散射变换,为训练和测试数据集计算散射特征。
scat_features_train = cell(trainSize,1);%113*1 cell 数据结构,每个cell是499*8 scat_features_test = cell(testSize,1);%49*1 cell数据结构,每个cell是499*8
四、利用散射特征训练LSTM
1.建立训练模型
现在让我们建立一个非常简单的LSTM网络进行训练。
[inputSize,~] = size(scat_features_train{1}); YTrain = categorical(trainLabels); numHiddenUnits = 100;%隐含层神经元数 numClasses = numel(unique(YTrain));%类别数量 maxEpochs = 125;%训练次数 miniBatchSize = 1000;%最小批处理数量 layers = [ ... sequenceInputLayer(inputSize) lstmLayer(numHiddenUnits,'OutputMode','last') fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
并建立一些通用的训练选项。
options = trainingOptions('adam', ...%adam学习器 'InitialLearnRate',0.01,...%初始学习率 'MaxEpochs',maxEpochs, ... 'MiniBatchSize',miniBatchSize, ... 'SequenceLength','shortest', ...%“最短”—截断每个小批中的序列,使其长度与最短序列相同。 'Shuffle','never',...%不打乱数据 'Plots','training-progress');
现在我们准备训练或者导入已经训练好的网络。
if true netScat = trainNetwork(scat_features_train,YTrain,layers,options); else load(fullfile(pwd, "data", "netScat.mat")) end
2.评估LSTM模型
现在我们可以测试我们训练好的模型:
YTest = categorical(testLabels);%提取测试输出实际类别 YPred = classify(netScat,scat_features_test, 'MiniBatchSize',miniBatchSize, 'SequenceLength','shortest'); accuracy = round((sum(YPred == YTest)./numel(YTest))*100);%正确率 confusionchart(YTest, YPred, "RowSummary", "row-normalized"); title("Accuracy: " + accuracy + "%")
3.提高分类准确度
如果您对结果不满意,则可以对散射滤波器组中的一个可选参数进行微调,以获得所需的结果。 invariance scale 的默认值是信号长度的一半(以样本为单位)。
您始终可以扫描 invariance scale 并使用贝叶斯优化来找出LSTM网络的超参数的正确组合。
五、总结
本示例使用小波时间散射和LSTM将ECG波形分类为三个诊断类别之一。 小波散射被证明是功能强大的特征提取器,它只需要一组最少用户指定的参数即可产生一组可靠的分类特征。