主要内容

使用自定义自信网络层和深度学习识别说话人

在本例中,您训练三个卷积神经网络(cnn)来执行说话人验证,然后比较架构的性能。三个cnn的架构都是等效的,除了每个cnn的第一卷积层:

  1. 在第一架构中,第一卷积层是“标准”卷积层,使用convolution2dLayer

  2. 在第二个体系结构中,第一个卷积层是一个常数sinc滤波器组,使用自定义层实现。

  3. 在第三个架构中,第一个卷积层是一个可训练的sinc滤波器组,使用自定义层实现辛克内特[1]

[1]结果表明,用滤波器组层代替标准卷积层可以加快训练收敛速度和提高精度。[1]还表明,使滤波器组的参数可学习可产生额外的性能增益。

介绍

说话人识别是一个重要的研究领域,有各种各样的应用,包括取证和生物特征认证。许多说话人识别系统依赖于预计算的特征,如i向量或MFCC,然后将其输入机器学习或深度学习网络进行分类。其他深度学习语音系统绕过特征提取阶段,将音频信号直接输入网络。在这种端到端系统中,网络直接学习低级音频信号特征。

在本例中,您首先训练传统的端到端说话人识别CNN。学习的过滤器往往具有随机形状,与感知证据或人类耳朵如何工作的知识不一致,尤其是在训练数据量有限的场景中[1].然后用自定义sinc滤波器组层替换网络中的第一个卷积层,该层引入了基于感知证据的结构和约束。最后,训练SincNet体系结构,它增加了sinc滤波器组参数的易学性。

示例中探索的三种神经网络架构总结如下:

  1. 标准卷积神经网络-输入波形直接连接到一个随机初始化的卷积层,该卷积层试图从原始音频帧中学习特征并捕获特征。

  2. 康斯坦丁克莱尔-输入波形与一组固定宽度的sinc函数(带通滤波器)进行卷积,这些函数在mel标度上等距分布。

  3. SincNetLayer-输入波形与一组sinc函数卷积,其参数由网络学习。在SincNet体系结构中,网络在训练时调谐sinc功能的参数。

本例定义并训练了上述三个神经网络,并在LibriSpeech数据集上评估了它们的性能[2]

数据集

下载数据集

在本例中,您使用了LibriSpeech数据集的一个子集[2].LibriSpeech数据集是一个以16khz采样的阅读英语语音的大型语料库。数据来源于从LibriVox项目中阅读的有声读物。

downloadDatasetFolder = tempdir;文件名=“火车——清洁- 100. tar.gz”;url ="http://www.openSLR.org/resources/12/"+文件名;datasetFolder = fullfile (downloadDatasetFolder,“LibriSpeech”,“列车清洁-100”);如果~isfolder(datasetFolder)gunzip(url,downloadDatasetFolder);unzip文件=fullfile(downloadDatasetFolder,filename);untar(unzip文件{1}(1:end-3),downloadDatasetFolder);结束

创建一个音频数据存储对象访问LibriSpeech音频数据。

ADS=音频数据存储(数据集文件夹,“IncludeSubfolders”1);

从文件路径中提取扬声器标签。

ADS.Labels=extractBetween(ADS.Files,fullfile(datasetFolder,filesep),filesep);

完整的dev-train-100数据集大约有6GB的数据。要使用来自所有251个扬声器的数据训练网络,请设置reduceDataset.要使用来自六个扬声器的数据快速运行此示例,请设置reduceDataset真正的

简化数据集=如果reducedDataSet indices = cellfun(@(c)str2double(c)<50,ADS.Labels);%#嗯ADS=子集(ADS,索引);结束广告= splitEachLabel(广告,0.1);

将音频文件拆分为培训和测试数据。80%的音频文件分配给培训集,20%分配给测试集。

[ADSTrain, ADSTest] = splitEachLabel(广告,0.8);

语音信号样本

绘制一个音频文件并收听。

[audioIn,dsInfo]=读取(ADSTrain);Fs=dsInfo.SampleRate;声音(audioIn,Fs)t=(1/Fs)*(0:长度(audioIn)-1);绘图(t,audioIn)标题(“音频样本”)包含(“时间(s)”) ylabel (“振幅”)网格

重置训练数据存储。

重置(ADSTrain)

数据预处理

CNN期望输入具有一致的维度。您将通过删除静音区域对音频进行预处理,然后将剩余语音分解为200毫秒帧,重叠40毫秒。

设置预处理的参数。

frameDuration = 200 e - 3;overlapDuration = 40 e - 3;frameLength =地板(Fs * frameDuration);overlapLength =圆(Fs * overlapDuration);

使用支持功能,金宝app预处理音频数据,对训练和测试数据进行预处理。XTrain克斯特分别包含训练和测试语音帧。YTrain欧美分别包含列车和测试标签。

[XTrain,YTrain]=预处理音频数据(ADSTrain,帧长,重叠长度,Fs);
使用“local”配置文件启动并行池(parpool)…连接到并行池(工作人员数量:6)。
[XTest,YTest]=预处理音频数据(ADSTest,帧长,重叠长度,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个完全连接的层fullyConnectedLayer(256)batchNormalizationLayer leakyReluLayer(0.2)fullyConnectedLayer(256)batchNormalizationLayer leakyReluLayer(0.2)fullyConnectedLayer(256)batchNormalizationLayer leakyReluLayer(0.2)fullyConnectedLayer(numSpeakers)softmaxLayer classificationLayer];

使用的方法分析神经网络的层次分析网络函数

analyzeNetwork(层)

列车网络

使用。训练15个纪元的神经网络亚当优化。在每个历元之前洗牌训练数据。神经网络的训练选项是使用trainingOptions. 将测试数据用作验证数据,以观察网络性能如何随着培训的进行而提高。

numEpochs=15;miniBatchSize=128;验证频率=楼层(numel(YTrain)/最小批量大小);选项=培训选项(“亚当”,...“洗牌”,“每个时代”,...“MiniBatchSize”,小批量,...“情节”,“培训进度”,...“冗长”假的,“MaxEpochs”numEpochs,...“验证数据”{XTest,直言(欧美)},...“验证频率”, validationFrequency);

要训练网络,请致电trainNetwork

[convNet,convNetInfo]=列车网络(XTrain,YTrain,图层,选项);

检查第一卷积层的频率响应

绘制从标准CNN网络学习的九个滤波器的幅频响应。这些过滤器的形状不是直观的,也不符合感知知识。下一节将探讨使用约束过滤器形状的效果。

F=挤压(convNet.Layers(2,1).重量);H=零(大小(F));Freq=零(大小(F));对于ii=1:size(F,2)[h,F]=freqz(F(:,ii),1251,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 Filterbank

在本节中,您将用一个常数sinc滤波器组层替换标准CNN中的第一个卷积层。常数sinc滤波器组层将输入帧与一组固定带通滤波器进行卷积。带通滤波器是两个sinc滤波器在时域的线性组合。带通滤波器的频率在mel尺度上是线性间隔的。

定义层

实现常数sinc滤波器组层可以在康斯坦丁克莱尔文件(附在此示例中)。定义康斯坦丁克莱尔.使用80个过滤器,过滤器长度为251。

numFilters=80;过滤器长度=251;numChannels=1;名字=“constant_sinc”

将第一个卷积层从标准CNN更改为康斯坦丁克莱尔并保持其他层不变。

cSL=ConstantsClayer(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] = trainNetwork (XTrain、YTrain层,选择);

检查第一卷积层的频率响应

这个绘图过滤器方法绘制的幅频响应N具有等间距滤波器索引的滤波器。在图中绘制九个滤波器的幅频响应康斯坦丁克莱尔

图n = 9;plotNFilters (constSincNet.Layers (2), n)

辛克内特

在本节中,您将使用可训练的SincNet层作为网络中的第一个卷积层。SincNet层使用一组带通滤波器卷积输入帧。SincNet滤波器的带宽和初始频率在mel比例中初始化为等距。SincNet层尝试学习更好的参数对于神经网络框架内的这些带通滤波器。

定义层

SincNet层filterbank层的实现可以在sincNetLayer.m文件(附在此示例中)。定义SincNetLayer.使用80个过滤器,过滤器长度为251。

numFilters=80;过滤器长度=251;numChannels=1;名字=“sinc”

替换康斯坦丁克莱尔从上一个具有SincNetLayer。此新层有两个可学习的参数:FilterFrequencies滤波器带宽

sNL=sincNetLayer(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]=列车网络(XTrain,YTrain,layers,options);

检查第一卷积层的频率响应

使用绘图过滤器方法SincNetLayer用SincNet学习的等间距索引可视化九个滤波器的幅频响应。

图1绘图仪过滤器(sincNet.层(2),9)

结果总结

精度

该表总结了所有三个神经网络的帧精度。

NetworkType = {“标准CNN”,“恒Sinc层”,“SincNet层”} ';精度= [convNetInfo.FinalValidationAccuracy; constSincInfo.FinalValidationAccuracy sincNetInfo.FinalValidationAccuracy];resultsSummary =表(NetworkType、准确性)
结果摘要=3×2表NetworkType准确性  _______________________ ________ {' 72.97标准CNN”}{“常数Sinc层”}74.902 78.062 {SincNet层的}

关于时代的表现

根据历元数绘制测试集的精度图,以查看随着历元数的增加,网络的学习效果如何。SincNet的性能优于康斯坦丁克莱尔网络,尤其是在训练的早期阶段。这表明在神经网络框架内更新带通滤波器的参数会导致更快的收敛。这种行为只有在数据集足够大时才会出现,因此在还原酶被设置为真正的

时代= linspace (0 numEpochs元素个数(sincNetInfo.ValidationAccuracy (~ isnan (sincNetInfo.ValidationAccuracy))));时代=[时代,numEpochs];sinc_valAcc = [sincNetInfo.ValidationAccuracy (~ isnan (sincNetInfo.ValidationAccuracy)),...sincNetInfo.finalvalidationaccurcy];const_sinc_valAcc=[constSincInfo.validationaccurcy(~isnan(constsinfo.validationaccurcy)),...constSincInfo.finalvalidationaccurcy];conv_valAcc=[convNetInfo.validationaccurcy(~isnan(convNetInfo.validationaccurcy)),...ConventInfo.FinalValidationAccuracy];图形绘图(历元,新瓦拉克,'-*',“MarkerSize”,4)保持地块(纪元、恒新元、瓦拉克),'-*',“MarkerSize”4)情节(conv_valAcc时代,'-*',“MarkerSize”,4)ylabel(“帧级精度(测试集)”)包含(“时代”) xlim([0 numEpochs+0.3]) title(“帧级精度与Epoch”)传奇(“sincNet”,“康斯坦丁克莱尔”,“conv2dLayer”,“位置”,“东南”)网格

在上图中,最终的帧精度与上次迭代中计算的帧精度略有不同。在训练时,批处理标准化层在小批上执行标准化。然而,在训练结束时,批处理归一化层对整个训练数据进行归一化,这导致性能略有变化。

金宝app辅助功能

函数(X, Y) = preprocessAudioData(广告、SL OL, Fs)如果~ isempty(版本(“平行”) pool = gcp;numPar = numpartitions(广告、池);其他的numPar=1;结束帕弗ii=1:numparx=zeros(1,SL,1,0);Y=zeros(0);subad=partition(ADS,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毫秒的块audio_chunk =重塑(audio_chunk 1 SL 1 q);%与现有音频连接audioData =猫(4 audioData audio_chunk);结束audioLabel = str2double (dsInfo.Label {1});%通过复制矩阵生成培训和测试的标签audioLabelsTrain=repmat(audioLabel,1,尺寸(audioData,4));将当前扬声器的数据点添加到现有数据中X =猫(4 X audioData);Y =猫(2 Y audioLabelsTrain);结束XC{ii}=X;YC{ii}=Y;结束X =猫(4,XC {:});Y =猫(2,YC {:});Y =分类(Y);结束

参考文献

[1] M. Ravanelli和Y. Bengio,“用SincNet从原始波形中识别说话人”,2018 IEEE口语技术研讨会(SLT),希腊雅典,2018年,第1021-1028页,内政部:10.1109/SLT.2018.8639585。

[2] V.Panayotov,G.Chen,D.Povey和S.Khudanpur,“图书馆语言:基于公共领域有声图书的ASR语料库,”2015年IEEE声学、语音和信号处理国际会议(ICASSP),布里斯班,QLD, 2015, pp. 5206-5210, doi: 10.1109/ICASSP.2015.7178964