在本例中,您训练三个卷积神经网络(cnn)来执行说话人验证,然后比较架构的性能。三个cnn的架构都是等效的,除了每个cnn的第一卷积层:
在第一架构中,第一个卷积层是使用的“标准”卷积层,使用convolution2dLayer
.
在第二个体系结构中,第一个卷积层是一个常数sinc滤波器组,使用自定义层实现。
在第三架构中,第一个卷积层是使用自定义层实现的培训inst referbank。该架构被称为SINCNET.[1].
[1]显示用滤波器层替换标准卷积层,导致更快的训练收敛性和更高的准确性。[1]还表明,使滤波器组的参数是可学习的,产生额外的性能增益。
扬声器识别是一个突出的研究区域,具有各种应用,包括取证和生物识别认证。许多扬声器识别系统依赖于预先计算的特征,例如I-Vectors或MFCC,然后将其送入机器学习或深度学习网络以进行分类。其他深度学习语音系统绕过特征提取级并将音频信号直接送入网络。在这种端到端系统中,网络直接学习低级音频信号特性。
在此示例中,您首先培训传统的端到端扬声器识别CNN。滤波器学到往往具有随机形状,不对应人类耳朵如何工作的感知证据或知识,特别是在培训数据量有限的情况下[1]。然后,将网络中的第一个卷积层替换为自定义sinc filterbank层,该层基于感知证据引入结构和约束。最后,培训SincNet体系结构,从而为sinc filterbank参数增加可学习性。
在该示例中探索的三种神经网络架构总结如下:
标准卷积神经网络- 输入波形直接连接到随机初始化的卷积层,该层试图从原始音频帧中学习功能和捕获特征。
ConstantsInclayer.- 输入波形,通过一组固定宽度SINC功能(带通滤波器)卷积在MEL刻度上。
SincNetLayer- 输入波形与一组SINC函数进行卷积,该函数由网络学习的参数。在SINCNET架构中,网络调谐训练时SINC功能的参数。
此示例定义并列举上面提出的三个神经网络,并在LibrisPeech数据集上评估其性能[2].
在本例中,您使用了LibriSpeech数据集的一个子集[2].LibriSpeech数据集是一个以16khz采样的阅读英语语音的大型语料库。数据来源于从LibriVox项目中阅读的有声读物。
downloadDatasetFolder = tempdir;文件名=“火车——清洁- 100. tar.gz”;网址=“http://www.openslr.org/resources/12/”+文件名;datasetFolder = fullfile (downloadDatasetFolder,“librispeech”那“火车清洁-100”);如果〜ISFolder(DataSetFolder)Gunzip(URL,DownloadDataSetFolder);UnzippedFile = fullfile(downloaddatasetfolder,filename);Untar(解析文件{1}(1:end-3),downloaddatasetfolder);结束
创建一个audiodatastore.
对象访问LibriSpeech音频数据。
广告= audiodataStore(DataSetFolder,“IncludeSubfolders”1);
从文件路径中提取扬声器标签。
Ads.Labels = Extractbetween(Ads.files,FullFile(DataSetFolder,Filesep),FileSEP);
完整的dev-train-100
数据集是约6 GB的数据。使用来自所有251个扬声器的数据训练网络,设置reduceDataset
到假
.要使用来自六个扬声器的数据快速运行此示例,请设置reduceDataset
到真正的
.
recloddataset =假;如果简化数据集索引=cellfun(@(c)str2double(c)<50,ADS.Labels);%#好的广告=子集(广告,指数);结束广告= splitEachLabel(广告,0.1);
将音频文件拆分为培训和测试数据。80%的音频文件被分配给训练集,20%分配给测试集。
[ADSTrain, ADSTest] = splitEachLabel(广告,0.8);
绘制一个音频文件并收听它。
[AudioIn,DsInfo] =读(adstrain);FS = DSINFO.SAMPLEDE;声音(AUDION,FS)T =(1 / FS)*(0:长度(AUDION)-1);plot(t,audioin)标题(“音频样本”)包含(“时间(s)”) ylabel (“振幅”) 网格在
重置训练数据存储。
重置(ADSTrain)
CNNS预计输入要具有一致的维度。您将通过删除静音区域并将其余的语音与40毫秒重叠中的剩余语音将其余的语音分解为200ms帧。
设置预处理的参数。
帧持续时间=200e-3;重叠持续时间=40e-3;帧长=楼层(Fs*帧持续时间);重叠长度=圆形(Fs*重叠持续时间);
使用支持功能,金宝appPreprocessAudiodata.,预处理培训和测试数据。XTrain.
和XTest.
分别包含训练和测试语音帧。YTrain
和欧美
分别包含火车和测试标签。
[Xtrain,YTrain] =预处理童话机(adstrain,frameLength,verlageplength,fs);
使用“local”配置文件启动并行池(parpool)…连接到并行池(工作人员数量:6)。
[xtest,ytest] = preprocessaudiodata(adstest,frameLength,overtaplenth,fs);
标准的CNN是受到神经网络架构的启发[1].
numFilters = 80;filterLength = 251;numSpeakers =元素个数(独特(ADS.Labels));[imageInputLayer([1 frame ength 1])] / /帧长度%第一卷积层卷积2dlayer ([1 filterLength],numFilters) batchNormalizationLayer leakyReluLayer(0.2) maxPooling2dLayer([1 3])%该层后面是2个卷积层卷积2dlayer ([1 5],60) batchNormalizationLayer leakyReluLayer(0.2) maxPooling2dLayer([1 3])卷积2dlayer ([1 5],60) batchNormalizationLayer leakyReluLayer(0.2) maxPooling2dLayer([1 3])%后面是3个完全连接的层全连接层(256)BatchnormalizationLayer LiquidyLultulayer(0.2)全连接列(256)BatchnormalizationLayer Liquidyrelayer(0.2)全连接列(256)BatchnormalizationLayer Leatolylayer(0.2)全连接层(NumSpeakers)SoftmaxLayer分类层];
使用的方法分析神经网络的层次分析
函数
分析网络(层)
用神经网络训练15个阶段的神经网络亚当
优化。在每个时代之前洗牌训练数据。使用神经网络的培训选项trainingOptions
.使用测试数据作为验证数据,以观察网络性能如何提高,因为培训进展。
numepochs = 15;minibatchsize = 128;验证频率=地板(Numel(YTrain)/小型匹配);选项=培训选项(“亚当”那......“洗牌”那“每个时代”那......“MiniBatchSize”,小匹马,......“情节”那“培训 - 进展”那......“verbose”假的,“最大时代”,努梅波克斯,......“validationdata”{XTest,直言(欧美)},......“验证职业”, validationFrequency);
培训网络,呼叫trainNetwork
.
[Convnet,ConvnetInfo] = Trainnetwork(XTrain,Ytrain,图层,选项);
从标准CNN网络中了解的九个过滤器的幅度频率响应。这些过滤器的形状不是直观的,并且不对应于感知知识。下一节探讨了使用约束滤波器形状的效果。
f =挤压(ConvNet.Layers(2,1)。重量);h =零(尺寸(f));freq = zeros(尺寸(f));为了II = 1:尺寸(f,2)[h,f] = freqz(f(:,ii),1,251,fs);h(:,ii)= abs(h);弗雷克(:,ii)= f;结束idx = linspace(1、大小(F, 2), 9);idx =圆(idx);数字为了JJ = 1:9子图(3,3,JJ)绘图(频率(:,idx(jj)),h(:,idx(jj)))sgtitle(“学习标准CNN滤波器的频率响应”)包含(“频率(Hz)”)结束
在本节中,您将用一个常数sinc滤波器组层替换标准CNN中的第一个卷积层。常数sinc滤波器组层将输入帧与一组固定带通滤波器进行卷积。带通滤波器是两个sinc滤波器在时域的线性组合。带通滤波器的频率在mel尺度上是线性间隔的。
恒定sinc滤波器组层的实现可以在ConstantsInclayer.m.
文件(附加到此示例)。定义一个参数ConstantsInclayer.
.使用80个过滤器,过滤器长度为251。
numFilters = 80;filterLength = 251;numchannels = 1;名称=“constant_sinc”;
将第一个卷积层从标准CNN改变为ConstantsInclayer.
并保持其他层保持不变。
CSL = ConstantsInclayer(NumFilters,FilterLength,FS,NumChannels,Name)
cSL = constantSincLayer with properties: Name: 'constant_sinc' NumFilters: 80 SampleRate: 16000 FilterLength: 251 NumChannels: [] Filters: [1×251×1×80 single] MinimumFrequency: 50 MinimumBandwidth: 50 startfrequency: [1×80 double] bandwidth: [1×80 double]显示所有属性
层(2)= CSL;
使用trainNetwork
功能。使用先前定义的相同培训选项。
[constSincNet,constSincInfo]=列车网络(XTrain,YTrain,层,选项);
这Plotnfilters.
该方法绘制了地震波的幅频响应N
过滤器具有同等间隔的滤波器指标。绘制九个过滤器的幅度频率响应ConstantsInclayer.
.
图n = 9;plotNFilters (constSincNet.Layers (2), n)
在本节中,您可以使用培训的真实层作为网络中的第一个卷积图层。SINCNET层将输入帧与带通滤波器组旋转。SINCNET滤波器的带宽和初始频率被初始化,如MEL刻度上等等。SINCNET层试图了解神经网络框架内的这些带通滤波器的更好参数。
可以在“上”中找到SincNet Layer FilterBank层的实现SINCNETLAYER.M.
文件(附加到此示例)。定义一个参数SincNetLayer
.使用80个过滤器,过滤器长度为251。
numFilters = 80;filterLength = 251;numchannels = 1;名称='sinc';
更换ConstantsInclayer.
从以前的网络与SincNetLayer
.这层新图层有两个可学习的参数:滤波频率
和过滤带宽
.
SNL = SINGNETLAYER(NUMFILTERS,FilterLength,FS,NumChannels,Name)
sNL = sincNetLayer with properties: Name: 'sinc' NumFilters: 80 SampleRate: 16000 FilterLength: 251 NumChannels: [] Window: [1×251 double] TimeStamps: [1×251 double] MinimumFrequency: 50 MinimumBandwidth: 50 Learnable Parameters FilterFrequencies: [1×80 double] filterbandwidth: [1×80 double]显示所有属性
层(2)=sNL;
使用trainNetwork
功能。使用先前定义的相同培训选项。
[sincnet,sincnetinfo] = Trainnetwork(Xtrain,Ytrain,图层,选项);
使用Plotnfilters.
的方法SincNetLayer
以SINCNET学习的同等间隔指数可视化九个过滤器的幅度频率响应。
图Plotnfilters(SINCNET.Layers(2),9)
该表总结了所有三个神经网络的帧准确性。
网络类型={“标准CNN”那“恒Sinc层”那'sincnet layer'} ';精度= [convNetInfo.FinalValidationAccuracy; constSincInfo.FinalValidationAccuracy sincNetInfo.FinalValidationAccuracy];resultsSummary =表(NetworkType、准确性)
结果umary =3×2表NetworkType准确性 _______________________ ________ {' 72.97标准CNN”}{“常数Sinc层”}74.902 78.062 {SincNet层的}
绘制测试集的准确性,针对纪元数量,看看网络的学习程度如何增加。SINCNET优于这一点ConstantsInclayer.
网络,特别是在培训的早期阶段。这表明,在神经网络框架内更新带通滤波器的参数导致更快的收敛。只有在数据集足够大时才会观察到此行为,因此可能无法看到逃守血统
设置为真正的
.
epoch=linspace(0,numEpochs,numel(sincNetInfo.validationaccurcy(~isnan(sincNetInfo.validationaccurcy));epoch=[epoch,numEpochs];sinc_valAcc=[sincNetInfo.validationaccurcy(~isnan(sincNetInfo.validationaccurcy)),......SINCNETINFO.FINALV alidationAccuracy];const_sinc_valacc = [constsincinfo.validationAccuracy(〜isnan(constsincinfo.validationActionAccuracy)),......constsincinfo.finalValidationAccuracy];conv_valacc = [convnetinfo.validationAccuracy(〜isnan(commnetInfo.validationAccuracy)),......commnetinfo.finalValidationAccuracy];图绘图(epoch,sinc_valacc,' - *'那“MarkerSize”,4)持有在plot(epoch,const_sinc_valacc,' - *'那“MarkerSize”,4)绘图(纪元、conv_valAcc、,' - *'那“MarkerSize”,4)ylabel('帧级精度(测试集)')包含(“时代”)xlim([0 numEpochs+0.3])标题(“帧级精度与Epoch”) 传奇(“新浪网”那“persitantsinclayer”那“conv2dlayer”那“位置”那“东南”) 网格在
在上图中,最终帧精度与上一次迭代中计算的帧精度略有不同。在培训期间,批标准化层对小批执行标准化。但是,在训练结束时,批处理规范化层对整个训练数据进行规范化,这会导致性能略有变化。
函数[X,Y]=预处理音频数据(ADS、SL、OL、Fs)如果~ isempty(版本(“平行”))pool=gcp;numPar=numpartitions(ADS,pool);其他的numpar = 1;结束议案II = 1:numpar x = zeros(1,sl,1,0);y =零(0);subads = partition(广告,numpar,ii);而hasdata(subADS) [audioIn,dsInfo] = read(subADS);speechIdx = detectSpeech (audioIn, Fs);numChunks =大小(speechIdx, 1);audioData = 0 (SL, 1,0);为了Chunk = 1:NumChunks%删除跟踪结束音频audio_chunk = audioIn (speechIdx(块,1):speechIdx(块,2));audio_chunk =缓冲区(SL, audio_chunk OL);q =大小(audio_chunk, 2);%将音频分割为200毫秒的块音频块=重塑(音频块,1,SL,1,q);%与现有音频连接audioData =猫(4 audioData audio_chunk);结束audioLabel = str2double (dsInfo.Label {1});%通过复制矩阵生成培训和测试的标签Audiolabelstrain = Repmat(Audiolabel,1,尺寸(Audiodata,4));%将当前说话人的数据点添加到现有数据X=cat(4,X,音频数据);Y=cat(2,Y,音频标签系列);结束XC {II} = X;yc {ii} = y;结束X=cat(4,XC{:});Y=cat(2,YC{:});Y=categorical(Y);结束
[1] M. Ravanelli和Y. Bengio,“用SincNet从原始波形中识别说话人”,2018 IEEE口语技术研讨会(SLT),雅典,希腊,2018年,第1021-1028页,DOI:10.1109 / SLT.2018.8639585。
[2] V.Panayotov,G. Chen,D. Povey和S. Khudanpur,“LibrisPeech:基于公共领域的ASR语料库,”2015 IEEE声学,语音和信号处理国际会议(ICASSP),布里斯班,QLD, 2015, pp. 5206-5210, doi: 10.1109/ICASSP.2015.7178964