主要内容

树莓派噪声代码生成中的关键字识别

这个例子演示了在树莓派™上使用双向长短期记忆(BiLSTM)网络和mel频率倒谱系数(MFCC)特征提取来生成关键字发现的代码。带有深度学习支持的MATLAB®Coder™能够在树莓派上生成独立的可执行文件(.elf)。MATLAB®(.mlx)文件和生成的可执行文件之间的通信通过异步用户数据报协议(UDP)进行。输入的语音信号使用timescope.掩码显示为围绕关键字YES的斑点实例的蓝色矩形。更多关于MFCC特征提取和深度学习网络训练的细节,请访问基于MFCC和LSTM网络的噪声关键字发现(音频工具箱)

例子要求

  • 深度学习支持包的MATLAB®编码器接口

  • 支持NEON扩展的ARM处理器

  • ARM计算库版本20.02.1(在目标ARM硬件上)

  • 编译器和库的环境变量

有关受支持的库版本和有关设置环境变量的信息,请参见用MATLAB编码器进行深度学习的先决条件(MATLAB编码器)

使用MATLAB®预训练网络关键字发现和麦克风流音频

预训练网络的抽样率为16kHz。将窗口长度设置为512样本,重叠长度为384样本,以及定义为窗口长度和重叠长度之差的跳长度。定义估计掩码的速率。每生成一个掩码numHopsPerUpdate音频帧。

Fs = 16e3;windowLength = 512;overlapLength = 384;hopLength = windowLength - overlapLength;numHopsPerUpdate = 16;maskLength = hopLength * numHopsPerUpdate;

创建一个audioFeatureExtractor(音频工具箱)对象执行MFCC特征提取。

afe = audioFeatureExtractor(“SampleRate”fs,...“窗口”损害(windowLength“周期”),...“OverlapLength”overlapLength,...“mfcc”,真的,...“mfccDelta”,真的,...“mfccDeltaDelta”,真正的);

下载并加载预训练的网络,以及平均值()和标准差(年代)用于特征标准化的向量。

url =“http://ssd.mathworks.com/supportfiles/audio/KeywordSpotting.zip”;downloadNetFolder =“。/”;netFolder = fullfile(downloadNetFolder,“KeywordSpotting”);如果~存在(netFolder“dir”) disp (下载预先训练的网络和音频文件(4个文件- 7mb)…解压缩(url, downloadNetFolder)结束负载(fullfile (netFolder“KWSNet.mat”),“KWSNet”“M”“S”);

调用generateMATLABFunction(音频工具箱)audioFeatureExtractor(音频工具箱)对象创建特征提取函数。

generateMATLABFunction (afe“generateKeywordFeatures”“IsStreaming”,真正的);

定义一个音频设备阅读器(音频工具箱)系统对象™从您的麦克风读取音频。设置帧长度等于跳长度。这样就可以为从麦克风接收到的每一个新的音频帧计算一组新的特征。

frameLength = hopLength;adr = audioDeviceReader(“SampleRate”fs,...“SamplesPerFrame”frameLength,“OutputDataType”“单一”);

创建一个时间范围(DSP系统工具箱)可视化语音信号和估计掩码。

Scope = timescope(“SampleRate”fs,...“TimeSpanSource”“属性”...“时间间隔”5,...“TimeSpanOverrunAction”“滚动”...“BufferLength”fs * 5 * 2,...“ShowLegend”,真的,...“ChannelNames”, {“演讲”“关键词面具”},...“YLimits”(-1.2 - 1.2),...“标题”关键字定位的);

初始化一个用于音频数据的缓冲区,一个用于计算特征的缓冲区,以及一个用于绘制输入音频和输出语音掩码的缓冲区。

dataBuff = dsp.AsyncBuffer(windowLength);featureBuff = dsp.AsyncBuffer(numHopsPerUpdate);plotBuff = dsp.AsyncBuffer(numHopsPerUpdate*windowLength);

对从麦克风接收到的语音执行关键字识别。要无限地运行循环,请设置期限.若要停止模拟,请关闭范围

显示(范围);timeLimit = 20;抽搐toc < timeLimit && isVisible(scope) data = adr();写(dataBuff、数据);写(plotBuff、数据);frame = read(dataBuff,windowLength,overlapLength);features = generateKeywordFeatures(frame,fs);写(featureBuff特性。');如果featureBuff。NumUnreadSamples == numHopsPerUpdate featureMatrix = read(featureBuff);featureMatrix(~isfinite(featureMatrix)) = 0;featureMatrix = (featureMatrix - M)./S;[keywordNet,v] = classifyAndUpdateState(KWSNet,featureMatrix.');V = double(V) - 1;v = repmat(v,hopLength,1);V = V (:);V =模(V);v = repmat(v,numHopsPerUpdate * hopLength,1); data = read(plotBuff); scope([data,v]); drawnowlimitrate结束结束隐藏(范围)

helperKeywordSpottingRaspi支持函数封装了先前演示的特征提取和网络预测过程。为了使特征提取与代码生成兼容,特征提取由生成的代码处理generateKeywordFeatures函数。为使网络与代码生成兼容,支持函数使用coder.loadDeepLearningNetwork(MATLAB编码器)函数加载网络。

辅助函数使用adsp。UDPReceiver(DSP系统工具箱)系统对象从MATLAB®接收捕获的音频,并使用dsp。UDPSender(DSP系统工具箱)系统对象将输入语音信号连同网络预测的估计掩码发送到MATLAB®。类似地,MATLAB®实时脚本使用dsp。UDPSender(DSP系统工具箱)系统对象,将捕获的语音信号发送到运行在树莓派上的可执行程序dsp。UDPReceiver(DSP系统工具箱)接收树莓派发出的语音信号和估计掩码的系统对象。

在树莓派上生成可执行文件

取代hostIPAddress加上你的机器地址。树莓派将输入语音信号和估计掩码发送到指定的IP地址。

hostIPAddress = coder。常数(“172.18.230.30”);

创建代码生成配置对象以生成可执行程序。指定目标语言为c++。

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

使用树莓派上的ARM计算库创建一个用于深度学习代码生成的配置对象。指定树莓派的体系结构,将深度学习配置对象附加到代码生成配置对象上。

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

使用树莓派支持包功能,raspi,以建立与树莓派的连接。在以下代码中,替换:

  • raspiname加上树莓派的名字

  • π用你的用户名

  • 密码使用密码

R = raspi(“raspiname”“π”“密码”);

创建一个coder.hardware(MATLAB编码器)对象,并将其附加到代码生成配置对象。

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

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

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

生成生成独立可执行文件所需的c++主文件。

cfg。GenerateExampleMain =“GenerateCodeAndCompile”

生成c++代码helperKeywordSpottingRaspi在树莓派上。

codegen配置cfghelperKeywordSpottingRaspiarg游戏{hostIPAddress}报告
部署代码。这可能需要几分钟。警告:函数'helperKeywordSpottingRaspi'不会因为无限循环而终止。警告在==> helperKeywordSpottingRaspi行:78列:1代码生成成功(带有警告):查看报告

使用部署的代码执行关键字发现

创建一个命令来打开helperKeywordSpottingRaspi应用在树莓派上。使用系统将命令发送到树莓派。

applicationName =“helperKeywordSpottingRaspi”;applicationDirPaths = raspi.utils.getRemoteBuildDirectory(“applicationName”applicationName);targetDirPath = applicationDirPaths{1}.directory;exeName = strcat(applicationName,“.elf”);命令= [“cd”targetDirPath,”;。/”exeName,' &> 1 &'];系统(r,命令);

创建一个dsp。UDPSender(DSP系统工具箱)将在MATLAB®中捕获的音频发送到树莓派的系统对象。更新targetIPAddress你的树莓派树莓派从相同的端口接收捕获的音频使用dsp。UDPReceiver(DSP系统工具箱)系统对象。

targetIPAddress =“172.18.231.92”;UDPSend = dsp。UDPSender (“RemoteIPPort”, 26000,“RemoteIPAddress”, targetIPAddress);

创建一个dsp。UDPReceiver(DSP系统工具箱)系统对象从树莓派接收语音数据和预测的语音掩码。树莓派接收到的每一个UDP报文由maskLength面具和语音样本。的最大消息长度dsp。UDPReceiver(DSP系统工具箱)对象是65507字节。计算缓冲区大小以容纳UDP报文的最大数量。

sizeOfFloatInBytes = 4;speakhdatalength = maskLength;numElementsPerUDPPacket = maskLength + speechDataLength;maxUDPMessageLength = floor(65507/sizeOfFloatInBytes);numPackets = floor(maxUDPMessageLength/numElementsPerUDPPacket);bufferSize = numPackets*numElementsPerUDPPacket*sizeOfFloatInBytes;UDPReceive = dsp。UDPReceiver (“LocalIPPort”, 21000,...“MessageDataType”“单身”...“MaximumMessageLength”1 + numElementsPerUDPPacket,...“下面的”bufferSize);

只要时间范围是开放的,或者直到达到时间限制,就可以发现关键字。如果要在达到时间限制之前停止实时检测,请关闭时间范围。

抽搐;显示(范围);时间限制= 20;toc < timelimit && isVisible(scope) x = adr();UDPSend (x);data = UDPReceive();如果~isempty(data) mask = data(1:maskLength);dataForPlot = data(maskLength + 1: numElementsPerUDPPacket);范围([dataForPlot、面具]);结束drawnowlimitrate结束

释放系统对象并终止独立的可执行文件。

hide(scope) release(UDPSend) release(UDPReceive) release(scope) release(adr) stopExecutable(codertarget.raspi.raspberrypi,exeName)

使用可选的PIL功能工作流评估执行时间

要评估树莓派上独立可执行文件所占用的执行时间,可以使用PIL(循环中处理器)工作流。要执行PIL分析,为支持函数生成一个PIL函数profileKeywordSpotting.的profileKeywordSpotting等于helperKeywordSpottingRaspi,只是前者返回语音和预测语音掩码,后者使用UDP发送相同的参数。UDP调用的时间小于1毫秒,与总体执行时间相比相对较小。

创建一个代码生成配置对象来生成PIL函数。

CFG = code .config(“自由”“是”,真正的);cfg。VerificationMode =“公益诉讼”

设置ARM计算库和架构。

DLCFG =编码器。DeepLearningConfig (“arm-compute”);cfg。DeepLearningConfig = dlcfg;cfg.DeepLearningConfig.ArmArchitecture =v7的;cfg.DeepLearningConfig.ArmComputeVersion =“20.02.1”

设置与目标硬件的连接。

如果(~ (“r”“var”) r = raspi(“raspiname”“π”“密码”);结束Hw = code .hardware(“树莓π”);cfg。硬件= hw;

设置生成目录和目标语言。

buildDir =“~ / remoteBuildDir”;cfg.Hardware.BuildDir = buildDir;cfg。TargetLang =“c++”

启用分析并生成PIL代码。MEX文件名为profileKeywordSpotting_pil在当前文件夹中生成。

cfg。CodeExecutionProfiling = true;codegen配置cfgprofileKeywordSpottingarg游戏{pinknoise (hopLength 1 '单')}报告
部署代码。这可能需要几分钟。生成的精灵的位置:/home/ Pi / remotebuilddir /MATLAB_ws/R2022a/W/Ex/ExampleManager/ sporwall . bdoc22a。j1844576/deeplearning_shared-ex18742368/codegen/lib/profileKeywordSpotting/pil Code generation successful:查看报告

评估树莓派的执行时间

多次调用生成的PIL函数以获得平均执行时间。

numPredictCalls = 10;totalCalls = numHopsPerUpdate * numPredictCalls;x = pinknoise(hopLength,1,“单一”);k = 1:totalCalls [maskReceived,inputSignal,plotFlag] = profileKeywordSpotting_pil(x);结束
##启动应用程序:'codegen\lib\profileKeywordSpotting\pil\profileKeywordSpotting. 'elf'终止执行:clear profileKeywordSpotting_pil ###正在启动应用程序profilekeywordspot .elf…可以查看执行分析数据。打开模拟数据检查器。终止后可获得执行分析报告。

终止PIL的执行。

清晰的profileKeywordSpotting_pil
###主机应用程序产生以下标准输出(stdout)和标准错误(stderr)消息:

生成一个执行概要报告,以评估执行时间。

executionProfile = getCoderExecutionProfile(“profileKeywordSpotting”);报告(executionProfile,...“单位”“秒”...“ScaleFactor”“1 e 03”...“NumericFormat”' % 0.4 f '
ans = 'W:\Ex\ExampleManager\ sporwall . bdoc22a .j1844576\deeplearning_share -ex18742368\codegen\lib\profileKeywordSpotting\html\ orphated \ExecutionProfiling_d43d66431b443d29.html'

根据生成的报告绘制每一帧的执行时间。

由于初始化开销,第一帧的处理花费了大约20毫秒。时间图中每16帧的峰值(numHopsPerUpdate)对应于计算密集的预测函数称为每16帧。最大执行时间为~30毫秒,低于实时流的128毫秒预算。性能是在树莓派4 Model B Rev 1.1上测量的。

Baidu
map