主要内容

音频功能的顺序特征选择

此示例显示了应用于讲解数字识别任务的特征选择的典型工作流程。

在顺序特征选择中,您在给定的功能集上培训网络,然后逐步添加或删除功能,直到达到最高精度[1].在本例中,使用自由语音数字数据集对语音数字识别任务应用顺序前向选择[2]

流语音数字识别

为了激发这个例子,首先加载一个预先训练过的网络audioFeatureExtractor对象用于训练网络,并对特征进行归一化因子。

负载(“network_Audio_SequentialFeatureSelection.mat”“bestNet”“安全的”'癌症');

创建一个audioDeviceReader从麦克风中读出声音。创建三个dsp。AsyncBuffer对象:一个用于从麦克风读取的缓冲音频,一个用于缓冲输入音频的短期能量,用于语音检测,以及一个缓冲预测。

fs = afe.SampleRate;deviceReader = audioDeviceReader (“SampleRate”,fs,'samplesperframe', 256);audioBuffer = dsp.AsyncBuffer (fs * 3);steBuffer = dsp.AsyncBuffer (1000);predictionBuffer = dsp.AsyncBuffer (5);

创建一个图来显示流音频、推断过程中网络输出的概率和预测。

图=图;Streamaxes =子图(3,1,1);Streamplot = plot(零(fs,1));ylabel(“振幅”)包含(“时间(s)”)标题(“音频流”) streamAxes。XTick = (0, fs);streamAxes。XTickLabel = [0, 1];streamAxes。YLim = [1];analyzedAxes =次要情节(3、1、2);analyzedPlot =情节(0 (fs / 2,1));标题(分析了部分的) ylabel (“振幅”)包含(“时间(s)”)设置(GCA,“XTickLabel”[]) analyzedAxes。XTick = [0, fs / 2];analyzedAxes。XTickLabel = [0, 0.5];analyzedAxes。YLim = [1];probabilityAxes =情节(3、1,3);probabilityPlot =酒吧(0:9,0.1 * (10));轴([1,10,0,1])ylabel (“概率”)包含(“类”

执行流数字识别(数字0到9)20秒。当循环运行时,说出其中一个数字并测试其准确性。

首先,定义一个短期能量阈值,在此阈值下假定一个信号不包含语音。

steThreshold = 0.015;idxVec = 1: fs;抽搐TOC <20%从您的设备帧中读取。audioIn = deviceReader ();%将音频写入缓冲区。写(audioBuffer audioIn);%当200毫秒的数据未使用时,继续此循环。audiobuffer.numunReadsamples> 0.2 * FS%从音频缓冲区读取1秒。这一秒的800毫秒%重新判定旧数据,200 ms是新数据。录音仪=读(AudioBuffer,FS,0.8 * FS);%更新图表以绘制当前的音频数据。streamPlot。YData = audioToAnalyze;ste =意味着(abs (audioToAnalyze));写(steBuffer, ste);如果steBuffer。NumUnreadSamples > 5 abc = sort(peek(steBuffer));steThreshold = abc(圆(0.4 *元素个数(abc)));结尾如果ste > steThreshold%使用detectspeech函数来确定一个区域是否有语音%。idx = detectSpeech (audioToAnalyze, fs);如果存在语音区域,则%执行以下操作。如果〜Isempty(IDX)除语音外,信号的所有部分都调零%区域,并修剪到0.5秒。AudiotoAnalyze = Helpertrimorpad(录音(IDX(1,1):IDX(1,2)),FS / 2);%标准化音频。audioToAnalyze = audioToAnalyze / max (abs (audioToAnalyze));%更新分析的分段图分析ZEDPLOT.YDATA =录音;提取特征和转置他们,使时间%在列。特点=(提取(afe audioToAnalyze) ';使特性正常化。feature = (features - normalizer . mean) ./ normalizer . standarddeviation;%调用分类以确定概率和%赢得标签。特性(isnan(特性))= 0;(标签,聚合氯化铝)= (bestNet、特性)进行分类;%更新概率和获胜的情节%的标签。probabilityPlot。YData =聚合氯化铝;写(predictionBuffer,聚合氯化铝);如果predicationbuffer.numunReadsamples == predicationBuffer.Capacity Lastten = Peek(预测缓冲);[〜,决策] = max(平均值(枚手* hann(size(lasten,1)),1));概率.Title.String = num2str(决策-1);结尾结尾别的%如果信号能量低于阈值,则假定无语音%检测。probabilityAxes.Title.String ='';probabilityPlot。YData = 0.1 * 1 (1);analyzedPlot。YData = 0 (f / 2、1);重置(predictionBuffer)结尾drawnlimitrate结尾结尾

示例的其余部分说明了如何训练流检测中使用的网络,以及如何选择送入网络的特征。

创建培训和验证数据集

下载自由口语数字数据集(FSDD)[2].FSDD由具有口头数字(0-9)的短音频文件组成。

url =“https://zenodo.org/record/1342401/files/Jakobovski/free-spoken-digit-dataset-v1.0.8.zip”;downloadFolder = tempdir;datasetFolder = fullfile (downloadFolder,“FSDD”);如果~存在(datasetFolder“dir”)流(“正在下载免费语音数字数据集……\n”解压缩(url, datasetFolder)结尾

创建一个audioDatastore指向录音得到数据集的抽样率。

广告= audiodataStore(DataSetFolder,“IncludeSubfolders”,真正的);[~, adsInfo] =阅读(广告);fs = adsInfo.SampleRate;

文件名的第一个元素是文件中所说的数字。获取文件名的第一个元素,将它们转换为分类,然后设置标签财产的audioDatastore

[〜,filenames] = Cellfun(@(x)fileparts(x),ads.files,“UniformOutput”、假);ads.Labels =分类(string (cellfun (@ (x) x(1),文件名)));

若要将数据存储划分为开发集和验证集,请使用spliteachlabel..分配80%的数据用于开发,剩余20%用于验证。

[adstrain,ADSValidation] = SpliteachLabel(广告,0.8);

设置音频特征提取器

创建一个audioFeatureExtractor对象提取音频特征超过30毫秒的Windows与10毫秒的更新率。将本例中要测试的所有特性设置为真正的

赢得=汉明(圆(0.03 * fs),“周期”);overtaplength = round(0.02 * fs);AFE = audiofeatureextractor(...“窗口”,赢了,...“OverlapLength”overlapLength,...“SampleRate”fs,......“linearSpectrum”假的,...“melSpectrum”假的,...'Barkspectrum'假的,...“erbSpectrum”假的,......“mfcc”,真的,...“mfccDelta”,真的,...“mfccDeltaDelta”,真的,...“gtcc”,真的,...'gtccdelta',真的,...'gtccdeltadelta',真的,......“spectralCentroid”,真的,...'spectralcrest',真的,...'spectraldecrease',真的,...“spectralEntropy”,真的,...“spectralFlatness”,真的,...'spectralflux',真的,...“spectralKurtosis”,真的,...“spectralRolloffPoint”,真的,...“spectralSkewness”,真的,...“spectralSlope”,真的,...'spectralspread',真的,......“节”假的,...“harmonicRatio”、假);

定义图层和培训选项

定义深度学习层列表(深度学习工具箱)trainingOptions(深度学习工具箱)在这个例子中使用。第一层,sequenceInputLayer(深度学习工具箱),只是一个占位符。根据您在顺序特征选择过程中测试的特征,第一层将被替换为sequenceInputLayer大小合适的。

numUnits =One hundred.;层= [...sequenceInputLayer (1) bilstmLayer (numUnits“OutputMode”“最后的”) full connectedlayer (numel(categories(adsTrain.Labels))) softmaxLayer classificationLayer];选择= trainingOptions (“亚当”...“LearnRateSchedule”“分段”...“洗牌”“every-epoch”...“详细”假的,...“MaxEpochs”, 20);

连续的特征选择

在序列特征选择的基本形式中,你在一个给定的特征集上训练一个网络,然后递增地添加或删除特征,直到精确度不再提高[1]

提出了选择

考虑一组四个功能的一个简单的前进选择。在第一前进选择循环中,通过培训网络并进行比较它们的验证精度,独立地测试四个特征中的每一个。注意到导致最高验证精度的功能。在第二正向选择循环中,来自第一环的最佳特征与每个剩余功能组合。现在每对功能都用于培训。如果第二循环中的准确性未在第一环中的准确性上提高,则选择过程结束。否则,选择了新的最佳功能集。前向选择循环继续,直到精度不再改善。

逆向选择

在向后特征选择中,首先在包含所有特征的特征集上进行训练,并测试在删除特征时准确性是否会提高。

运行顺序特征选择

辅助函数(救助人员HelperTrainAndValidateNetwork,HelperTrimOrPad)实现向前或向后顺序特征选择。指定训练数据存储、验证数据存储、音频特征提取器、网络层、网络选项和方向。一般来说,如果您预期的是小的特性集,则选择向前;如果您预期的是大的特性集,则选择向后。

方向=“前进”;(日志,bestFeatures bestNet标准化者]= HelperSFS (adsTrain、adsValidation afe,层,选择,方向);
使用“本地”配置文件启动并行池(Parpool)连接到并行池(工人数:6)。

日志输出HelperFeatureExtractor是一个包含所有测试的特性配置和相应验证精度的表。

日志
日志=48×2表功能精度__________________________________ ________ "mfcc, gtcc" 97.333 "mfcc, mfccDelta, gtcc" 97 "mfcc, gtcc,频谱熵" 97 "mfcc, gtcc,频谱平坦度" 97 "mfcc, gtcc, spectralFlux" 97 "mfcc, gtcc, spectralSpread" 97 "gtcc" 96.667 "gtcc, spectralFlux" 96.667 "mfcc, gtcc,mfcc, gtcc, spectrum rolloffpoint“96.667”mfcc, gtcc, spectrum skewness“96.667”gtcc, spectrum entropy“96.333”mfcc, gtcc, gtccDeltaDelta“96.333”mfcc, gtcc, spectrum kurtosis“96.333”mfccDelta, gtcc“96”gtcc, gtccDelta“96⋮

bestFeatures输出救助人员包含将最佳特性设置为的结构体真正的

bestFeatures
BestFeatures =.结构与字段:mfcc: 1 mfccDelta: 0 mfccDeltaDelta: 0 gtcc: 1 gtccDelta: 0 gtccDeltaDelta: 0 spectralCentroid: 0 spectralCrest: 0 spectralDecrease: 0 spectralEntropy: 0 spectralFlatness: 0 spectralFlux: 0 spectralKurtosis: 0 spectralRolloffPoint: 0 spectralSkewness: 0 spectralSlope: 0 spectralSpread: 0

你可以设置audioFeatureExtractor使用结构体。

安全设置(afe bestFeatures)
AFE = audiofeatureextractor具有属性:属性窗口:[240×1双]俯视高分:160 Samplege:8000 FFTLINPUT:'Linearspectrum'启用的功能MFCC,GTCC禁用功能Linearspectrum,Melspectrum,Barkspectum,Erbspectrum,MFCCDelta,MFCCDeltadelta GTCCDelta,GTCCDELTADELTA,Spectralcerroid,SpectralcRest,SpectralofeaeS,Spectralopy Spectrallats,Spectralflux,Spectarkurtosis,Spectraloffpoint,Spectralswness,Spectralslope Spectralspread,Titch,Hashonicratio提取一个功能,将相应的属性设置为True。例如,obj.mfcc = true,将mfcc添加到启用功能列表中。

救助人员并输出性能最佳的网络和与所选特征对应的归一化因子。保存已配置的网络audioFeatureExtractor,和归一化因子,取消注释这一行:

%保存(“network_Audio_SequentialFeatureSelection.mat”、“bestNet”,“安全的”,“标准化者”)

结论

这个例子说明了递归神经网络(LSTM或BiLSTM)的顺序特征选择的工作流。它可以很容易地适应CNN和RNN-CNN的工作流程。

金宝app支持功能

HelperTrainAndValidateNetwork

函数[trueLabels predictedLabels,净,标准化者]= HelperTrainAndValidateNetwork (adsTrain、adsValidation afe,层,选项)%培训和验证网络。%的输入:% adsTrain -指向训练集的audioDatastore对象%ADSValidation  - 要指向验证集的AudioDataStore对象% afe - audioFeatureExtractor对象。%层 -  LSTM或Bilstm网络的层% options - trainingOptions对象%输出:% true标签-验证集的真标签% predictedLabels -验证集的预测标签% net -训练的网络正规化因子-被测特性的正规化因子版权所有2019 The MathWorks, Inc.%将数据转换为高数组。tallTrain =高(adsTrain);tallValidation =高(adsValidation);%从训练集中提取特征。重新定位功能,以便% time沿着行与sequenceInputLayer兼容。fs = afe.SampleRate;tallTrain = cellfun (@ (x) HelperTrimOrPad (x, fs / 2) tallTrain,“UniformOutput”、假);tallTrain = cellfun (@ x (x) / max (abs (x)、[]'全部')、tallTrain“UniformOutput”、假);tallFeaturesTrain = cellfun (@ (x)提取(afe x), tallTrain,“UniformOutput”、假);tallFeaturesTrain = cellfun (@ (x) x ', tallFeaturesTrain,“UniformOutput”、假);% #好< NASGU >[~, featuresTrain] = evalc (“收集(tallFeaturesTrain)”);%使用evalc抑制命令行输出。tallValidation = cellfun (@ (x) HelperTrimOrPad (x, fs / 2) tallValidation,“UniformOutput”、假);tallValidation = cellfun (@ x (x) / max (abs (x)、[]'全部')、tallValidation“UniformOutput”、假);tallFeaturesValidation = cellfun (@ (x)提取(afe x), tallValidation,“UniformOutput”、假);tallFeaturesValidation = cellfun (@ (x) x ', tallFeaturesValidation,“UniformOutput”、假);% #好< NASGU >[~, featuresValidation] = evalc ('聚集(TallfeaturesValidation)');%使用evalc抑制命令行输出。%使用训练集确定每个的平均值和标准偏差%的特性。将训练和验证集规范化。allFeatures =猫(2,featuresTrain {:});M =意味着(allFeatures 2“omitnan”);S =性病(allFeatures 0 2,“omitnan”);featuresTrain = cellfun (@ (x)(即x m)。/ S, featuresTrain,“UniformOutput”、假);为了ii = 1:numel(featuresTrain) idx = find(isnan(featuresTrain{ii}));如果~isempty(idx) featuresTrain{ii}(idx) = 0;结尾结尾featuresValidation = cellfun (@ (x)(即x m)。/ S, featuresValidation,“UniformOutput”、假);为了II = 1:NUMEL(特征)idx = find(ISNAN(特征过验证{II}));如果~isempty(idx) featuresValidation{ii}(idx) = 0;结尾结尾%复制列车和验证集的标签,以便它们在%与序列一一对应。labelsTrain = adsTrain.Labels;%更新输入层的测试特性的数量。层(1)= sequenceInputLayer(大小(featuresTrain {1}, 1));%训练网络。net = trainnetwork(Featurestrain,labelstrain,图层,选项);%评估网络。调用classify以获得每个的预测标签%的序列。predictedLabels =分类(净,featuresValidation);trueLabels = adsValidation.Labels;%将标准化因子保存为结构体。标准化者。意味着= M;标准化者。StandardDeviation = S;结尾

救助人员

函数(日志,bestFeatures bestNet bestNormalizers] = HelperSFS (adsTrain、adsValidate afeThis,层,选择,方向)%的输入:% adsTrain -指向训练集的audioDatastore对象% adsValidate -指向验证集的audioDatastore对象% afe - audioFeatureExtractor对象。设置所有功能测试为真%层 -  LSTM或Bilstm网络的层% options - trainingOptions对象% direction - SFS方向,指定为“forward”或“backward”%输出:%日志-包含测试特性配置和相应验证精度的表% bestFeatures -包含最佳特性配置的结构体% bestNet -训练有素的网络,具有最高的验证精度% bestnormalizer -最佳特征的特征归一化因子版权所有2019 The MathWorks, Inc.afe =副本(afethis);featureesttest = fieldnames(信息(afe));n = numel(featureastotest);BestValidationAccuracy = 0;设置初始特性配置:开启向后选择%或全部关闭向前选择。featureconfig =信息(afe);为了i = 1: N如果strcmpi(方向,“落后”) featureConfig.(featuresToTest{i}) = true;别的featureConfig。(featuresToTest{我})= false;结尾结尾%初始化日志以跟踪功能配置和准确性。日志=表(featureConfig 0“VariableNames”,[“功能配置”“准确性”]);执行顺序特征评估。wrapperIdx = 1;bestAccuracy = 0;wrapperIdx < = N创建包含要测试的所有功能配置的单元格数组在当前循环中。featureConfigsToTest =细胞(元素个数(featuresToTest), 1);为了2 = 1:元素个数(featuresToTest)如果strcmpi(方向,“落后”) featureConfig.(featuresToTest{ii}) = false;别的featureConfig。(featuresToTest {2}) = true;结尾featureConfigsToTest {2} = featureConfig;如果strcmpi(方向,“落后”)featureconfig。(featureestottest {ii})= true;别的featureConfig。(featuresToTest {2}) = false;结尾结尾%循环每个特性集。为了2 = 1:元素个数(featureConfigsToTest)确定当前要测试的特性配置。更新%该功能安全。currentConfig = featureConfigsToTest {2};currentConfig集(afe)%培训并获得当前k倍交叉验证精度%的功能配置。[trueLabels predictedLabels,净,标准化者]= HelperTrainAndValidateNetwork (adsTrain、adsValidate afe,层,选项);valAccuracy =意味着(trueLabels = = predictedLabels) * 100;如果valaccuracy> bestValidationAccuracy eStValidationAccuracy = ValAccuracy;bestnet = net;Bestnormalizers =癌症;结尾%更新日志结果=表(CurrentConfig,Valaguracy,“VariableNames”,[“功能配置”“准确性”]);日志=(日志;结果);%#OK 结尾%以最佳精度确定和打印设置。如果精度%没有提高,结束跑。[a, b] = max(日志{:,“准确性”});如果A <= BESTACCURACY WRAPPERIDX = INF;别的wrapperIdx = wrapperIdx + 1;结尾bestAccuracy =一个;%根据最近的胜出者更新待测试的功能。赢家=日志{b,“功能配置”};fn =字段名(冠军);tf = structfun (@ (x) (x)赢家);如果strcmpi(方向,“落后”) featuresToRemove = fn(~tf);别的featuresToRemove = fn (tf);结尾为了ii = 1:numel(featuresToRemove) loc = strcmp(featuresToTest,featuresToRemove{ii});featuresToTest (loc) = [];如果strcmpi(方向,“落后”)featureconfig。(featureastoremove {ii})= false;别的featureConfig。(featuresToRemove {2}) = true;结尾结尾结尾%对日志进行排序,使其更可读。日志(1,:) = [];%删除第一行占位符。日志= sortrows(日志,{“准确性”},{“下”});bestFeatures =日志{1,“功能配置”};m =日志{:,“功能配置”};fn =字段名(m);myString =字符串(元素个数(m), 1);为了wrapperIdx = 1:num (m) tf = structfun(@(x)(x),logbook{wrapperIdx,“功能配置”});mystring(wrapperidx)= strjoin(fn(tf),”、“);结尾日志=表(myString日志{:,“准确性”},“VariableNames”,[“特征”“准确性”]);结尾

HelperTrimOrPad

函数y = HelperTrimOrPad (x, n)% y = HelperTrimOrPad(x,n)修剪或填充输入x到n个样本。如果x是%修剪,前后修剪均匀。如果x被填充,它就是%填充在前面的正面和用零。对于奇数修剪或%填充,额外的样品从后面修剪或填充。版权所有2019 The MathWorks, Inc.一个=大小(x, 1);如果a < n frontPad = floor((n-a)/2);backPad = n - a - frontPad;(y = 0 (frontPad 1); x; 0(挤压垫,1)];elseifa > n frontTrim = floor((a-n)/2)+1;backTrim = a - n - frontTrim;y = x (frontTrim: end-backTrim);别的y = x;结尾结尾

参考文献

Jain A.和D. Zongker。《特征选择:评估、应用和小样本性能》模式分析与机器智能学报。1997年第19卷第2期153-158页。

[2] Jakobovski。“Jakobovski / Free-Spoken-Digit-Dataset。”GitHub, 2019年5月30日。https://github.com/Jakobovski/free-spoken-digit-dataset。