主要内容

树莓派语音指令识别代码的生成

这个例子展示了如何使用特征提取和卷积神经网络(CNN)对树莓派™进行语音命令识别。为了生成特征提取和网络代码,您使用MATLAB Coder, MATLAB支持包树莓派硬件,和ARM®计算库。金宝app在本例中,生成的代码是Raspberry Pi上的可执行文件,它由一个MATLAB脚本调用,该脚本显示预测的语音命令以及信号和听觉声谱图。MATLAB脚本和树莓派上的可执行文件之间的交互是使用用户数据报协议(UDP)处理的。关于音频预处理和网络培训的详细信息请参见使用深度学习的言语命令识别

先决条件

  • 支持NEON扩展的ARM处理器金宝app

  • ARM Compute库版本19.05(在目标臂硬件上)

  • 编译器和库的环境变量

有关设置金宝app环境变量的支持版本,请参阅深度学习与MATLAB编码器的先决条件(MATLAB编码器)

在matlab中的媒体演示

使用相同的参数进行特征提取管道和分类使用深度学习的言语命令识别

定义与网络训练相同的采样率(16khz)。定义分类率和每帧输入音频样本的数量。输入到网络的特征是对应1秒音频数据的Bark声谱图。计算了25 ms窗口和10 ms跳数的Bark谱图。计算每个谱图中单个光谱的数量。

fs = 16000;classificationRate = 20;samplesPerCapture = fs / classificationRate;segmentDuration = 1;segmentSamples =圆(segmentDuration * fs);frameDuration = 0.025;frameSamples =圆(frameDuration * fs);hopDuration = 0.010;hopSamples =圆(hopDuration * fs);numSpectrumPerSpectrogram = floor((segmentsamples - framessamples)/hopSamples) + 1;

创建一个audioFeatureExtractor对象提取50带Bark谱图,无需窗口标准化。计算每个频谱图中的元素数。

AFE = audiofeatureextractor(...“采样器”fs,...“FFTLength”,512,...“窗口”,汉恩(框架,'定期'),...“重叠长度”frameSamples - hopSamples...'Barkspectrum',真正的);numbands = 50;setExtractorParams(AFE,'Barkspectrum'“NumBands”numBands,“窗口规范化”,错误的);numElementsperspectroge = numspectrumperspectroge * numbands;

加载预先训练的CNN和标签。

负载(“commandNet.mat”)标签= TrountAynet.Layers(END).Classes;numlabels = numel(标签);backgrounduct x =查找(标签=='背景');

定义缓冲区和决策阈值以对网络预测进行后期处理。

probBuffer =单(0 ([NumLabels classificationRate / 2]));YBuffer = single(NumLabels * ones(1, classificationRate/2));countThreshold =装天花板(classificationRate * 0.2);probThreshold =单(0.7);

创建一个audioDeviceReader对象从设备读取音频。创建一个dsp。AsyncBuffer对象以将音频缓冲为块。

adr = audiodevicereader(“采样器”fs,'samplesperframe'samplesPerCapture,“OutputDataType”“单一”);audioBuffer = dsp.AsyncBuffer (fs);

创建一个dsp。MatrixViewer对象和一个Timescope.对象以显示结果。

MatrixViewer = DSP.MatrixViewer(“ColorBarLabel”“每个频带的功率(dB/频带)”...“包含”“帧”...“ylabel”“树皮乐队”...“位置”,[400 100 600 250],...“ColorLimits”2.6445 [4],...“AxisOrigin”“左下角”...“名称”基于深度学习的语音指令识别);timeScope = timeScope (“SampleRate”fs,...“YLimits”[1],...“位置”,[400 380 600 250],...“名称”“基于深度学习的语音指令识别”...“时间跨度源”“财产”...“时间间隔”,1,...“缓冲区长度”fs,...“ylabel”“振幅”...“夏普林”,真正的);

显示时间范围和矩阵查看器。只要时间范围和矩阵查看器都是打开的,或者直到达到时间限制,就可以检测命令。若要在达到时间限制前停止实时检测,请关闭时间范围窗口或矩阵查看器窗口。

show(timescope)show(matrixviewer)timelimit = 10;Tic.isVisible(timeScope) && isVisible(matrixViewer) && toc < timeLimit%捕捉音频x = adr ();写(audioBuffer x);fs, y =阅读(audioBuffer fs-samplesPerCapture);计算听觉特征=特征提取(afe y);auditoryFeatures = log10(features + 1e-6);%执行预测probs =预测(经过训练,听觉遗传);[〜,ypredicted] = max(probs);%进行统计后处理YBuffer = [YBuffer(2:结束),YPredicted);probBuffer = [probBuffer(:, 2:结束)、聚合氯化铝(:));[YModeIdx, count] = mode(YBuffer);maxProb = max (probBuffer (YModeIdx:));如果ymodeidx ==单(backgroundageidx)||单(计数)其他的speechCommandIdx=YModeIdx;结尾%更新绘图matrixViewer(auditoryFeatures');timeScope(x);如果(spehcommandidx == backgrounddidx)Title =' '其他的timescope.title = char(标签(speathcommandidx));结尾drawnowlimitrate结尾

隐藏范围。

隐藏(矩阵查看器)隐藏(时间范围)

准备MATLAB代码进行部署

创建一个函数来执行与代码生成兼容的功能提取,调用generateMATLABFunctionaudioFeatureExtractor目的。这generateMATLABFunctionObject函数创建一个独立函数,执行等效功能提取,与代码生成兼容。

generateMATLABFunction (afe“extractSpeechFeatures”

allowerspeepehmmandmandrecognitionraspi.金宝app支持函数封装了前面演示的特征提取和网络预测过程。为了使特征提取与代码生成兼容,特征提取由生成的代码处理extractSpeechFeatures函数。使网络兼容代码生成,支持功能使用金宝appCoder.LoadDeePlearningnetwork.(MATLAB编码器)函数加载网络。支持功能金宝app使用dsp.udpreceiver.系统对象发送听觉频谱图和对应于来自Raspberry PI到MATLAB的预测语音命令对应的索引。支持功能金宝app使用dsp.udpreceiver.在MATLAB中接收麦克风捕获的音频的系统对象。

在覆盆子pi上生成可执行文件

更换hostIPAddress您的Raspberry Pi将听觉频谱图和预测语音命令发送到此IP地址。

hostIPAddress =编码器。常数('172.18.230.30');

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

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

使用raspberry pi上的ARM Compute库创建用于深度学习代码的配置对象。指定Raspberry Pi的体系结构,并将深度学习配置对象附加到代码生成配置对象。

dlcfg =编码器。DeepLearningConfig (“arm-compute”);dlcfg。ArmArchitecture =v7的;dlcfg.armcomputeversion =.'19 .05';cfg。DeepLearningConfig = dlcfg;

使用Raspberry Pi支持包函数,金宝appraspi,以创建与Raspberry Pi的连接。在以下代码中,替换:

  • 树莓名称你的树莓派的名字

  • PI与您的用户名

  • 密码用你的密码

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

创建一个编码器硬件(MATLAB编码器)raspberry pi对象并将其附加到代码生成配置对象。

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

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

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

使用自动生成的c++主文件来生成独立的可执行文件。

cfg.generateeExampleMain='generatecodeandcompile'

呼叫Codegen.(MATLAB编码器)要生成C ++代码和Raspberry PI上的可执行文件。默认情况下,raspberry pi应用程序名称与MATLAB函数相同。

Codegen.配置CFG.allowerspeepehmmandmandrecognitionraspi.-  args.{hostIPAddress}报告- v
部署代码。这可能需要几分钟。###编译函数HelperSpeechCommandRecognitionRasPi…------------------------------------------------------------------------ 生成的精灵的位置:/home/pi/remoteBuildDir / MATLAB_ws / R2021b / C / ExampleMatlab / ExampleManager / sporwal.Bdoc21b。### #使用工具链:GNU GCC嵌入式Linux ### # 'C:\ExampleMatlab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning_shared-ex00376115\codegen\exe\HelperSpeechCommandRecognitionRasPi\HelperSpeechCommandRecognitionRasPi_rtw。### build 'HelperSpeechCommandRecognitionRasPi': make -f HelperSpeechCommandRecognitionRasPi_rtw. ##创建helperspeech commands可所有的  ------------------------------------------------------------------------ ### 生成编译报告……警告:函数“HelperSpeechCommandRecognitionRasPi”不会因为无限循环而终止。Warning in ==> HelperSpeechCommandRecognitionRasPi Line: 86 Column: 1代码生成成功(with warnings):查看报告

在Raspberry Pi上初始化应用程序

创建一个命令来打开HelperSpeechCommandRasPi覆盆子派的应用。用系统发送命令给你的树莓派

应用程序名=“HelperSpeechCommandRecognitionRasPi”; ApplicationDirpath=raspi.utils.getRemoteBuildDirectory(“applicationName”,应用名称);targetdirpath = applicationdirpaths {1} .directory;exename = strcat(ApplicationName,“.elf”);命令= [“cd”targetDirPath'./'exeName' &> 1 &'];系统(r,命令);

创建一个dsp.udpreceiver.系统对象将MATLAB中捕获的音频发送到Raspberry Pi。更新targetIPAddress你的树莓派。树莓派接收捕获的音频从同一端口使用dsp.udpreceiver.系统对象。

targetipaddress ='172.18.228.24';UDPSend=dsp.UDPSender('remempport',26000,'remedipaddress', targetIPAddress);

创建一个dsp.udpreceiver.系统对象从树莓派接收听觉特征和预测的语音命令索引。从树莓派接收到的每个UDP报文由列主顺序的听觉特征和预测的语音命令索引组成。的最大消息长度dsp.udpreceiver.对象是65507字节。计算缓冲区大小以适应最大UDP数据包数。

sizeOfFloatInBytes=4;maxUDPMessageLength=地板(65507/大小的原始字节);每个数据包的样本数=1+Numelements透视图;numPackets=地板(最大消息长度/每包样本数);bufferSize=numPackets*samplesPerPacket*sizeOfFloatInBytes;udprecive=dsp.udpreciver(“LocalIPPort”,21000,...“messageatatype”“单身”...“最大消息长度”,samplespacket,...“receptbuffersize”,缓冲区大小);

通过向Raspberry PI上的可执行文件发送zeros帧来减少初始化开销。

UDPSend (0 (samplesPerCapture 1“单身”));

使用部署代码进行语音命令识别

只要时间范围和矩阵查看器都是打开的,或者直到达到时间限制,就可以检测命令。要在达到时间限制之前停止实时检测,请关闭时间范围或矩阵查看窗口。

显示(时间范围)显示(矩阵浏览器)时间限制=20;ticisVisible(timeScope) && isVisible(matrixViewer) && toc < timeLimit%捕获音频并将其发送到Raspix=adr();UDPSend(x);%接收来自RasPi的数据包udprec = udpreceive();如果〜isempty(udprec)%提取预测索引,接收到的UDP报文的最后一个样本speechCommandIdx = udpRec(结束);%提取听觉频谱图spec =整形(udpRec(1:numElementsPerSpectrogram), [numBands, numSpectrumPerSpectrogram]);%显示时域信号和听觉频谱图timeScope (x) matrixViewer(规范)如果speechCommandIdx==BackGroundIdx timeScope.Title=' '其他的timescope.title = char(标签(speathcommandidx));结尾drawnowlimitrate结尾结尾隐藏(矩阵查看器)隐藏(时间范围)

停止在Raspberry PI上的可执行文件,使用stopExecutable。释放UDP对象。

stopexecutable(codertarget.raspi.raspberypi,exename)发行版(Udpsend)发行版(Udpreceive)

轮廓使用PIL工作流程

您可以使用PIL(处理器在循环)工作流来度量Raspberry Pi的执行时间。这ProfileSpeechCommandRecognitionRaspi.金宝app支撑功能相当于allowerspeepehmmandmandrecognitionraspi.函数,只是前者返回语音命令索引和听觉谱图,后者使用UDP发送相同的参数。UDP调用所花费的时间小于1毫秒,与总体执行时间相比相对较小。

创建PIL配置对象。

cfg = coder.config('lib'“是”,真正的);cfg。VerificationMode =“公益诉讼”

设置ARM Compute库和体系结构。

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

建立与目标硬件的连接。

如果(~ ('r''var') r =“raspiname”“π”“密码”);结尾hw = coder.hardware (“树莓π”);cfg。硬件= hw;

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

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

启用分析,然后生成PIL代码。一个名为ProfileSpeechCommandRecognition_PIL.在您当前的文件夹中生成。

cfg.codeexecutionProfIning = true;Codegen.配置CFG.ProfileSpeechCommandRecognitionRaspi.-  args.{rand(samplespercapture,1,'单')}报告- v
部署代码。这可能需要几分钟编译函数ProfileSpeechCommandRecognitionRaspi…###函数“ProfileSpeechCommandRecognitionRaspi”的连接配置:“Raspberry Pi”####使用工具链:GNU GCC Embedded Linux###创建'C:\ExampleMatalab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning_shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\coderassumptions\lib\ProfileSpeechCommandRecognitionRaspi###构建“ProfileSpeechCommandRecognitionRaspi#ca”:使用工具链生成-f ProfileSpeechCommandRecognitionRaspi#ca.mk all####创建'C:\ExampleMatalab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning\u shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\pil\ProfileSpeechCommandRecognitionRaspi\u rtw.mk'…#构建“ProfileSpeechCommandRecognitionRaspi”:生成-f ProfileSpeechCommandRecognitionRaspi_rtw.mk生成elf的所有位置:/home/pi/remoteBuildDir/MATLAB_ws/R2021b/C/exampleMatalab/ExampleManager/sporwal.Bdoc21b.j1648568/deeplearning_shared-ex00376115/codegen/lib/ProfileSpeechCommandRecognitionRaspi/pil------------------------------------------------------------------------#####使用工具链:GNU GCC Embedded Linux#####C:\ExampleMatalab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning\u shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\ProfileSpeechCommandRecognitionRaspi\u rtw.mk'是最新的##“ProfileSpeechCommandRecognitionRaspi”:make-f ProfileSpeechCommandRecognitionRaspi_rtw.mk all-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------正在生成编译报告。。。代码生成成功:查看报告

评估树莓派的执行时间

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

testDur = 50 e - 3;我会= 100;为了k = 1:numcalls x = pinknoise(fs * testdur,“单一”);[Speathcommandidx,听觉优势] = ProfileSpeechCommandRecognitionRaspi_Pil(x);结尾
###启动应用程序:'codegen\lib\ProfileSpeechCommandRecognitionRaspi\pil\ProfileSpeechCommandRecognitionRaspi。###启动应用程序profilespeechcommandrecognitionraspii .elf…可以查看执行分析数据。打开仿真数据检查器。终止后可用的执行分析报告。

终止PIL执行。

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

生成执行配置文件报告以评估执行时间。

executionProfile = getCoderExecutionProfile (“ProfileSpeechCommandRecognitionRaspi”);报告(executionprofile,...“单位”'秒'...“ScaleFactor”“1 e 03”...“NumericFormat”“%0.4f”
ans = ' C: \ ExampleMatlab \ ExampleManager \ sporwal.Bdoc21b.j1648568 \ deeplearning_shared-ex00376115 \ codegen \ lib \ ProfileSpeechCommandRecognitionRaspi \ html \ \ ExecutionProfiling_4f9ceee464b795df.html孤儿”

的最大执行时间ProfileSpeechCommandRecognitionRaspi.函数几乎是平均执行时间的两倍。您可以注意到执行时间是PIL函数的第一次调用的最大时间,这是由于在第一次调用中发生了初始化。平均执行时间大约为20毫秒,低于50毫秒的预算(音频捕获时间)。性能是在树莓Pi 4模型B Rev 1.1上测量的。