主要内容

利用小波和深度学习在树莓派上部署信号分类器

这个例子展示了使用连续小波变换(CWT)和深度卷积神经网络(CNN)对人体心电图(ECG)信号进行分类的工作流程。这个例子还提供了关于如何在树莓派目标(基于ARM®的设备)上生成和部署用于预测的代码和CNN的信息。

SqueezeNet是一个深度CNN,最初设计用于将图片分类为1000个类别。在这个例子中用小波分析和深度学习对时间序列进行分类, SqueezeNet被重新训练来分类心电图波形基于他们量图.尺度图是信号的时频表示,是信号的CWT的绝对值。我们在本例中重用重新训练的SqueezeNet。

心电图数据描述

在本例中,ECG数据来自生理网使用。心电图数据来自三组人:心律失常(ARR)、充血性心力衰竭(CHF)和窦性心律正常(NSR)的人。数据集包括96个ARR患者的录音,30个CHF患者的录音,36个NSR患者的录音。这162个心电图记录来自三个PhysioNet数据库:MIT-BIH心律失常数据库[2] [3],MIT-BIH正常窦性节律数据库[3]充血性心力衰竭数据库[1][3]。上述参考资料的心电图简写资料可从GitHub库

先决条件

有关受支持的库版本和有关设置环境变量的信息,请参见用MATLAB编码器进行深度学习的先决条件(MATLAB编码器).此示例在MATLAB Online™中不受支持。

生成代码的功能

生成的可执行文件中的核心功能,processECG,使用65,536个单精度心电数据样本作为输入。功能:

  1. 取心电数据的CWT。

  2. 从小波系数中得到尺度图。

  3. 将尺度图转换为尺寸为227 × 227 × 3的RGB图像。这使得映像与SqueezeNet网络架构兼容。

  4. 使用SqueezeNet对图像进行分类预测。

类型processECG
function [YPred] = processECG(input) % processECG function -将1D ECG转换为图像,并预测心脏病的综合征% %此函数仅用于支持以下示例:%使用小波生成信号分类代码和%树莓派上的深度学习。它可能在%未来的版本中更改或删除。% Copyright 2020 The MathWorks, Inc. % colormap for image transformation persistent net jetdata;If (isempty(jetdata)) jetdata = colormap (128,class(input));如果(isempty(net)) net = code . loaddeeplearningnetwork ('trainedNet.mat');end %小波变换&图像转换cfs = ecg_to_Image(input);形象= ind2rgb (im2uint8(重新调节(cfs)),单(jetdata));形象= im2uint8 (imresize(形象,[227227]));%数字如果为空(code .target) imshow(图像);end %预测[YPred] =预测(网络,图像); %% ECG to image conversion function cfs = ecg_to_Image(input) %Wavelet Transformation persistent filterBank [~,siglen] = size(input); if isempty(filterBank) filterBank = cwtfilterbank('SignalLength',siglen,'VoicesPerOctave',6); end %CWT conversion cfs = abs(filterBank.wt(input)); end %% Colourmap function J = colourmap(m,class) n = ceil(m/4); u = [(1:1:n)/n ones(1,n-1) (n:-1:1)/n]'; g = ceil(n/2) - (mod(m,4)==1) + (1:length(u))'; r = g + n; b = g - n; r1 = r(r<=128); g1 = g(g<=128); b1 = b(b >0); J = zeros(m,3); J(r1,1) = u(1:length(r1)); J(g1,2) = u(1:length(g1)); J(b1,3) = u(end-length(b1)+1:end); feval = str2func(class); J = feval(J); end end

创建代码生成配置对象

为可执行程序的生成创建代码生成配置对象。指定c++代码的生成。

cfg = coder.config (exe”);cfg。TargetLang =“c++”

设置深度学习代码生成的配置对象

创建一个编码器。ARMNEONConfig对象。请指定与树莓派相同的ARM计算库版本。指定树莓派的架构。

dlcfg =编码器。DeepLearningConfig (“arm-compute”);dlcfg。ArmComputeVersion =“19.05”;dlcfg。ArmArchitecture =v7的

将深度学习配置对象附加到代码生成配置对象

设置DeepLearningConfig属性为深度学习配置对象的代码生成配置对象。在代码生成时,使MATLAB Source Comments在配置对象中可见。

cfg。DeepLearningConfig = dlcfg;cfg。MATLABSourceComments = 1;

创建到树莓派的连接

使用MATLAB支持包实现树莓派支持包功能,raspi,以创建到树莓派的连接。在以下代码中,替换:

  • raspiname与树莓派的名称或IP地址

  • 用户名用你的用户名

  • 密码用你的密码

r = raspi (“raspiname”“用户名”“密码”);

配置树莓派代码生成硬件参数

创建一个编码器。硬件对象,并将其附加到代码生成配置对象。

hw = coder.hardware (“树莓π”);cfg。硬件= hw;

指定树莓派上的构建文件夹。

buildDir =“~ / remdirECG”;cfg.Hardware.BuildDir = buildDir;

提供代码执行的c++主文件

c++主文件读取输入的心电数据,调用processECG函数,利用CNN对心电数据进行预处理和深度学习,并显示分类概率。

在代码生成配置对象中指定主文件。了解关于生成和自定义的更多信息main_ecg_raspi.cpp,请参考从MATLAB代码生成独立的C/ c++可执行程序(MATLAB编码器)

cfg。CustomSource =“main_ecg_raspi.cpp”

生成源c++代码使用codegen

使用codegen函数来生成c++代码。当codegen与树莓派硬件的MATLAB支持包一起使用,可执行程序构建在树莓派板上。

确保设置了环境变量ARM_COMPUTELIB而且LD_LIBRARY_PATH在树莓派上看到用MATLAB编码器进行深度学习的先决条件(MATLAB编码器)

codegen配置cfgprocessECGarg游戏{(1, 65536,“单”)}- darm_compute
部署代码。这可能需要几分钟。

获取生成的可执行目录

如果需要在树莓派上测试生成的代码,请将输入的心电信号复制到生成的代码目录中。方法可以手动或使用raspi.utils.getRemoteBuildDirectoryAPI。该函数列出使用生成的二进制文件的目录codegen

applicationDirPaths = raspi.utils.getRemoteBuildDirectory (“applicationName”“processECG”
applicationDirPaths =1×4单元阵列{1×1 struct} {1×1 struct} {1×1 struct} {1×1 struct}

远程构建目录的完整路径是从当前工作目录派生出来的。如果你不知道是哪个applicationDirPaths条目包含生成的代码,使用助手函数helperFindTargetDir.否则,请指定正确的目录。

directoryUnknown = true;如果directoryUnknown targetDirPath = helperFindTargetDir(applicationDirPaths);其他的targetDirPath = applicationDirPaths {1} .directory;结束

复制输入文件到树莓派

的文本文件input_ecg_raspi.csv包含有代表性的ARR信号的心电图样本。要复制运行可执行程序所需的文件,请使用putFile,它可与树莓派硬件的MATLAB支持包一起使用。

r.putFile (“input_ecg_raspi.csv”, targetDirPath);

对于图形表示,可以使用这些步骤绘制前1000个样本。

输入= dlmread (“input_ecg_raspi.csv”);情节(输入(1:1000))标题(“ARR信号”

在树莓派上运行可执行文件

在MATLAB中运行树莓派上的可执行程序,并将输出直接返回到MATLAB。输入文件名作为可执行文件的命令行参数传递。

exeName =“processECG.elf”%可执行文件的名字文件名=“input_ecg_raspi.csv”%输入被推到目标的心电图文件命令= [“cd”targetDirPath“。/”exeName' '文件名);输出=系统(r,命令)
output = '目标硬件ARR CHF NSR上的预测值0.806078 0.193609 0.000313103 '

参考文献

  1. 拜姆、D. S.、W. S.科鲁奇、E. S.蒙拉德、H. S.史密斯、R. F.赖特、A.拉努、D. F.戈捷、B. J.兰希尔、W.格罗斯曼和E.布劳沃尔德。口服米力农治疗严重充血性心力衰竭患者的生存率美国心脏病学会杂志.1986年第7卷第3期,第661-670页。

  2. 戈德伯格、l.a.n.阿马拉尔、l.g lass、j.m.豪斯多夫、p.ch Ivanov、r.g. Mark、j.e.m ietus、g.b. Moody、c.k.。彭和h·e·斯坦利。PhysioBank, PhysioToolkit和PhysioNet:复杂生理信号新研究资源的组成部分。循环。第101卷第23期:e215-e220。(循环电子页;http://circ.ahajournals.org/content/101/23/e215.full];2000(6月13日)。cir.101.23.e215 doi: 10.1161/01.。

  3. 穆迪,G. B.和R. G.马克。“麻省理工-波黑心律失常数据库的影响。”IEEE医学和生物学工程杂志.20卷。第三期,2001年5月至6月,第45-50页。(PMID: 11446209)

支持功能

helperFindTargetDir

函数targetDir = helperFindTargetDir (dirPaths)此函数仅用于支持小波深度学习示例。它可能会在未来的版本中更改或删除。。%找到pwdp = pwd;如果ispc%用下划线替换空格p = strrep (p,' '“_”);%分割路径到组件文件夹pSplit = regexp (p filesep“分裂”);%因为Windows使用冒号,请删除出现的任何冒号k=1:numel(pSplit) pSplit{k} = erase(pSplit{k},“:”);结束%现在使用Linux文件分离构建路径pLinux =k=1:numel(pSplit)-1 pLinux = [pLinux,pSplit{k},' / '];结束pLinux = [pLinux pSplit{结束});其他的pLinux = p;结束targetDir =k=1:numel(dirPaths) d = strfind(dirPaths{k}.directory,pLinux);如果~isempty(d) targetDir = dirPaths{k}.directory;打破结束结束如果numel(targetDir) == 0“目标目录未找到。”);结束结束

另请参阅

相关的话题

Baidu
map