主要内容

基于后期融合的声场景识别

这个例子展示了如何创建一个用于声学场景识别的多模型后期融合系统。该示例使用mel谱图训练卷积神经网络(CNN),使用小波散射训练集成分类器。该示例使用TUT数据集进行培训和评估[1]。

介绍

声场景分类(ASC)是根据环境产生的声音对环境进行分类的任务。ASC是一个通用分类问题,是设备、机器人和许多其他应用程序中上下文感知的基础[1]。ASC的早期尝试使用mel频率倒谱系数(mfcc)和高斯混合模型(GMMs)来描述它们的统计分布。ASC的其他常用特征包括过零率、光谱质心(Spectralcentroid.)、谱衰减(光谱衰减点)、谱通量(光谱通量)和线性预测系数(lpc) [5]. 训练隐马尔可夫模型(HMM)来描述GMM的时间演化。最近,性能最好的系统使用了深度学习(通常是CNN)和多个模型的融合。DCASE 2017大赛中排名靠前的系统最受欢迎的功能是mel光谱图(MELSPectRoge.).在该挑战中排名靠前的系统使用了后期融合和数据增强技术来帮助其系统推广。

为了说明一种产生合理结果的简单方法,本例使用mel谱图训练CNN,使用小波散射训练集成分类器。CNN和集成分类器的总体准确率大致相当,但在区分不同的声学场景方面表现得更好。为了提高总体精度,您可以使用后期融合来合并CNN和集成分类器结果。

加载声学场景识别数据集

要运行该示例,必须首先下载数据集[1]。完整的数据集大约为15.5 GB。根据你的电脑和互联网连接的不同,下载数据可能需要大约4个小时。

downloadFolder = tempdir;datasetFolder = fullfile (downloadFolder,“TUT-acoustic-scenes-2017”);如果~存在(datasetFolder“dir”)disp(“下载TUT-acoustic-scenes-2017 (15.5 GB)……”) HelperDownload_TUT_acoustic_scenes_2017 (datasetFolder);结束

将开发集元数据作为表读入。给表变量命名文件名AcousticScene,具体位置

metadata_train = readtable (fullfile (datasetFolder'tut-acoustic-scenes-2017-开发'“meta.txt”),......“分隔符”, {' \ t '},......“ReadVariableNames”,false);元数据\u train.Properties.VariableNames={“文件名”“声学场景”“SpecificLocation”};车长(列车)
ans = 8×3表文件名声命名____________________________________________________00.wav'} {'b020'} {'b020'} {'b020'} {b020'} {b020'}{'音频/ b020_100_110.wav'} {'beach'} {'b020'} {'audio / b020_40_50.wav'} {'b020'} {'b020'} {'audio / b020_50_60.wav'} {'海滩'} {'b020'} {'audio / b020_30_40.wav'} {'b020'} {'b020'} {'audio / b020_160_170.wav'} {'beach'} {'b020'} {'b020'} {'b020'} {'audio / b020_170_180.wav'} {'beach'} {'b020'}
metadata_test = readtable (fullfile (datasetFolder”图坦卡蒙-声场景- 2017 -评价”“meta.txt”),......“分隔符”, {' \ t '},......“ReadVariableNames”,假);元数据\u test.Properties.VariableNames={“文件名”“声学场景”“SpecificLocation”};负责人(元数据测试)
ans = 8×3表文件名AcousticScene SpecificLocation  __________________ _____________ ________________ {' 音频/ 1245. wav}{“海滩”}{‘b174}{“音频/ 1456. wav”}{“海滩”}{‘b174}{“音频/ 1318. wav”}{“海滩”}{‘b174}{“音频/ 967. wav”}{“海滩”}{‘b174}{“音频/ 203. wav”}{“海滩”}{‘b174}{“音频/ 777. wav”}{“海滩”}{‘b174} {' wav音频/ 231. '} {'beach'} {'b174'} {'audio/768.wav' } {'beach'} {'b174'}

请注意,测试集中的特定记录位置与开发集中的特定记录位置不相交。这使得验证经过训练的模型是否可以推广到实际场景更加容易。

sharedRecordingLocations =相交(metadata_test.SpecificLocation metadata_train.SpecificLocation);流('列车和测试集中特定记录位置的数量=%d\n',numel(共享记录位置))
列车和测试集中的特定录制位置数= 0

元数据表的第一个变量包含文件名。将文件名与文件路径串联。

列车文件路径=完整文件(数据集文件夹,'tut-acoustic-scenes-2017-开发', metadata_train.FileName);test_filePaths = fullfile (datasetFolder,”图坦卡蒙-声场景- 2017 -评价”元数据_test.FileName);

为列车和测试集创建音频数据存储。设置标签财产audioDatastore到声学场景。调用countEachLabel验证列车和测试集中的标签均匀分布。

adsTrain=音频数据存储(列车文件路径,......“标签”,分类(元数据列车声学场景),......“IncludeSubfolders”,真正的);显示(CountAckeLabel(adstrain))adstest = audiodatastore(test_filepaths,......“标签”,分类(元数据测试,声学场景),......“IncludeSubfolders”,真正的);显示器(countEachLabel (adsTest))
15×2表标签数  ________________ _____ 海滩312总线312咖啡馆/餐厅312车312 city_center 312 forest_path 312 grocery_store 312家312图书馆312 metro_station 312 office 312公园312 residential_area 312列车312电车312 15×2表标签数  ________________ _____ 海滩108总线108咖啡馆/餐厅108车108 city_center 108森林之路杂货店家图书馆地铁车站办公室公园住宅区火车电车

您可以减少本例中使用的数据集,以以性能为代价加快运行时间。通常,减少数据集是开发和调试的一种良好实践。集reduceDataset真正的来减少数据集。

depentataset = false;如果SDENTATASET ADSTRAIN = SPLITHEACHLABEL(adstrain,20);adstest = spliteachlabel(adstest,10);结束

调用从列车集合中获取一个文件的数据和采样率。数据库中的音频具有一致的采样率和持续时间。将音频正常化,然后收听它。显示对应的标签。

(数据、adsInfo) =阅读(adsTrain);data =有悖于/ max(数据,[],“全部”);fs=adsInfo.SampleRate;声音(数据,fs)fprintf('声学场景=%s \ n',adstrain.labels(1))
声学场景=海滩

调用重置将数据存储返回其初始条件。

重置(adsTrain)

CNN的特征提取

数据集中的每个音频剪辑由10秒的立体声(左右)音频组成。本例中的特征提取管道和CNN架构都是基于[3]的。利用系统的超参数优化工作流,对特征提取的超参数、CNN架构和训练选项进行了修改。

首先,将音频转换为中间编码。[3]表明中间编码数据提供了更好的空间信息,CNN可以使用这些信息来识别移动源(例如火车在声学场景中移动)。

dataMidSide =[总和(数据,2),数据(:1)拼(:,2)];

将信号分为1秒重叠段。最终系统使用1秒段的概率加权平均值预测测试集中每10秒音频片段的场景。将音频片段分为1秒段使网络更易于训练,并有助于防止网络中的特定声学事件过度拟合训练集。重叠有助于确保训练数据捕获彼此相关的所有特征组合。它还为系统提供额外的数据,这些数据可以在增强过程中唯一地混合。

segmentLength = 1;segmentOverlap = 0.5;[dataBufferedMid, ~] =缓冲区(dataMidSide(: 1),圆(segmentLength * fs),圆(segmentOverlap * fs),“nodelay”);[dataBufferedSide,~]=缓冲区(dataMidSide(:,2),圆形(segmentLength*fs),圆形(segmentOverlap*fs),“nodelay”); 数据缓冲=零(大小(数据缓冲,1),大小(数据缓冲,2)+大小(数据缓冲,2));数据缓冲(:,1:2:end)=数据缓冲;数据缓冲(:,2:2:end)=数据缓冲区;

使用MELSPectRoge.将数据转换为紧凑的频域表示。按照[3]的建议定义mel谱图的参数。

windowlength = 2048;Samplesperhop = 1024;Samplesoverlap = windowlength  -  Samplesperhop;fftlength = 2 * windowlength;numbands = 128;

MELSPectRoge.独立地沿通道操作。为了优化处理时间,请调用MELSPectRoge.整个缓冲信号。

spec=光谱图(数据缓冲,fs,......'窗户'汉明(windowLength“周期”),......“OverlapLength”samplesOverlap,......“FFTLength”fftLength,......“麻木人”,麻木);

将MEL谱图转换为对数标度。

规范= log10(规范+ eps);

将数组整形为维度(带数)-按-(跳数)-按-(通道数)-按-(段数)。当你将一个图像输入神经网络时,前两个维度是图像的高度和宽度,第三个维度是通道,第四个维度将单个图像分离。

X =重塑(规格、尺寸(规范,1),大小(规范,2),大小(数据,2),[]);

调用MELSPectRoge.没有输出参数来绘制1秒增量的前6个中间通道的MEL谱图。

图melSpectrogram(dataBuffered(:,channel),fs,......'窗户'汉明(windowLength“周期”),......“OverlapLength”samplesOverlap,......“FFTLength”fftLength,......“麻木人”,numBands);标题(sprintf(”段% d ',ceil(频道/2)))结束

辅助功能HelperSegmentedMelSpectrograms执行上面概述的特征提取步骤。

为加快处理速度,提取数据存储中所有音频文件的音频谱图数组。与内存中的数组不同,在您请求使用收集功能。此延迟评估使您可以使用大数据集快速工作。当您最终请求输出时收集,Matlab在可能的情况下结合了排队的计算,并通过数据占据最小次数。如果您有并行计算工具箱™,则可以在本地MATLAB会话中或在本地并行池中使用高阵列。如果安装了MATLAB®PartinalServer™,您还可以在群集中运行高阵列计算。

如果没有并行计算工具箱™, 本例中的代码仍在运行。

pp = parpool(“空闲时间”,inf);训练集高=高(adsTrain);xTrain=cellfun(@(x)HelperSegmentedMelSpectrograms(x,fs,......“分段长度”,分段长度,......“SegmentOverlap”,分段重叠,......“窗口长度”,窗长,......'hoplength',samplesPerHop,......“麻木人”,麻木,......“FFTLength”,fft长度),......火车站高,......“UniformOutput”、假);xTrain =收集(xTrain);xTrain =猫(4,xTrain {:});test_set_tall =高(adsTest);xTest = cellfun (@ (x) HelperSegmentedMelSpectrograms (x, fs,......“分段长度”,分段长度,......“SegmentOverlap”,分段重叠,......“窗口长度”,窗长,......'hoplength',samplesPerHop,......“麻木人”,麻木,......“FFTLength”,fft长度),......test_set_tall,......“UniformOutput”、假);xtest =聚集(xtest);xtest = cat(4,xtest {:});
正在使用连接到并行池的“本地”配置文件启动并行池(parpool)(工作线程数:6).使用并行池“本地”评估tall表达式:-第1次通过,共1次:在3分钟45秒内完成评估在3分钟45秒内完成使用并行池“本地”评估tall表达式:-第1次通过,共1次:在1分钟22秒内完成评估在1分钟22秒内完成

复制训练集的标签,使它们与段一一对应。

numSegmentsPer10seconds=大小(数据缓冲,2)/2;yTrain=repmat(adsTrain.Labels,1,numsegmentsper10秒);yTrain=yTrain(:);

CNN的数据增强

DCASE 2017数据集包含任务的相对较少的声学记录,并且开发集和评估集记录在不同的特定位置。因此,在培训期间很容易过度拟合数据。减少过度拟合的一种流行方法是混淆。在“混合”中,通过混合两个不同类的功能来扩充数据集。混合功能时,将按相等比例混合标签。即:

$$\begin{array}{l}\tilde{\mathrm{x}}=\lambda{\mathrm{x}}}{i+\left(1-\lambda&{xA;\right){\mathrm{x}}}{\tilde{y}=\lambda y}\i+\left(1-\lambda\right)y}\end{array}$$

通过从概率分布而不是混合标记汲取的标记,通过[2]重新加入混合物。在该示例中的混合物的实现是混合的简化版本:将每个频谱图与不同标签的谱图混合,其中Lambda设置为0.5。原始和混合数据集组合用于培训。

xTrainExtra = xTrain;yTrainExtra = yTrain;λ= 0.5;i=1:尺寸(xTrain,4)%查找具有不同标签的所有可用光谱图。availableSpectrograms=find(yTrain~=yTrain(i));%在可用的光谱图中随机选择一个不同的标签。numAvailableSpectrograms=numel(可用spectrograms);idx=randi([1,numAvailableSpectrograms]);%混合。XtrainExtra(:,::,i)= lambda * xtrain(::::,i)+(1-lambda)* xtrain(:,:,:,availableSpectRoge(IDX));%指定由lambda随机设置的标签。如果rand>lambda yTrainExtra(i)=yTrain(可用的谱图(idx));结束结束xTrain=cat(4,xTrain,xTrainExtra);yTrain=[yTrain;yTrainExtra];

调用概括显示扩展训练集的标签分布。

总结(yTrain)
海滩公共汽车咖啡馆/餐厅汽车城市中心森林小路杂货店家庭图书馆地铁车站办公公园住宅区火车有轨电车

定义和培训CNN

定义CNN架构。该体系结构基于[1],并经过反复试验进行了修改。看到深度学习层名单(深度学习工具箱)了解更多关于MATLAB®中可用的深度学习层。

imgSize=[size(xTrain,1),size(xTrain,2),size(xTrain,3)];numF=32;层=[......imageInputLayer(imgSize)批规格化层卷积2DLayer(3,numF,“填充”“相同”) batchNormalizationLayer reluLayer卷积2dlayer (3,numF,“填充”“相同”maxPooling2dLayer(3,“步”2.“填充”“相同”) convolution2dLayer (3 2 * numF“填充”“相同”)BatchnormalizationLayer Rufulayer卷积2dlayer(3,2 * numf,“填充”“相同”maxPooling2dLayer(3,“步”2.“填充”“相同”)卷积2层(3,4*numF,“填充”“相同”) batchNormalizationLayer reluLayer卷积2dlayer (3,4*numF,“填充”“相同”maxPooling2dLayer(3,“步”2.“填充”“相同”) convolution2dLayer (3 8 * numF,“填充”“相同”)batchNormalizationLayer reluLayer卷积2Dlayer(3,8*numF,“填充”“相同”) batchNormalizationLayer reluLayer globalAveragePooling2dLayer dropoutLayer(0.5) fulllyconnectedlayer (15) softmaxLayer classificationLayer];

定义trainingOptions(深度学习工具箱)美国有线电视新闻网。这些选项基于[3],并通过系统的超参数优化工作流进行修改。

miniBatchSize=128;tuneme=128;lr=0.05*miniBatchSize/tuneme;选项=培训选项(“sgdm”......“初始学习率”,lr,......'minibatchsize',小批量,......“动力”,0.9,......'L2Regularization',0.005,......“MaxEpochs”8......'洗牌'“every-epoch”......“阴谋”“训练进步”......“冗长”假的,......“LearnRateSchedule”“分段”......“LearnRateDropPeriod”2.......“LearnRateDropFactor”, 0.2);

调用列车网络(深度学习工具箱)训练网络。

TrousaInnet = Trainnetwork(XTrain,Ytrain,图层,选项);

评价CNN

调用预测(深度学习工具箱)使用HALT-OUT测试集预测训练网络的响应。

cnnResponsesPerSegment =预测(trainedNet xTest);

平均每个10秒的音频剪辑。

类= trainedNet.Layers . class(结束);numFiles =元素个数(adsTest.Files);counter = 1;cnnResponses = 0 (numFiles元素个数(类));channel = 1:numFiles cnnResponses(channel,:) = sum(cnnResponsesPerSegment(counter:counter+numSegmentsPer10seconds-1,:),1)/numSegmentsPer10seconds;counter = counter + numsegmentsper10秒;结束

对于每个10秒的音频剪辑,选择预测的最大值,然后将其映射到相应的预测位置。

[〜,classidx] = max(cnnresponses,[],2);cnnpredictedlabels =类(classidx);

调用confusionchart(深度学习工具箱)将测试集上的精度可视化。将平均精度返回到命令窗口。

身材(“单位”“归一化”“位置”,[0.2 0.2 0.5 0.5]) cm = confusionchart(adsTest。标签,cnnPredictedLabels,“标题”“测试准确性-CNN”); cm.摘要=“column-normalized”; cm.RowSummary=“行规范化”;fprintf('CNN的平均准确性=%0.2F \ n',意味着(adsTest.Labels = = cnnPredictedLabels) * 100)
CNN的平均准确性= 73.33

Ensemble分类器的功能提取

[4]中已经展示了小波散射,以提供声学场景的良好表示waveletScattering(小波工具箱)目的:通过反复试验确定不变性量表和质量因子。

sf=小波模式(“SignalLength”,大小(数据,1),......'采样频率',财政司司长,......'invariarcescale', 0.75,......“QualityFactors”(4 - 1));

将音频信号转换为单声道,然后调用featureMatrix(小波工具箱)为了返回散射分解框架的散射系数,科幻小说

dataMono =意味着(数据,2);dataMono scatteringCoeffients = featureMatrix(科幻小说,“转变”“日志”);

平均10秒音频剪辑上的散射系数。

featureVector =意味着(scatteringCoeffients, 2);流('每10秒剪辑的小波特征数= %d\n'元素个数(featureVector))
每10秒剪辑的小波特征数= 290

辅助功能HelperWaveletFeatureVector执行上述步骤。使用一个数组与赛尔芬HelperWaveletFeatureVector平行化特征提取。提取列车和测试集的小波特征向量。

散射棘手= Cellfun(@(x)HelperWaveRetFeatureVector(x,sf),train_set_tall,“UniformOutput”、假);xTrain =收集(scatteringTrain);xTrain = cell2mat (xTrain ') ';scatteringTest = cellfun (@ (x) HelperWaveletFeatureVector (x,科幻小说),test_set_tall,“UniformOutput”、假);xTest =收集(scatteringTest);xTest = cell2mat (xTest ') ';
使用并行池“本地”评估高表达: - 通过1:25分钟内完成的1/5秒评估,在25分钟内完成使用并行池“本地”评估高表达式: -  PASS 1,共1分:在8中完成分2秒评估在8分2秒内完成

定义和训练集成分类器

使用fitcensemble.创建培训的分类集合模型(分类符号).

子空间维度=最小值(150,大小(xTrain,2)-1);numLearningCycles=30;ClassificationnSemble=fitcensemble(xTrain,adsTrain.Labels,......“方法”“子空间”......'numlearnicalnycle'numLearningCycles,......“学习者”“歧视性”......“NPredToSample”,子空间维数,......“类名”,removecats(唯一(adstrain.labels)));

评价集成分类器

对于每10秒的音频剪辑,请调用预测返回标签和权重,然后将其映射到相应的预测位置。调用confusionchart(深度学习工具箱)使测试集的准确性可视化。打印的平均。

[小波预测标签,小波响应]=预测(ClassificationInsemble,xTest);图(“单位”“归一化”“位置”,[0.2 0.2 0.5 0.5])cm=混淆图(adsTest.标签,小波预测标签,“标题”'测试精度 - 小波散射'); cm.摘要=“column-normalized”; cm.RowSummary=“行规范化”;fprintf('分类器的平均精度=%0.2f\n',意味着(adsTest.Labels = = waveletPredictedLabels) * 100)
分类器的平均精度= 76.05

应用后期融合

对于每10秒的剪辑,调用小波分类器上的predict,CNN返回一个向量,表示他们的决策的相对可信度waveletResponsescnnResponses创建一个后期融合系统。

融合=小波响应。*cnnResponses;[~,classIdx]=max(融合,[],2);预测标签=类(classIdx);

评估晚融合

调用confusionchart可视化融合分类精度。将平均精度打印到命令窗口。

身材(“单位”“归一化”“位置”,[0.2 0.2 0.5 0.5]) cm = confusionchart(adsTest。标签,predictedLabels,“标题”“测试精度-融合”); cm.摘要=“column-normalized”; cm.RowSummary=“行规范化”;fprintf('融合模型的平均精度= %0.2f\n',平均(adstest.labels == predightlabels)* 100)
融合模型的平均精度= 78.21

关闭平行池。

删除(pp)
使用“本地”配置文件的并行池正在关闭。

参考文献

[1] A. Mesaros,T. Heittola和T.Virtanen。声场分类:DCEAD 2017挑战条目的概述。在proc。国际车间关于声学信号增强,2018。

[2] 混搭:依赖数据的数据增强〉《推断》,2017年11月3日,2019年1月15日访问。https://www.inference.vc/mixup-data-dependent-data-augmentation/

[3]韩允昌、朴正洙、李京九声学场景和事件的检测与分类(DCASE)(2017): 1-5。

[4] Lostanlen,Vincent和Joakim Anden.小波散射双耳场景分类.技术报告,DCASE2016挑战,2016。

A. J. Eronen, V. T. Peltonen, J. T. Tuomi, A. P. Klapuri, S. Fagerlund, T. Sorsa, G. Lorho, and J. Huopaniemi,“基于音频的上下文识别”,IEEE Trans。《音频、语音和语言处理》,第14卷,第2期。1,页321-329,2006年1月。

[6]TUT声学场景2017,开发数据集

[7]TUT声学场景2017,评估数据集

附录—支持功能万博1manbetx

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%allersegmentedmelspectregregs.函数X=HelperSegmentedMelSpectrograms(X,fs,varargin)p=inputParser;addParameter(p,“窗口长度”, 1024);addParameter (p,'hoplength', 512);addParameter (p,“麻木人”, 128);addParameter (p,“分段长度”1);addParameter (p,“SegmentOverlap”, 0);addParameter (p,“FFTLength”,1024);parse(p,varargin{:})params=p.Results;x=[sum(x,2),x(:,1)-x(:,2)];x=x./max(max(x));[xb_m,~]=buffer(x(:,1),round(params.SegmentLength*fs),round(params.SegmentOverlap*fs),“nodelay”); [xb_s,~]=缓冲区(x(:,2),圆形(参数分段长度*fs),圆形(参数分段重叠*fs),“nodelay”); xb=零(大小(xb_m,1),大小(xb_m,2)+大小(xb_s,2));xb(:,1:2:end)=xb_m;xb(:,2:2:end)=xb_s;spec=光谱图(xb,fs,......'窗户',hamming(参数窗长,“周期”),......“OverlapLength”,params.WindowLength-params.HopLength,......“FFTLength”,参数FFTLENGHT,......“麻木人”,参数个数。NumBands,......“频率范围”[0,地板(fs / 2)));规范= log10(规范+ eps);X =重塑(规格、尺寸(规范,1),大小(规范,2),大小(X, 2), []);结束%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HelperWaveletFeatureVector函数feature = helperwaveetfeaturevector (x,sf) x = mean(x,2);特点= featureMatrix(科幻,x,“转变”“日志”);特征=平均值(特点,2);结束%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%