此示例演示如何使用深度学习和信号处理对PhysioNet 2017挑战赛中的心跳心电图(ECG)数据进行分类。特别是,此示例使用长-短记忆网络和时频分析。
心电图记录一段时间内一个人心脏的电活动。医生使用心电图目视检测患者的心跳是否正常或不规则。
心房颤动(AFib)是一种不规则的心跳,当心脏的上腔(心房)与下腔(心室)不协调时发生。
本例使用来自PhysioNet 2017挑战赛的ECG数据[1.], [2.], [3.],可于https://physionet.org/challenge/2017/.该数据由一组在300赫兹取样并通过一个专家小组分成四个不同的类ECG信号中的:正常(N),AFIB(A),其他的节奏(O),和噪声录音(〜)。这个例子说明了如何使用深度学习自动分类过程。的程序探索二元分类器,可以从示出AFIB的迹象信号区分正常ECG信号。
此示例使用长短时记忆(LSTM)网络,这是一种非常适合研究序列和时间序列数据的递归神经网络(RNN)。LSTM网络可以学习序列时间步长之间的长期相关性。LSTM层(lstmLayer
(深度学习工具箱))可以向前看时间序列,而双向LSTM层(bilstmLayer
(深度学习工具箱))可以看看在向前和向后方向的时间序列。这个例子使用一个双向LSTM层。
要加快培训过程,请在具有GPU的计算机上运行此示例。如果您的计算机具有GPU和并行计算工具箱™, 然后MATLAB®自动使用GPU进行训练;否则,它将使用CPU。
运行读取物理网络数据
从PhysioNet网站下载数据并生成MAT文件的脚本(PhysionetData.mat
),其包含在适当的格式的ECG信号。下载数据可能需要几分钟的时间。使用运行该脚本只有一个条件语句PhysionetData.mat
当前文件夹中不存在。
如果~isfile(“PhysionetData.mat”)读取物理网络数据终止负载生理数据
加载操作将向工作区添加两个变量:信号
和标签
.信号
是一种储存ECG信号的细胞阵列。标签
是保存的信号的对应的地面实况标签一个分类数组。
信号(1:5)
ans=5×1单元阵列{1×9000双}{1×9000双}{1×18000双}{1×9000双}{1×18000双}
标签(1:5)
ans=5×1分类N N A
使用总结
函数查看数据中包含多少AFib信号和正常信号。
摘要(标签)
A 738 N 5050
生成信号长度的直方图。大多数信号都有9000个样本长。
L=cellfun(@length,Signals);h=histogram(L);xticks(0:3000:18000);xticklabels(0:3000:18000);标题(“信号长度”)xlabel('长度')ylabel(“伯爵”)
将每个类别的一个信号片段可视化。AFib心跳间隔不规则,而正常心跳有规律地出现。AFib心跳信号也通常缺少P波,在正常心跳信号中,P波在QRS波群之前脉冲。正常信号的曲线图显示P波和QRS波群。
正常=信号{1};AFIB =信号{4};副区(2,1,1)图(正常)称号(“正常节奏”)XLIM([4000,5200])ylabel(‘振幅(mV)’)文本(4330,150,“P”,'水平对齐',“中心”)文本(4370,850,“QRS”,'水平对齐',“中心”)子地块(2,1,2)地块(aFib)名称(“心房颤动”)xlim([40005200])xlabel(“样品”)ylabel(‘振幅(mV)’)
在培训期间列车网络
函数将数据拆分为小批量。然后,该函数在同一个小批量中填充或截断信号,使它们具有相同的长度。过多的填充或截断可能会对网络性能产生负面影响,因为网络可能会根据添加或删除的信息错误地解释信号。
为避免过度填充或截断,请应用segmentSignals
ECG信号的函数,因此它们都有9000个样本长。该函数忽略采样数少于9000的信号。如果一个信号有9000多个样本,segmentSignals
将其拆分为尽可能多的9000个采样段,并忽略剩余的采样。例如,具有18500个样本的信号变为两个9000个样本信号,其余500个样本将被忽略。
[信号,标签]=分段信号(信号,标签);
查看文档的前五个元素信号
数组来验证每个条目现在是否有9000个样本长。
信号(1:5)
ans=5×1单元阵列{1×9000双精度}{1×9000双精度}{1×9000双精度}{1×9000双精度}{1×9000双精度}
为了设计分类器,使用上一节中产生的原始信号。拆分信号转换成训练集训练分类和测试集来测试新的数据分类的准确性。
使用总结
函数显示AFib信号与正常信号的比率为718:4937,或约为1:7。
摘要(标签)
A 718 N 4937
因为大约有7/8的信号是正常的,所以分类器会发现,只要将所有信号分类为正常信号,就可以实现高精度。为了避免这种偏差,可以通过复制数据集中的AFib信号来增加AFib数据,以便有相同数量的正常和AFib信号。这种复制通常称为过采样,是深度学习中使用的一种数据扩充形式。
根据信号的类别来划分。
afibX=信号(标签=='一种');afibY=标签(标签=='一种');normalX =信号(标签==“不”);= = =饱和标签(标签“不”);
接下来,使用分割
将每个班级的目标随机划分为训练集和测试集。
[trainIndA,~,testIndA]=dividerand(718,0.9,0.0,0.1);[trainIndN,~,testIndN]=dividerand(4937,0.9,0.0,0.1);XTrainA=afibX(trainIndA);YTrainA=afibY(trainIndA);XTrainN=normalX(trainIndN);YTrainN=normalY(trainIndN);xteststa=afibX(testIndA);ytistta=afibY(testIndN);stn=normalY(testIndN);
现在有646个AFib信号和4443个正常信号用于训练。为了在每个类中获得相同数量的信号,请使用前4438个正常信号,然后使用repmat
重复前634个AFib信号七次。
对于测试,有72个AFib信号和494个正常信号。使用前490个正常信号,然后使用repmat
重复前70个AFIB信号七次。默认情况下,神经网络随机训练前慢腾腾的数据,确保连续的信号并不都具有相同的标签。
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)];YTest=[repmat(YTestA(YTestA(1:70),7,1);YTestN(1:490);];
在训练集中和测试集中,Normal和AFib信号之间的分布现在是均匀平衡的。
摘要(YTrain)
A 4438 N 4438
摘要(YTest)
A 490 N 490
LSTM网络可以学习序列数据的时间步长之间的长期依赖。此示例使用双向LSTM层bilstmLayer
,因为它看起来在向前和向后方向的顺序。
因为每个输入信号都有一个维度,所以将输入大小指定为大小为1的序列。指定输出大小为100的双向LSTM层,并输出序列的最后一个元素。此命令指示双向LSTM层将输入时间序列映射为100个特征,然后为完整的输入准备输出连接层。最后,通过包括大小为2的完全连接层,然后是softmax层和分类层来指定两个类。
层= [......sequenceInputLayer(1)bilstmLayer(100,“输出模式”,“最后”)fullyConnectedLayer(2)softmaxLayer classificationLayer]
layers=5x1带层的层阵列:1''序列输入序列输入1维2''BiLSTM BiLSTM带100个隐藏单元3''完全连接2''完全连接层4''Softmax Softmax 5''分类输出crossentropyex
接下来指定分类培训选项。设置'maxepochs'
到10,以允许网络通过训练数据进行10次。A“MiniBatchSize”
of 150指示网络一次查看150个训练信号“初始学习率”
0.01有助于加快培训过程。指定一个“SequenceLength”
1000,将信号分成更小的部分,这样机器不会因为一次查看太多数据而耗尽内存。设置'GradientThreshold
'为1,以防止梯度变得过大,从而稳定训练过程。指定“情节”
像'培训 - 进步'
生成随着迭代次数增加而显示训练进度的图形。集“冗长”
到错误的
抑制与绘图中显示的数据对应的表格输出。如果要查看此表,请设置“冗长”
到符合事实的
.
本例使用自适应矩估计(ADAM)解算器。ADAM执行与像LSTMs比动量(SGDM)求解器的默认随机梯度下降RNNs更好。
选项=培训选项(“亚当”,......'maxepochs'10,......“MiniBatchSize”,150,......“初始学习率”,0.01%,......“SequenceLength”,1000,......“梯度阈值”1.......“执行环境”,“自动”,......“阴谋”,'培训 - 进步',......“冗长”,错误的);
使用指定的培训选项和层架构培训LSTM网络列车网络
.由于训练集很大,训练过程可能需要几分钟。
网= trainNetwork (XTrain、YTrain层,选择);
培训进度图的顶部子批次表示培训精度,即每个小批次的分类精度。当培训成功进行时,该值通常会增加到100%。底部子批次显示培训损失,即每个小批次的交叉熵损失。当培训成功进行时不幸的是,该值通常会朝着零的方向减小。
如果训练不收敛,图可能会在值之间振荡,而不会朝着某个向上或向下的方向。这种振荡意味着训练精度没有提高,训练损失没有减少。这种情况可能在训练开始时就出现,或者在训练准确性初步提高后,情节可能会趋于平稳。在许多情况下,改变训练选项可以帮助网络实现收敛。减少小批量
或减少初始学习率
可能会导致更长的培训时间,但它可以帮助网络更好地学习。
分类器的训练精度在大约50%到大约60%之间波动,在10个时代结束时,训练已经花费了几分钟。
计算训练精度,该精度表示分类器对训练信号的精度。首先,对训练数据进行分类。
trainPred=分类(净、XTrain、,“SequenceLength”,1000);
在分类问题中,混淆矩阵用于可视化分类器在一组已知真值的数据上的性能。目标类是信号的基本真值标签,输出类是网络分配给信号的标签。轴标签表示类标签AFib(a)正常(N)。
使用confusionchart
命令来计算测试数据的预测总体分类准确度。指定“行摘要”
像“row-normalized”
在行汇总中显示真实阳性率和假阳性率。同时,指定“专栏摘要”
像“列规格化”
在列摘要中显示阳性预测值和错误发现率。
LSTMAccuracy=sum(trainPred==YTrain)/numel(YTrain)*100
LSTMAccuracy = 61.7283
图2:混乱图(YTrain、trainPred、,“专栏摘要”,“列规格化”,......“行摘要”,“row-normalized”,“标题”,“LSTM的混淆图”);
现在使用相同的网络对测试数据进行分类。
testPred=分类(净、XTest、,“SequenceLength”,1000);
计算测试精度和可视化的分类性能作为一个混淆矩阵。
LSTMAccuracy=sum(testPred==YTest)/numel(YTest)*100
LSTMAccuracy = 66.2245
图2:混淆图(YTest、testPred、,“专栏摘要”,“列规格化”,......“行摘要”,“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矩:
瞬时频率(英斯特弗尔
)
谱熵(戊酸
)
这个英斯特弗尔
函数将信号的时间相关频率估计为功率谱图的第一个矩。函数使用时间窗口上的短时傅里叶变换计算谱图。在本例中,函数使用255个时间窗口。函数的时间输出对应于时间窗口的中心。
可视化每一种信号的瞬时频率。
[instreqa,tA]=instreq(aFib,fs);[instreqn,tN]=instreq(normal,fs);地物子地块(2,1,1);地块(tN,instreqn)标题(“正常信号”)xlabel(‘时间’)ylabel(“瞬时频率”)副区(2,1,2);图(TA,instFreqA)称号(“AFib信号”)xlabel(‘时间’)ylabel(“瞬时频率”)
使用cellfun
应用英斯特弗尔
功能在训练和测试集的每一个细胞。
instfreqTrain=cellfun(@(x)instfreq(x,fs)'),XTrain,'UniformOutput',false);instfreqTest=cellfun(@(x)instfreq(x,fs)'),XTest,'UniformOutput',错误的);
谱熵测量信号的谱有多平坦。一个具有尖峰频谱的信号,就像一个正弦信号的和,具有低的谱熵。频谱平坦的信号,比如白噪声,具有高的频谱熵。这个戊酸
函数根据功率谱图估计谱熵。与瞬时频率估计情况一样,戊酸
使用255个时间窗口计算频谱图。函数的时间输出对应于时间窗口的中心。
可视化每种类型信号的光谱熵。
[pentropyA,tA2]=pentropy(aFib,fs);[戊丙炔,tN2]=戊丙炔(正常,fs);图子地块(2,1,1)图(tN2,戊丙炔)标题(“正常信号”)ylabel(“光谱熵”)副区(2,1,2)图(TA2,pentropyA)称号(“AFib信号”)xlabel(‘时间’)ylabel(“光谱熵”)
使用cellfun
应用戊酸
功能在训练和测试集的每一个细胞。
pentropyTrain=cellfun(@(x)pentropy(x,fs)”,XTrain,'UniformOutput',假);pentropyTest=cellfun(@(x)pentropy(x,fs)”,XTest,'UniformOutput',错误的);
拼接的特征,使得在新的训练和测试集每个单元有两个维度,或两个功能。
XTrain2=cellfun(@(x,y)[x;y],instreqtrain,pentropyTrain,'UniformOutput',错误的);XTest2 = cellfun(@(X,Y)[X; Y],instfreqTest,pentropyTest,'UniformOutput',错误的);
可视化新输入的格式。每个单元格不再包含一个9000样本长的信号;现在它包含两个255样本长的特征。
XTrain2(1:5)
ans=5×1单元阵列{2×255双} {2×255双} {2×255双} {2×255双} {2×255}双
瞬时频率和频谱熵具有装置,其由几乎一个数量级的差异。此外,对于LSTM有效地学习瞬时频率均值可能太高。当网络是适合于数据具有大的平均和大的值的范围,大的投入可以在网络的学习和收敛[减缓6.].
平均值(单位:N)
ans=5.5615
平均值(戊丙炔)
ans=0.6326
使用训练集均值和标准偏差对训练集和测试集进行标准化。标准化,或z评分,是一种在训练中提高网络性能的流行方法。
XV=[XTrain2{:}];mu=均值(XV,2);sg=std(XV,[],2);XTrainSD=XTrain2;XTrainSD=cellfun(@(x)(x-mu)。/sg,XTrainSD,'UniformOutput',错误的);XTestSD = XTest2;XTestSD = cellfun(@(X)(X-MU)./ SG,XTestSD,'UniformOutput',错误的);
示出了标准化的瞬时频率和频谱熵的手段。
instFreqNSD = XTrainSD {1} (1:);pentropyNSD = XTrainSD {1} (2:);意思是(instFreqNSD)
ans=-0.3211
平均值(pentropyNSD)
ANS = -0.2416
既然每个信号都有两个维度,那么有必要通过将输入序列大小指定为2来修改网络架构。指定输出大小为100的双向LSTM层,并输出序列的最后一个元素。通过包含大小为2的完全连接层,然后是softmax层和分类层,指定两个类别。
层= [......sequenceInputLayer(2)bilstmLayer(100,“输出模式”,“最后”)fullyConnectedLayer(2)softmaxLayer classificationLayer]
layers=5x1层阵列和层:1''序列输入序列输入2维2''BiLSTM BiLSTM带100个隐藏单元3''完全连接2''完全连接层4''Softmax Softmax 5''分类输出crossentropyex
指定训练选项。将最大历元数设置为30,以允许网络通过训练数据30次。
选项=培训选项(“亚当”,......'maxepochs'30,......“MiniBatchSize”,150,......“初始学习率”,0.01%,......“梯度阈值”1.......“执行环境”,“自动”,......“阴谋”,'培训 - 进步',......“冗长”,错误的);
使用指定的培训选项和层架构培训LSTM网络列车网络
.
net2=列车网络(XTrainSD、YTrain、图层、选项);
有一个在训练精度有很大的改进。向0交叉熵损失的趋势。此外,训练所需的时间降低,因为TF时刻是比原始序列短。
使用更新后的LSTM网络对训练数据进行分类。将分类性能可视化为一个混淆矩阵。
trainPred2=分类(net2,XTrainSD);LSTMAccuracy=总和(trainPred2==YTrain)/numel(YTrain)*100
LSTMAccuracy = 83.5962
图2混乱图(YTrain,trainPred2,“专栏摘要”,“列规格化”,......“行摘要”,“row-normalized”,“标题”,“LSTM的混淆图”);
将测试数据与更新的网络进行分类。绘制混淆矩阵以检查测试的准确性。
testPred2 =分类(net2 XTestSD);LSTMAccuracy = sum(testPred2 == YTest)/numel(YTest)*100
LSTMAccuracy=80.1020
图2:混淆图(YTest、testPred2、,“专栏摘要”,“列规格化”,......“行摘要”,“row-normalized”,“标题”,“LSTM的混淆图”);
此示例示出了如何建立一个分类器检测在使用LSTM网络ECG信号房颤。该过程使用过采样,以避免当一个人试图检测主要的健康患者组成种群异常情况发生的分类偏压。在一个贫穷的分类准确使用原始信号数据结果培训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年心脏病学挑战赛中的生理网络计算。”在计算心脏病(雷恩:IEEE),2017年第44卷,第1-4页。
[3] Goldberger,A.L.,L.A.N.Amaral,L.Glass,J.M.Hausdorff,P.C.Ivanov,R.G.Mark,J.E.Mietus,G.B.Moody,C.-K.Peng和H.E.Stanley.“生理银行,生理工具包和生理网:复杂生理信号新研究资源的组成部分”。循环.第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] 深度学习重塑了助听器IEEE综览,卷。54,第3号,2017年3月,第32-37。DOI:10.1109 / MSPEC.2017.7864754。
[6]布朗利,杰森。如何扩大数据对于长短期记忆网络在Python.2017年7月7日。https://machinelearningmastery.com/how-to-scale-data-for-long-short-term-memory-networks-in-python/.