主要内容

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

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

先决条件

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

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

  • 编译器和库的环境变量

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

MATLAB中的流演示

为特征提取管道和分类使用与中开发的相同的参数基于深度学习的语音指令识别

定义网络训练时使用的相同采样率(16 kHz)。定义分类率和每帧输入的音频样本数。输入到网络的特征是对应于1秒音频数据的巴克谱图。树皮谱图是在25毫秒窗口和10毫秒跳数下计算的。计算每个光谱图中单个光谱的数量。

fs=16000;分类率=20;samplesPerCapture=fs/分类率;持续时间=1;分段样本=圆形(分段持续时间*fs);帧持续时间=0.025;frameSamples=四舍五入(frameDuration*fs);hopDuration=0.010;hopSamples=圆形(hopDuration*fs);numSpectrumPerSpectrogram=地板((分段样本框架样本)/啤酒花样本)+1;

创建一个audioFeatureExtractor对象提取50波段Bark谱图,无需窗归一化。计算每个谱图中的元素数。

afe = audioFeatureExtractor (...“SampleRate”,财政司司长,...“FFTLength”, 512,...“窗口”损害(frameSamples“周期”),...“OverlapLength”frameSamples - hopSamples...“barkSpectrum”,真正的);numBands = 50;setExtractorParams (afe“barkSpectrum”“NumBands”numBands,“WindowNormalization”、假);numElementsPerSpectrogram = numSpectrumPerSpectrogram * numBands;

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

负载(“commandNet.mat”)标签= trainedNet.Layers(end).Classes;NumLabels =元素个数(标签);backgrounddidx = find(标签==“背景”);

定义缓冲区和决策阈值,用于后期处理网络预测。

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

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

adr = audioDeviceReader (“SampleRate”,财政司司长,“SamplesPerFrame”,samplesPerCapture,“OutputDataType”“单一”); audioBuffer=dsp.AsyncBuffer(fs);

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

matrixViewer = dsp。MatrixViewer (“ColorBarLabel”“频带功率(dB/频带)”...“XLabel”“帧”...“YLabel”“汪汪”乐队...“位置”,[400 100 600 250],...“ColorLimits”2.6445 [4],...“AxisOrigin”“左下角”...“姓名”“使用深度学习的语音命令识别”);timeScope = timeScope (“SampleRate”,财政司司长,...“YLimits”,[-1 1],...“位置”,[400 380 600 250],...“姓名”“使用深度学习的语音命令识别”...“TimeSpanSource”“财产”...“时间间隔”,1,...“BufferLength”,财政司司长,...“YLabel”“振幅”...“ShowGrid”,真正的);

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

show(timeScope) show(matrixViewer) timlimit = 10;抽搐虽然isVisible(timeScope) && isVisible(matrixViewer) && toc < timeLimit%捕获音频x=adr();写入(音频缓冲区,x);y=读取(音频缓冲区、fs、fs samplesPerCapture);%计算听觉特征特征=提取(afe,y);auditoryFeatures=log10(features+1e-6);%进行预测probs =预测(trainedNet, auditoryFeatures);[~, YPredicted] = max(probs);%执行统计后处理YBuffer = [YBuffer(2:结束),YPredicted);probBuffer = [probBuffer(:, 2:结束)、聚合氯化铝(:));[YModeIdx, count] = mode(YBuffer);maxProb = max (probBuffer (YModeIdx:));如果YModeIdx == single(BackGroundIdx) || single(count) < countThreshold || maxprobx < probThreshold其他的speechCommandIdx = YModeIdx;结束%更新图matrixViewer (auditoryFeatures ');timeScope (x);如果(spehcommandidx == backgrounddidx)Title =' '其他的timeScope。Title =char(labels(speechCommandIdx));结束刷新屏幕limitrate结束

隐藏的范围。

隐藏(matrixViewer)隐藏(timeScope)

为部署准备MATLAB代码

要创建一个函数来执行与代码生成兼容的特征提取,调用generateMATLABFunctionaudioFeatureExtractor对象。的generateMATLABFunction对象函数创建一个独立的函数,执行等价的特征提取,并与代码生成兼容。

generateMATLABFunction(afe,“extractSpeechFeatures”

HelperSpeechCommandRecognitionRasPi金宝app支持函数封装了前面演示的特征提取和网络预测过程。因此,特征提取与代码生成兼容,特征提取由生成的提取语音特征函数。使网络兼容代码生成,支持功能使用金宝appcoder.loadDeepLearningNetwork(MATLAB编码器)命令功能,加载网络。支持函数金宝app使用adsp。UDPReceiver系统对象将树莓派的听觉谱图和预测语音命令对应的索引发送到MATLAB。支持函数金宝app使用dsp。UDPReceiver在MATLAB中接收麦克风捕获的音频的系统对象。

生成可执行文件在树莓派

取代hostIPAddress你的机器地址。你的树莓派发送听觉光谱图和预测语音命令到这个IP地址。

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

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

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

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

dlcfg =编码器。DeepLearningConfig (“arm计算”); dlcfg.ArmArchitecture=v7的;dlcfg。ArmComputeVersion =“19.05”; cfg.DeepLearningConfig=dlcfg;

使用树莓派支持包功能,金宝appraspi,创建连接到你的树莓派。在以下代码中,替换:

  • raspiname你的树莓派的名字

  • PI与您的用户名

  • 暗语用你的密码

r=拉斯皮(“raspiname”“π”“密码”);

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

hw=编码器硬件(“覆盆子皮”); 硬件=硬件;

指定Raspberry Pi上的生成文件夹。

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

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

cfg。GenerateExampleMain =“GenerateCodeAndCompile”

调用codegen(MATLAB编码器)在树莓派上生成c++代码和可执行文件。默认情况下,树莓派应用程序的名称与MATLAB函数相同。

codegen-配置cfgHelperSpeechCommandRecognitionRasPiarg游戏{hostIPAddress}报告-五
部署代码。这可能需要几分钟。###编译函数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):查看报告

初始化应用树莓派

创建一个命令以打开HelperSpeechCommandRasPi覆盆子派的应用.使用系统将命令发送到您的Raspberry Pi。

applicationName =“HelperSpeechCommandRecognitionRasPi”;applicationDirPaths = raspi.utils.getRemoteBuildDirectory (“应用程序名”applicationName);targetDirPath = applicationDirPaths {1} .directory;exeName = strcat (applicationName,“小精灵”);命令= [“cd”targetDirPath”;。/”exeName' &> 1 &'];系统(r,命令);

创建一个dsp。UDPReceiver系统对象发送音频捕获在MATLAB到您的树莓派。更新女靶子你的树莓派。树莓派接收捕获的音频从同一端口使用dsp。UDPReceiver系统对象。

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

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

sizeOfFloatInBytes = 4;maxUDPMessageLength =地板(65507 / sizeOfFloatInBytes);samplesPerPacket = 1 + numElementsPerSpectrogram;numPackets =地板(maxUDPMessageLength / samplesPerPacket);bufferSize = numPackets * samplesPerPacket * sizeOfFloatInBytes;UDPReceive = dsp。UDPReceiver (“LocalIPPort”, 21000,...“MessageDataType”“单身”...“MaximumMessageLength”samplesPerPacket,...“下面的”bufferSize);

通过向运行在树莓派上的可执行文件发送一帧0来减少初始化开销。

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

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

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

show(timeScope) show(matrixViewer) timeLimit = 20;抽搐虽然isVisible(timeScope) && isVisible(matrixViewer) && toc < timeLimit%捕获音频并发送到RasPix = adr ();UDPSend (x);%接收来自RasPi的数据包udpRec = UDPReceive ();如果~ isempty (udpRec)%提取预测索引,即接收到的UDP数据包的最后一个样本speechCommandIdx=udpRec(结束);%提取听觉谱图spec =整形(udpRec(1:numElementsPerSpectrogram), [numBands, numSpectrumPerSpectrogram]);%显示时域信号和听觉谱图时间范围(x)矩阵过滤器(规格)如果spehcommandidx == backgrounddidx timeScope。Title =' '其他的timeScope。Title =char(labels(speechCommandIdx));结束刷新屏幕limitrate结束结束隐藏(matrixViewer)隐藏(timeScope)

要停止树莓派上的可执行文件,请使用stopExecutable.释放UDP对象。

stopExecutable (codertarget.raspi.raspberrypi exeName)发布(UDPSend)发布(UDPReceive)

使用PIL工作流配置文件

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

创建一个PIL配置对象。

cfg = coder.config (“自由”“ecoder”,对);验证模式=“公益诉讼”

设置ARM计算库和架构。

dlcfg =编码器。DeepLearningConfig (“arm计算”);cfg。DeepLearningConfig = dlcfg;cfg.DeepLearningConfig.ArmArchitecture =v7的; cfg.DeepLearningConfig.ArmComputeVersion=“19.05”

建立与目标硬件的连接。

如果(~ (“r”“var”) r =“raspiname”“π”“密码”);结束hw=编码器硬件(“覆盆子皮”); 硬件=硬件;

设置构建目录和目标语言。

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

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

cfg。CodeExecutionProfiling = true;codegen-配置cfgProfileSpeechCommandRecognitionRaspiarg游戏{兰德(samplesPerCapture 1 '单')}报告-五
部署代码。这可能需要几分钟。###编译函数ProfileSpeechCommandRecognitionRaspi…### # profile espeechcommandrecogntionraspi函数的连通性配置:###创建'C:\ExampleMatlab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning_shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\ coder假设\lib\ProfileSpeechCommandRecognitionRaspi_ca。可”……### build 'ProfileSpeechCommandRecognitionRaspi_ca': make -f ProfileSpeechCommandRecognitionRaspi_ca. ### # build 'ProfileSpeechCommandRecognitionRaspi_ca':### # create 'C:\ExampleMatlab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning_shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\pil\ProfileSpeechCommandRecognitionRaspi_rtw. mk# ###使用工具链:GNU GCC嵌入式Linux可”……### build ' profilespeechcommandrecogntionraspi ': make -f profilespeechcommandrecogntionraspi_rtw . ### # build ' profilespeechcommandrecogntionraspi ': make -f profilespeechcommandrecogntionraspi_rtw . ###/home/pi/ remotebuilddir /MATLAB_ws/R2021b/C/ExampleMatlab/ExampleManager/ sporwall . bdoc21b . mk所有生成elf的位置:j1648568 / deeplearning_shared-ex00376115 codegen / lib / ProfileSpeechCommandRecognitionRaspi /公益诉讼  ------------------------------------------------------------------------ ### 使用工具链: GNU GCC Embedded Linux ### 'C:\ExampleMatlab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning_shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\ProfileSpeechCommandRecognitionRaspi_rtw.mk' is up to date ### Building 'ProfileSpeechCommandRecognitionRaspi': make -f ProfileSpeechCommandRecognitionRaspi_rtw.mk all ------------------------------------------------------------------------ ### Generating compilation report ... Code generation successful: View report

评估树莓派的执行时间

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

testDur=50e-3;numCalls=100;k = 1:numCalls x = pinknoise(fs*testDur,“单一”);[speechCommandIdx, auditoryFeatures] = ProfileSpeechCommandRecognitionRaspi_pil(x);结束
###启动应用程序:'codegen\lib\ProfileSpeechCommandRecognitionRaspi\pil\ProfileSpeechCommandRecognitionRaspi。###启动应用程序profilespeechcommandrecognitionraspii .elf…可以查看执行分析数据。打开仿真数据检查器。终止后可用的执行分析报告。

终止公益诉讼执行。

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

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

executionProfile=getCoderExecutionProfile(“ProfileSpeechCommandRecognitionRaspi”);报告(executionProfile,...“单位”“秒”...“ScaleFactor”“1 e 03”...“NumericFormat”' % 0.4 f '
ans='C:\ExampleMatalab\ExampleManager\sporwal.Bdoc21b.j1648568\deeplearning\u shared-ex00376115\codegen\lib\ProfileSpeechCommandRecognitionRaspi\html\orphaned\ExecutionProfiling\u 4f9ceee464b795df.html'

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