主要内容

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

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

先决条件

  • 支持霓虹灯扩展的ARM处理器金宝app

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

  • 编译器和库的环境变量

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

MATLAB中的流演示

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

定义网络培训的相同采样率(16 kHz)。定义每个帧输入的分类速率和音频样本数。输入到网络的特征是对应于1秒的音频数据的Bark谱图。将Bark谱图用于25毫秒的窗口,10 ms跳。计算每个频谱图中的个体频谱的数量。

FS = 16000;分类= 20;SamplesPapture = FS /分类;semmentduration = 1;segmensamples = round(semmentduration * fs);Framedrion = 0.025;FramesAmples =圆形(框架* FS);HopDuration = 0.010;HOPSAMALSERS =圆形(HOPDOUNT * FS);numspectrumperspectrogge =地板((Segmenssamples-framesamples)/ hopsamples)+ 1;

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

afe = audioFeatureExtractor (...“SampleRate”,fs,...'fftlength', 512,...“窗口”损害(frameSamples“周期”),...“OverlapLength”frameSamples - hopSamples...“barkSpectrum”,真正的);numBands = 50;setExtractorParams (afe“barkSpectrum”“NumBands”numBands,'风向正常化'、假);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);

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

adr = audioDeviceReader (“SampleRate”,fs,“SamplesPerFrame”,样本papture,“OutputDataType”“单一”);audiobuffer = dsp.asyncubuffer(FS);

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

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

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

show(timeScope) show(matrixViewer) timlimit = 10;抽搐尽管isVisible(timeScope) && isVisible(matrixViewer) && toc < timeLimit%捕获音频x = adr ();写(audiobuffer,x);Y =读取(AudioBuffer,FS,FS-Samplepercapture);%计算听觉特征特点=提取物(AFE,Y);听觉优势= log10(特点+ 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));结束drawnowlimitrate结束

隐藏的范围。

隐藏(matrixViewer)隐藏(timeScope)

为部署准备MATLAB代码

要创建一个函数来执行与代码生成兼容的特征提取,调用generatematlabfunction.在这方面audioFeatureExtractor对象。的generatematlabfunction.对象函数创建一个独立的函数,执行等价的特征提取,并与代码生成兼容。

generatematlabfunction(afe,'提取分流'

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-compute');dlcfg.armArchitecture =v7的;dlcfg。ArmComputeVersion =“19.05”;cfg.deeplearningconfig = dlcfg;

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

  • raspiname你的树莓派的名字

  • PI与您的用户名

  • 密码用你的密码

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

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

hw = coder.hardware('覆盆子pi');cfg.hardware = hw;

在raspberry pi上指定构建文件夹。

builddir =“~ / remoteBuildDir”;cfg.hardware.builddir = builddir;

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

cfg。GenerateExampleMain =“GenerateCodeAndCompile”

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

codegen-Config.cfgHelperSpeechCommandRecognitionRasPiarg游戏{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):查看报告

初始化应用树莓派

创建一个命令打开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到您的树莓派。更新Targetipaddress.你的树莓派。树莓派接收捕获的音频从同一端口使用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数据包的最后一个样本stategeCommandidx = UdPrec(END);%提取听觉谱图spec =整形(udpRec(1:numElementsPerSpectrogram), [numBands, numSpectrumPerSpectrogram]);%显示时域信号和听觉谱图Timescope(x)矩阵浏览器(规格)如果spehcommandidx == backgrounddidx timeScope。Title =' '其他的timeScope。Title =char(labels(speechCommandIdx));结束drawnowlimitrate结束结束隐藏(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',真正的);cfg.verificationMode =.“公益诉讼”

设置ARM计算库和架构。

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

建立与目标硬件的连接。

如果(~ (“r”“var”) r =“raspiname”“π”“密码”);结束hw = coder.hardware('覆盆子pi');cfg.hardware = hw;

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

builddir =“~ / remoteBuildDir”;cfg.hardware.builddir = builddir;cfg.targetlang ='c ++'

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

cfg。CodeExecutionProfiling = true;codegen-Config.cfgProfileSpeechCommandRecognitionRaspiarg游戏{兰德(samplesPerCapture 1 '单')}报告-v.
部署代码。这可能需要几分钟。###编译函数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”'1E-03'...“NumericFormat”'%0.4f'
ans ='c:\ examplematlab \ examplemanager \ sporwal.bdoc21b.j1648568 \ deeplearning_shared-ex00376115 \ codegen \ lib \ profileSpeechcommandRecognitionRaspi \ html \ orphaned \ executionProfIning_4f9ceee464b795df.html'

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