主要内容

利用长、短期记忆网络对心电信号进行分类

此示例显示如何使用深度学习和信号处理将心跳心电图(ECG)数据分类为2017年挑战。特别是,该示例使用长短短期内存网络和时频分析。

介绍

ECG在一段时间内记录了一个人心脏的电活动。如果患者的心跳正常或不规则,医生使用ECGS在视觉上检测。

心房纤颤(AFib)是一种不规则的心跳,当心脏的上腔室(心房)与下腔室(心室)的跳动不协调时发生。

本例使用了PhysioNet 2017挑战赛的心电图数据[1], [2], [3.],网址是https://physionet.org/challenge/2017/.这些数据由一组以300赫兹采样的心电信号组成,由一组专家分为四类:正常(N)、非正常(a)、其他节律(O)和噪声记录(~)。这个例子展示了如何使用深度学习自动化分类过程。该程序探索了一种可以区分正常心电信号和显示AFib信号的二值分类器。

这个例子使用了长短期记忆(LSTM)网络,这是一种非常适合研究序列和时间序列数据的递归神经网络(RNN)。LSTM网络可以学习序列时间步长之间的长期依赖关系。LSTM层(lstmLayer(深度学习工具箱))可以正向查看时间序列,而双向LSTM层(bilstmLayer(深度学习工具箱))可以从正反两个方向看时间序列。这个例子使用了一个双向LSTM层。

为了加速训练过程,请在带有GPU的机器上运行此示例。如果您的机器有GPU和并行计算工具箱™,那么MATLAB®自动使用GPU进行训练;否则,使用CPU。

加载并检查数据

运行ReadPhysionetData脚本从PhysoioNet网站下载数据并生成MAT文件(PhysionetData.mat),其中包含适当格式的心电信号。下载数据可能需要几分钟。使用条件语句,仅当PhysionetData.mat当前文件夹中不存在。

如果~ isfile (“PhysionetData.mat”) ReadPhysionetData结束负载PhysionetData

加载操作将两个变量添加到Workspace:信号标签信号是保存心电信号的细胞阵列。标签是一个类别数组,其中保存信号的相应地真值标签。

信号(1:5)
ans =5×1个单元阵列{1×9000 double} {1×9000 double} {1×18000 double} {1×9000 double} {1×18000 double}
标签(1:5)
ans =5×1分类N N N a

使用总结函数查看数据中包含了多少AFib信号和Normal信号。

总结(标签)
A 738 n 5050

生成信号长度的直方图。大多数信号都有9000个样本长。

L = cellfun (@length,信号);h =直方图(左);xticks (0:3000:18000);xticklabels (0:3000:18000);标题(“信号长度”)包含(“长度”) ylabel (“数”

可视化来自每个类的一个信号的片段。AFib的心跳间隔是不规则的,而正常的心跳是有规律的。AFib心跳信号也经常缺乏P波,它在正常心跳信号的QRS复合体之前跳动。正常信号的图显示了P波和QRS波复合体。

正常={1}信号;aFib ={4}信号;次要情节(2,1,1)情节(正常的)标题('正常节奏') xlim((4000、5200))ylabel (“振幅(mV)”)文本(4330、150、“P”“HorizontalAlignment”“中心”)文本(4370、850、“QRS”“HorizontalAlignment”“中心”) subplot(2,1,2) plot(aFib) title(心房纤维性颤动的) xlim((4000、5200))包含(“样本”) ylabel (“振幅(mV)”

准备培训数据

在培训期间,trainNetwork函数将数据分割为小批量。然后,该函数在同一小批量中填充或截断信号,使它们具有相同的长度。过多的填充或截断会对网络的性能产生负面影响,因为网络可能会根据添加或删除的信息错误地解释信号。

为避免过度填充或截断,请应用segmentSignals功能,所以它们都是9000个样本长。该功能忽略小于9000个样本的信号。如果一个信号有超过9000个样本,segmentSignals将其分成尽可能多的9000样本段,忽略剩余的样本。例如,具有18500个样本的信号变为两个9000样本信号,并且剩余的500个样本被忽略。

[信号,标签]= segmentSignals(信号,标签);

查看的前五个元素信号数组,以验证每个条目现在是9000个样本长。

信号(1:5)
ans =5×1个单元阵列{1×9000 double} {1×9000 double} {1×9000 double} {1×9000 double} {1×9000 double}

使用原始信号数据训练分类器

要设计分类器,请使用前一节中生成的原始信号。将信号分割为训练集来训练分类器和测试集来测试分类器对新数据的准确性。

使用总结函数显示AFib信号与Normal信号的比值为718:4937,或约为1:7。

总结(标签)
一个718 n 4937

由于大约7/8的信号是正常的,因此分类器将得知它可以通过将所有信号作为正常分类来实现高精度。为避免这种偏差,通过在数据集中复制AFIB信号来增强AFIB数据,以便存在相同数量的正常和AFIB信号。这种重复,通常称为过采样,是深度学习中使用的一种形式的数据增强。

根据信号的类别来划分。

afibX(标签= = =信号“一个”);afibY =标签(标签= =“一个”);normalX(标签= = =信号“N”);= = =饱和标签(标签“N”);

接下来,使用分开将每个班级的目标随机划分为训练集和测试集。

[训练达,〜,testinda] = divierand(718,0.9,0.0.0.1);[TrainIndn,〜,TestIndn] = Divierand(4937,0.9,0.0,0.1);Xtraina = afibx(Traininda);ytraina = afiby(traininda);Xtrainn = IrmanicX(TareIndn);Ytrainn = normaly(Tarchindn);xtesta = afibx(testinda);ytesta = afiby(testinda);xtestn = uncormx(testindn);ytestn = normaly(testindn);

目前训练有646个AFib信号,4443个Normal信号。要在每个类中实现相同数量的信号,首先使用4438个Normal信号,然后使用repmat将前634个AFib信号重复七次。

用于测试的有72个AFib信号和494个Normal信号。先用490正常信号,再用repmat将前70个AFib信号重复7次。默认情况下,神经网络在训练前随机洗牌数据,以确保连续的信号不都有相同的标签。

XTrain = [repmat (XTrainA(1:634), 7日,1);XTrainN (1:4438)];YTrain = [repmat (YTrainA(1:634), 7日,1);YTrainN (1:4438)];XTest = [repmat (XTestA(1:70), 7日,1);XTestN (1:490)];欧美= [repmat (YTestA(1:70), 7日,1);YTestN (1:490);];

在训练集中和测试集中,Normal和AFib信号之间的分布现在是均匀平衡的。

总结(YTrain)
A 4438 n 4438
总结(欧美)
A 490 n 490

定义LSTM网络架构

LSTM网络可以学习序列数据时间步长之间的长期依赖关系。本例使用双向LSTM层bilstmLayer,因为它在前后两个方向上都观察序列。

因为输入信号每个具有一个维度,所以指定输入大小为尺寸1.指定具有100的输出大小的双向LSTM层并输出序列的最后一个元素。此命令指示双向LSTM层将输入时间序列映射到100个功能中,然后为完全连接的图层准备输出。最后,通过包括一个完全连接的大小2层来指定两个类,然后是Softmax层和分类层。

层= [...sequenceInputLayer (1) bilstmLayer (100“OutputMode”“最后一次”(2) softmaxLayer classificationLayer
Layer = 5x1 Layer array with layers: 1 '' Sequence Input Sequence Input with 1 dimensions 2 '' BiLSTM BiLSTM with 100 hidden units 3 '' Fully Connected 2 Fully Connected Layer 4 '' Softmax Softmax 5 '' Classification Output crossentropyex

接下来为分类器指定训练选项。设置“MaxEpochs”到10,允许网络10次通过训练数据。一个“MiniBatchSize”其中150个信号指示网络一次查看150个训练信号。一个“InitialLearnRate”0.01有助于加快培训过程。指定A.“SequenceLength”1000可以将信号分成较小的部分,使机器在一次看太多数据时不会耗尽内存。放 'GradientThreshold'为1,以防止梯度变得过大,从而稳定训练过程。指定“阴谋”作为“训练进步”生成随着迭代次数增加而显示训练进度的图形。集“详细”禁止与图中显示的数据对应的表输出。如果你想看这张桌子,就去“详细”真的

本例使用自适应矩估计(ADAM)求解器。ADAM在像lstm这样的rnn中比默认的SGDM(随机梯度下降与动量)求解器表现更好。

选项=培训选项(“亚当”...“MaxEpochs”10...“MiniBatchSize”, 150,...“InitialLearnRate”, 0.01,...“SequenceLength”, 1000,...“GradientThreshold”, 1...“ExecutionEnvironment”“汽车”...“阴谋”“训练进步”...“详细”、假);

培训LSTM网络

使用指定的训练选项和层架构对LSTM网络进行训练trainNetwork.由于训练集很大,训练过程可能需要几分钟。

网= trainNetwork (XTrain、YTrain层,选择);

训练进度图的顶部子图表示训练准确率,即每个小批上的分类准确率。当培训成功进行时,这个值通常会增加到100%。底部的子图显示了训练损失,这是每个小批上的交叉熵损失。当训练成功进行时,这个值通常会降至零。

如果训练不收敛,图可能会在值之间振荡,而不会朝着某个向上或向下的方向。这种振荡意味着训练精度没有提高,训练损失没有减少。这种情况可能在训练开始时就出现,或者在训练准确性初步提高后,情节可能会趋于平稳。在许多情况下,改变训练选项可以帮助网络实现收敛。减少小匹匹匹匹配或减少initiallearnrate.可能会导致更长的训练时间,但它可以帮助网络更好地学习。

分类器的训练精度振荡在大约50%和约60%之间,并且在10个时期结束时,它已经花了几分钟才能训练。

可视化培训和测试准确性

计算训练准确率,它表示分类器对所训练信号的准确率。首先,对训练数据进行分类。

trainpred =分类(net,xtrain,“SequenceLength”, 1000);

在分类问题中,混淆矩阵用于可视化分类器在一组已知真值的数据上的性能。目标类是信号的地面真实标签,输出类是网络分配给信号的标签。轴标签代表类标签,AFib (A)和Normal (N)。

使用confusionchart命令来计算测试数据预测的总体分类精度。指定“RowSummary”作为“row-normalized”在行汇总中显示真实阳性率和假阳性率。同时,指定'placeSummary'作为“column-normalized”在列摘要中显示阳性预测值和错误发现率。

LSTMAccuracy = sum(trainPred == YTrain)/numel(YTrain)*100
LSTMAccuracy = 61.7283
图confusionchart (YTrain trainPred,'placeSummary'“column-normalized”...“RowSummary”“row-normalized”“标题”“LSTM混淆图”);

现在用同一个网络对测试数据进行分类。

XTest testPred =分类(净,“SequenceLength”, 1000);

计算测试精度并将分类性能可视化为一个混淆矩阵。

LSTMAccuracy = sum(testPred == YTest)/numel(YTest)*100
LSTMAccuracy = 66.2245
图confusionchart(欧美、testPred'placeSummary'“column-normalized”...“RowSummary”“row-normalized”“标题”“LSTM混淆图”);

通过特征提取提高性能

从数据中提取特征有助于提高分类器的训练和测试精度。为了确定要提取哪些特征,本例采用了一种计算时频图像(如光谱图)的方法,并使用它们来训练卷积神经网络[4], [5].

可视化每一种信号的声谱图。

FS = 300;图次要情节(2,1,1);PSPectrum(正常,FS,的谱图“TimeResolution”, 0.5)标题(“正常信号”次要情节(2,1,2);pspectrum (aFib fs,的谱图“TimeResolution”, 0.5)标题(“AFib信号”

因为此示例使用LSTM而不是CNN,所以要翻译方法是很重要,所以它适用于一维信号。时间频率(TF)矩提取频谱图的信息。每个时刻可以用作输入到LSTM的一维特征。

在时域中探索两个TF矩:

  • 瞬时频率(instfreq

  • 光谱熵(pentropy.

instfreq功能估计信号作为功率谱图的第一矩的时间相关频率。该功能使用时间窗口的短时傅里叶变换计算频谱图。在此示例中,该函数使用255个时间窗口。该功能的时间输出对应于时间窗口的中心。

可视化每一种信号的瞬时频率。

[instFreqA, tA] = instfreq (aFib fs);[instFreqN, tN] = instfreq(正常,fs);图次要情节(2,1,1);情节(tN, instFreqN)标题(“正常信号”)包含('时间(s)') ylabel (瞬时频率的次要情节(2,1,2);instFreqA情节(tA)标题(“AFib信号”)包含('时间(s)') ylabel (瞬时频率的

cellfun应用instfreq功能到训练和测试集的每个单元。

instfreqTrain = cellfun (@ (x) instfreq (x, fs), XTrain“UniformOutput”、假);instfreqTest = cellfun (@ (x) instfreq (x, fs), XTest“UniformOutput”、假);

谱熵测量信号的谱有多平坦。一个具有尖峰频谱的信号,就像一个正弦信号的和,具有低的谱熵。频谱平坦的信号,比如白噪声,具有高的频谱熵。的pentropy.函数根据功率谱图估计谱熵。与瞬时频率估计情况一样,pentropy.使用255个时间窗口来计算谱图。函数的时间输出对应于时间窗口的中心。

可视化每一种信号的谱熵。

[pentropyA, tA2] = pentropy (aFib fs);[pentropyN, tN2] = pentropy(正常,fs);图subplot(2,1,1) plot(tN2,pentropyN) title(“正常信号”) ylabel (“谱熵”) subplot(2,1,2) plot(tA2,pentropyA) title(“AFib信号”)包含('时间(s)') ylabel (“谱熵”

cellfun应用pentropy.功能到训练和测试集的每个单元。

pentropyTrain = cellfun (@ (x) pentropy (x, fs), XTrain“UniformOutput”、假);pentropyTest = cellfun (@ (x) pentropy (x, fs), XTest“UniformOutput”、假);

连接特性,使新的训练和测试集中的每个单元具有两个维度,或两个特性。

XTrain2 = cellfun (@ (x, y) (x, y), instfreqTrain, pentropyTrain,“UniformOutput”、假);XTest2 = cellfun (@ (x, y) (x, y), instfreqTest, pentropyTest,“UniformOutput”、假);

可视化新输入的格式。每个单元不再包含一个9000个样本长的信号;现在它包含两个255个样本长的特性。

XTrain2 (1:5)
ans =5×1个单元阵列{2×255 double} {2×255 double} {2×255 double} {2×255 double} {2×255 double}

标准化的数据

瞬时频率和谱熵的平均值相差几乎一个数量级。此外,瞬时频率均值可能过高,导致LSTM无法有效学习。当网络适合于均值大、取值范围大的数据时,大的输入会减慢网络的学习和收敛[6].

意思(instfreqn)
ans = 5.5615
意思是(pentropyN)
ans = 0.6326

使用训练集均值和标准偏差对训练集和测试集进行标准化。标准化,或z评分,是一种在训练中提高网络性能的流行方法。

十五= [XTrain2 {}):;μ=意味着(十五,2);sg =性病(十五,[],2);XTrainSD = XTrain2;XTrainSD = cellfun (@ (x)(即xμ)。/ sg, XTrainSD,“UniformOutput”、假);XTestSD = XTest2;XTestSD = cellfun (@ (x)(即xμ)。/ sg, XTestSD,“UniformOutput”、假);

显示了标准化瞬时频率和谱熵的方法。

instFreqNSD = XTrainSD {1} (1:);pentropyNSD = XTrainSD {1} (2:);意思是(instFreqNSD)
ans = -0.3211
平均值(Pentropynsd)
ans = -0.2416

修改LSTM网络结构

既然,每个信号都具有两个维度,所以必须通过指定输入序列大小来修改网络架构。指定具有100的输出大小的双向LSTM层,并输出序列的最后一个元素。通过包括一个完全连接的大小2层来指定两个类,然后是softmax层和分类层。

层= [...sequenceInputLayer (2) bilstmLayer (100“OutputMode”“最后一次”(2) softmaxLayer classificationLayer
图层= 5x1层阵列带图层:1''序列输入序列输入用2尺寸2''Bilstm Bilstm,具有100个隐藏单元3''完全连接的2完全连接的第4层''Softmax Softmax 5''分类输出CrossentRopyex

指定培训选项。设置最大纪元数为30,允许网络通过30次训练数据。

选项=培训选项(“亚当”...“MaxEpochs”30岁的...“MiniBatchSize”, 150,...“InitialLearnRate”, 0.01,...“GradientThreshold”, 1...“ExecutionEnvironment”“汽车”...“阴谋”“训练进步”...“详细”、假);

用时频特征训练LSTM网络

使用指定的训练选项和层架构对LSTM网络进行训练trainNetwork

net2 = trainnetwork(xtrainsd,ytrain,图层,选项);

训练的准确性有了很大的提高。交叉熵损失趋向于0。此外,由于TF矩比原始序列短,训练所需的时间也减少了。

可视化培训和测试准确性

使用更新后的LSTM网络对训练数据进行分类。将分类性能可视化为一个混淆矩阵。

trainPred2 =分类(net2 XTrainSD);LSTMAccuracy = sum(trainPred2 == YTrain)/numel(YTrain)*100
LSTMAccuracy = 83.5962
图confusionchart (YTrain trainPred2,'placeSummary'“column-normalized”...“RowSummary”“row-normalized”“标题”“LSTM混淆图”);

将测试数据与更新的网络进行分类。绘制混淆矩阵以检查测试的准确性。

testPred2 =分类(net2 XTestSD);LSTMAccuracy = sum(testPred2 == YTest)/numel(YTest)*100
LSTMAccuracy = 80.1020
图confusionchart(欧美、testPred2'placeSummary'“column-normalized”...“RowSummary”“row-normalized”“标题”“LSTM混淆图”);

结论

这个例子展示了如何使用LSTM网络构建分类器来检测心电信号中的心房颤动。该程序使用过采样,以避免在主要由健康患者组成的人群中检测异常情况时发生的分类偏差。使用原始信号数据对LSTM网络进行训练,分类精度较差。利用每个信号的两个时频矩特征对网络进行训练,显著地提高了分类性能,同时减少了训练时间。

参考文献

[1]基于短单导联心电图记录的心房颤动分类:物理网络/计算在心脏病学中的挑战,2017。https://physionet.org/challenge/2017/

[2] Clifford, Gari, Chengyu Liu, Benjamin Moody, Li-wei H. Lehman, Ikaro Silva, Qiao Li, Alistair Johnson, Roger G. Mark。基于单导联心电图记录的心房颤动分类:物理网络计算在心脏病学中的挑战2017计算在心脏病学(rennes:ieee)。卷。44,2017,pp。1-4。

[3] Goldberger,A.L.,L.A.A.NARAL,L.玻璃,J.M.Hausdorff,P. Ch。Ivanov,R.G.Mark,J.E.Mietus,G. B.Coody,C. -K。彭和H. E. Stanley。“Physiobank,PhysioToolkit和PhysioIoneet:复杂生理信号的新研究资源组件”。循环.第101卷,第23卷,2000年6月13日,页e215-e220。http://circ.ahajournals.org/content/101/23/e215.full

[4] Pons Jordi Thomas Lidy和Xavier Serra。“实验音乐驱动的卷积神经网络”。第十四届基于内容的多媒体索引国际研讨会.2016年6月。

[5]王,D。“深入学习重新发明助听器”IEEE频谱, Vol. 54, No. 3, 2017年3月,32-37页。doi: 10.1109 / MSPEC.2017.7864754。

[6] Brownlee,杰森。如何在Python中扩展长短期内存网络的数据.2017年7月7日。https://machinelearningmastery.com/how-to-scale-data-for-long-short-term-memory-networks-in-python/。

另请参阅

功能

相关的话题