主要内容

音频功能的顺序功能选择

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

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

流语音数字识别

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

负载(“network_Audio_SequentialFeatureSelection.mat”“bestNet”“安全的”“标准化者”);

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

fs = afe.SampleRate;deviceReader = audioDeviceReader (“SampleRate”,财政司司长,“样品性能框架”, 256);audioBuffer = dsp.AsyncBuffer (fs * 3);steBuffer = dsp.AsyncBuffer (1000);predictionBuffer = dsp.AsyncBuffer (5);

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

图=图;流轴=子地块(3,1,1);流图=地块(零(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)”)set(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;抽搐总有机碳<20%从设备读取音频帧。audioIn = deviceReader ();%将音频写入缓冲区中的音频。写(audioBuffer audioIn);%当200毫秒的数据未使用时,继续此循环。audioBuffer.numreadsamples>0.2*fs%从音频缓冲区读取1秒。这一秒的800毫秒%正在重新读取旧数据,200毫秒是新数据。audioToAnalyze=读取(音频缓冲区,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(audioToAnalyze(idx(1,1):idx(1,2)),fs/2;%使音频正常化。audioToAnalyze = audioToAnalyze / max (abs (audioToAnalyze));%更新分析的分段图analyzedPlot.YData=音频分析;提取特征和转置他们,使时间%在列。特点=(提取(afe audioToAnalyze) ';使特性正常化。feature = (features - normalizer . mean) ./ normalizer . standarddeviation;%调用分类以确定概率和%获奖标签。特性(isnan(特性))= 0;(标签,聚合氯化铝)= (bestNet、特性)进行分类;%更新概率和获胜的情节%的标签。probabilityPlot。YData =聚合氯化铝;写(predictionBuffer,聚合氯化铝);如果predictionBuffer.NumUnreadSamples==predictionBuffer.Capacity lastTen=peek(predictionBuffer);[~,decision]=max(平均值(lastTen.*hann(大小(lastTen,1)),1));probabilityAxes.Title.String=num2str(decision-1);终止终止其他的%如果信号能量低于阈值,则假定无语音%检测。probabilityAxes.Title.String ='';probabilityPlot。YData = 0.1 * 1 (1);analyzedPlot。YData = 0 (f / 2、1);重置(predictionBuffer)终止刷新屏幕limitrate终止终止

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

创建培训和验证数据集

下载自由口语数字数据集(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指向录音得到数据集的抽样率。

ads=音频数据存储(数据集文件夹,“IncludeSubfolders”,真正的);[~, adsInfo] =阅读(广告);fs = adsInfo.SampleRate;

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

[~,文件名]=cellfun(@(x)文件部分(x),ads.Files,“UniformOutput”、假);ads.Labels =分类(string (cellfun (@ (x) x(1),文件名)));

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

[adsTrain,adsValidation]=splitEachLabel(ads,0.8);

设置音频特征提取器

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

赢得=汉明(圆(0.03 * fs),“周期”); 重叠长度=圆形(0.02*fs);afe=音频特征提取程序(...“窗口”,赢了,...“OverlapLength”overlapLength,...“SampleRate”fs,......“linearSpectrum”假的,...“melSpectrum”假的,...“巴克光谱”假的,...“erbSpectrum”假的,......“mfcc”,真的,...“mfccDelta”,真的,...“mfccDeltaDelta”,真的,...“gtcc”,真的,...“gtccDelta”,真的,...“gtccDeltaDelta”,真的,......“spectralCentroid”,真的,...“幽灵休息”,真的,...“幽灵秘方”,真的,...“spectralEntropy”,真的,...“spectralFlatness”,真的,...“Spectraflux”,真的,...“spectralKurtosis”,真的,...“spectralRolloffPoint”,真的,...“spectralSkewness”,真的,...“spectralSlope”,真的,...“光谱分布”,真的,......“节”假的,...“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
最佳特征=带字段的结构: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=具有属性的音频特征提取器:属性窗口:[240×1双]重叠长度:160采样器:8000 FFT长度:[]光谱描述输入:“线性光谱”启用功能mfcc,gtcc禁用功能线性光谱、melSpectrum、barkSpectrum、erbSpectrum、mfccDelta、mfccDelta、gtccDelta、SpectrcEntroid、SpectrcRest、SpectrcAlDecrease、SpectrumalEntroid、SpectrumalTreaty Spectrum平坦度、SpectrumalFlux、SpectrumalKurtosis、SpectrumalRolloffpoint、SpectrumalSkewness、spectralSlope spectralSpread、pitch、harmonicRatio要提取特征,请将相应的属性设置为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(featuresValidation)idx=find(isnan(featuresValidation{ii}));如果~isempty(idx) featuresValidation{ii}(idx) = 0;终止终止%复制列车和验证集的标签,以便它们在%与序列一一对应。labelsTrain = adsTrain.Labels;%更新输入层的测试特性的数量。层(1)= sequenceInputLayer(大小(featuresTrain {1}, 1));%培训网络。net=列车网络(特征应变、标签序列、图层、选项);%评估网络。调用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);featuresToTest=字段名(信息(afe));N=numel(featuresToTest);bestValidationAccuracy=0;设置初始特性配置:开启向后选择%或全部关闭向前选择。功能配置=信息(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.(featuresToTest{ii})=真;其他的featureConfig。(featuresToTest {2}) = false;终止终止%循环每个特性集。对于2 = 1:元素个数(featureConfigsToTest)确定当前要测试的特性配置。更新%该功能安全。currentConfig = featureConfigsToTest {2};currentConfig集(afe)%培训并获得当前k倍交叉验证精度%的功能配置。[trueLabels predictedLabels,净,标准化者]= HelperTrainAndValidateNetwork (adsTrain、adsValidate afe,层,选项);valAccuracy =意味着(trueLabels = = predictedLabels) * 100;如果ValAccurance>bestValidationAccuracy bestValidationAccuracy=ValAccurance;bestNet=net;bestNormalizers=normalizers;终止%更新日志结果=表格(currentConfig,ValAccurance,“VariableNames”,[“功能配置”“准确性”]);日志=(日志;结果);%#好的终止%以最佳精度确定和打印设置。如果精度%没有提高,结束跑。[a, b] = max(日志{:,“准确性”});如果a<=最佳精度包装器IDX=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.(featuresToRemove{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。