zoukankan      html  css  js  c++  java
  • 声纹识别

    声纹识别,也称说话人识别,是一种通过声音判断说话人身份的技术。声纹识别可以分为说话人辨识(Speaker Identification, SI)和说话人确认(Speaker Verification, SV)。SI指将待测语音与已知集合内若干说话人比对,选取最为匹配的说话人;而SV指对于一个目标身份,判断一段未知语音是否来自于这个目标身份即可。因此,SI是一个1对多的判别问题,而SV实际是一个1对1的二分类问题。SV典型的应用就是声纹锁或声纹验证,对于一段验证语音,系统只需要回答"通过"或“拒绝”即可。SI问题可以间接分解为多个SV问题,因此对于声纹识别系统的性能评测多以SV方式进行。从语音字典是否受限的角度看,声纹识别又分为文本无关和文本相关识别。文本无关就是系统对于输入语音的内容不做限制,识别系统应当客服语音中的字典信息(也即语义信息)的多变性和差异性,对语音背后的身份进行判断;而文本相关识别则会限制语音的语义内容。文本相关识别又可以细分为固定口令和有限搭配的字典集合。

    从离散信号到特征

    语音是一种时变的一维信号,语音首先承载的是语义,语义信息的背后才是身份信息,我们讲的话可以对应到成百上千的字词信息,但是在背后却只对应一个不变的身份。声纹之所以可以被识别,是因为每个人的口腔、鼻腔和声道结构都存在唯一性质的差别,但语音信号始终不停在变。不过,语音具备一个良好的性质:短时平稳,在一个20~50毫秒内,语音近似可以看作是良好的周期信号。

    在声音的音调、响度和音色这三个基本属性中,音色是最能反映一个人身份信息的属性。比如人在暴怒时,响度和音调都可以急速飙升,而音色不会急剧变化。而音色上的差异在信号处理中可以表示为在频域不同频段能量的差异。因此可以通过抽取不同频段上能量值来表示这个短时平稳语音内频谱性质。另外可以综合考虑人耳的听觉属性(人耳在可听频段内,对于低频变化较为敏感),噪声鲁棒性(希望提前到的特征只对语音敏感,而对噪声等无关信息不变),均衡不同频段的能量差异,去除特征相关性设计合理的短时声学特征。通过信号处理,一段20~50ms的语音(以8KHz采样为例,该段语音对应160~400个采样点)可以映射为39~60维的向量。为了充分保留语音中的原始信息,同时不增加计算负担,通过以15~20ms帧移提取短时语音的特征。

    在声纹识别,以及语音识别领域,传统的声学特征包括梅尔倒谱系数MFCC、感知线性预测系数PLP、近几年逐渐受到关注的深度特征Deep Feature,以及15年公开发表的能量规整谱系数PNCC等,都能作为声纹识别中的声学特征。

    算法演进

    尽管每个人的语音看起来千变万化,但常用的字词不过数千个左右,继续将语音拆分可以到音素(phone)级别,狭义的现代汉语只需要32个音素就已经足够了。如果考虑到每个音素的形态还会收到前后音素的影响,构建三音素模型(tri-phone)的话,至多也只有几千个备选的三音素集合(这里是简单的32的三次方,会去掉一些稀有和根本不会出现的搭配),而不同说话人的三音素样本尽管有明显的差异,但都能在空间中的某个区域内聚类。首此启发,可以将高斯混合模型(Gaussian Mixture Model, GMM)应用到声纹识别任务中,在深度学习之前,声纹识别都是在GMM的基础上进行改进和拓展。

    类型 主要算法
    文本无关 GMM-UBM(2000)
    GMM-SVM(2006)
    JFA(2007)
    i-vector/PLDA(2011)
    DNN i-vector(2014)
    Deep Embedding(2017)
    文本相关 GMM-UBM
    HMM-UBM
    TMM-UBM
    i-vector
    DNN-ivector

    GMM-UBM框架

    基于高斯模型的方法包括单高斯模型(SGM, Single Gaussian Model)和高斯混合模型(GMM, Gaussian Mix Model),GMM-UBM是对GMM的一种改进,解决了实际训练场景下GMM的缺陷。

    SGM

    • 当一个一维向量(X)服从高斯分布时,其概率密度函数(PDF)定义为:

      [N(x;mu,sigma^2)=frac{1}{(2pi sigma^2)^{frac{1}{2}}exp[-frac{1}{2sigma^2}(x-mu)^2]} ]

      其中,(mu)表示均值,(sigma^2)表示方差

    • 当一个多维向量(X)服从高斯分布时,它的概率密度函数(PDF)定义为:

      [N(x;mu,Sigma)=frac{1}{(2pi)^{frac{D}{2}}}frac{1}{(|Sigma|)^{frac{1}{2}}}exp[-frac{1}{2}(x-mu)^TSigma^{-1}(x-mu)] ]

      其中,(mu)表示均值,(Sigma)表示(D*D)的协方差矩阵,(|Sigma|)表示该协方差行列式的值。

    单高斯模型在二维空间上近似于椭圆形,在三维空间上近似于椭球形。

    GMM

    高斯混合模型是将多个单高斯的概率密度函数加权求和来拟合更加复杂的空间分布。假设GMM模型由K个SGM模型组成,每个SGM称为一个分模型(component),这些分模型线性加权就组成了GMM:

    [p(x)=sum_{k=1}^Kp(k)p(x|k)=sum_{k=1}^Kpi_kN(x|mu_x,Sigma_k) ]

    其中:

    • (pi_k)表示GMM中第k个分模型的概率,或称权重
    • (mu_k)表示第k个分模型的均值
    • (sigma_k)表示第k个分模型的方差
    • 每个SGM 分模型表示为(N_ksim N(mu_k, heta_k),k=1,2,...,K),其分布对应一个聚类中心,每个聚类中心的坐标可以看作是((mu_k, heta_k))。对于一个样本(x_i),它属于第k个聚类中心的可能性为(pi_k,pi_ksim (0,1))

    GMM的参数训练,通常使用最大似然估计(MLE)和最大后验概率(MAP)完成,参见李航-《统计学习方法》-9.3。通常情况下,在数据充足情况下,多个高斯概率分布的线性组合可以平滑的逼近任意形状的概率密度函数,并且是一个易于处理的参数模型,具备对实际数据很强的表征能力。GMM的缺陷在于:参数规模会随着模型复杂度等比例膨胀,需要更多的数据来驱动GMM的参数训练才能得到一个泛化能力更强的GMM模型。

    假设对一个维度为50的声学特征建模,GMM包含1024个分模型,并简化高维高斯的协方差为对角矩阵。GMM待估计的参数总量为1024(权重(pi)个数)+1024×50(均值(mu)参数个数)+1024×50(协方差(sigma)参数个数)=103424,也即超过10w个参数需要估计,这其中均值和协方差的参数占比都接近50%。

    GMM-UBM

    现实中,每一个说话人的语音数据有限,难以训练出高效的GMM模型。另外由于多通道的问题,训练GMM模型的语音和测试语音可能存在不匹配的问题,这些因素都会降低GMM声纹识别系统的表现,因此提出了通用背景模型(Universal Background Model, UBM):先采集大量与说话人无关的语音特征训练一个UBM,然后使用少量的说话人数据,通过自适用算法(如最大后验概率,最大似然线性回归等)突出说话人的个性特征,从而得到目标说话人模型。

    GMM-UBM本质是一种自适用的思想,也就是深度学习领域fine-tuning思想。既然我们无法获取目标说话人大量的数据,那么可以先用大量的数据构建一个大型的通用GMM模型空间(均值模型),再用目标说话人的语音特征去自适用,建模效果会显著提升。GMM-UBM最重要的优势就是通过最大后验概率估计对模型参数进行估计,避免了过拟合的存在,同时我们不必调整目标用户GMM的所有参数(GMM所有参数:权重、均值和方差),而只需要对各个分模型的均值参数进行估计,就能实现最好的识别性能。显然这种做法可以使得参数减少大约一半,越少的参数则意味着更快的收敛,不需要大量的目标用户数据即可完成训练:

    • Feature Extraction

      使用HTK工具提取HMM特征。

    • Development

      使用EM算法训练UBM模型,也即使用包含大量说话人语音数据的训练集训练GMM。

    • Enrollment

      使用目标说话人的语音数据,利用MLE或MAP来重新估计均值,得到新的GMM模型。

    • Test

      Eds8SO.png

    GMM-SVM

    在GMM-UBM模型中,在自适用环节只是对UBM模型在目标说话人数据上做了均值的自适用。GMM-UBM算法可以解决目标说话人数据不足导致的建模效果太差,但是不能消除由信道干扰导致的说话人信息的扰动。换言之,用iPhone注册模型,在小米手机上识别就无法通过,这是因为不同型号的录音设备对语音都会造成一定程度的畸变,同时由于背景环境和传输信道等差异,对语音信息也会造成不同程度的损伤。于是可以将支持向量机(Support Vector Machine, SVM)引入到GMM-UBM中,将GMM每个分模型的均值提取出来构建一个高斯超向量(Gaussian Super Vector, GSV),利用SVM核函数的强大非线性分类的能力,在原始GMM-UBM的基础上大幅提升了识别性能。同时,基于GSV的一些规整算法,例如扰动属性投影(Nuisance Attribute Projection, NAP)类内方差规整(Within Class Covariance Normalization, WCCN)等,都在一定程度上补偿了由于信道易变形对声纹建模带来的影响。

    JFA

    在实践中GMM-UBM待估计参数还是过多,因子分析(Factor Analysis, FA)可以只用少量的参数就能控制GMM所有分模型变化,在FA算法框架中,只用数百个基向量的线性组合就足以表征所有高斯超向量的变化。为了解决GMM-UBM模型不抗信道干扰的问题,出现了联合因子分析(Joint Factor Analysis, JFA)。在JFA中,GMM-UBM系统中高斯模型均值的高斯超向量由两部分叠加,一部分是和说话人本身的向量特征,另一部分是和信道和其它变化有关的向量特征。也就是说,将说话人GMM均值高斯超向量所在的空间分解为本征空间、信道空间和残差空间。联合因子分析的思路就是抽取和说话人有关的特征而去掉和信道相关的特征。

    i-vector

    JFA的前提是说话人特征空间和信道空间独立假设,也就是同一说话人不管如何采集语音,采集多少语音,在说话人特征空间上的参数映射都应该是相同的,而最终的GMM模型参数之所以有差别,都是因为信道空间的不同导致的,但是这种假设在现实中是不存在的。因此后续有提出了更为宽松的假设:既然声纹信息和信道信息不能完全独立,那就用超向量子空间同时描述说话人信息和信道信息。此时,同一说话人如何采集语音,以及采集多少语音,在这个子空间上的映射坐标都会有所不同,这和实际情况相符。这个既模拟说话人差异性又模拟信道差异性的空间称为全因子空间(Total Factor Matrix),每段语音在这个空间上的映射坐标称为身份向量(Identity Vector, i-vector),i-vector的维度通常在400~600左右。后续对i-vector进行了许多改进,包括线性区分分析(Linear Discriminate Analysis, LDA),基于概率的线性预测区分分析(Probabilistic Linear Discriminant Analysis, PLDA)甚至度量学习(Metric Learning)等。i-vector在文本无关的声纹识别上表现优异,但在文本有关的识别上不如GMM-UBM,因为其舍弃了太多东西,包括文本差异性。

    Deep Speaker: an End-to-End Neural Speaker Embedding System

    论文地址:Deep Speaker: an End-to-End Neural Speaker Embedding System

    不同于之前介绍的声纹识别系统,Deep Speaker摒弃了传统声纹识别的思路,介绍基于神经网络的端到端声纹识别。该论文侧重于端到端声纹识别的神经网络结构设计,包括基于CNN和RNN的两种网络结构。Deep Speaker相比于其它声纹识别有两大优势:1)在大数据集上能够很好的收敛;2)易于在多个语言上迁移。

    Residual CNN

    EdsNmd.md.png

    其中,average表示时间维度上平均;ln为归一化层(length normalization):

    [||x_i||_p=frac{x_i}{(sum_{i=1}^n|x_i|^p)^{frac{1}{p}}} ]

    此处(p)可取2.

    在该ResCNN结构中,每个ResBlock包含两个卷积核为3×3,步长为1的卷积层,每一个ResBlock之前加一个卷积核为5×5,步长为2的卷积层,在每一层之间对序列维度上使用Batch Normalization,非线性映射使用裁剪修正线性函数(clipped rectified linear(clipped-ReLU)):

    [sigma(x)=min{max{x,0},20} ]

    GRU network

    EdyG40.png

    Speaker Embedding

    average层输出如下计算:

    [h=frac{1}{T}sum_{t=0}^{T-1}x(t) ]

    其中,(x(t))为上一层的输出。

    经过归一化之后,使用cosine相似度度量两个embedding距离:

    [cos(x_i,x_j)=x_i^Tx_j ]

    其中,(x_i,x_j)为两个embedding向量。可以使用scipy的scipy.spatial.distance.cosine计算cosine距离,与cosine相似度的关系为:

    [cosine\_distance+cosine\_similarity=1 ]

    参见:scipy.spatial.distance.cosine

    Triplet Loss & Softmax Pre-training

    Triplet Loss是由FaceNet中提出的概念,主要想法是:使得锚样本(anchor)正样本(Anchor-Positive, AP)的尽可能接近,与负样本(Anchor-Negative, AN)尽可能远离。在DeepSpeaker中,锚样本(anchor)即为从特定说话人中选取的一句话,正样本(AP)即为从同一说话人中选取的另外一句话,而负样本(AN)即为从不同说话人选取的一句话:

    [Loss=sum_{i=0}^N[s_i^{an}-s_i^{ap}+alpha]_+ ]

    其中,([x]_+=max(x,0))

    在Triplet三元组的选择上,有两种方式:

    • hard-negative

      在mini-batch中,保持AP对(Anchor-Positive)不变,对每一个AP对,选择一个使得AN相似度最高的负样本,这样可以加速收敛。

    • semi-hard-negative

      在mini-batch中,保持AP对(Anchor-Positive)不变,对每一个AP对,选择一个使得AN相似度尽可能高但必须小于AP相似度的负样本。这是FaceNet文章中推荐的选择方法,但在Deep Speaker原论文中采用的是hard-negative+softmax-pretrain的方法。

    为了避免过早陷入局部最优点,Deep Speaker使用了Softmax+交叉熵预训练方法,从实验结果上看,Softmax预训练确实有助于快速收敛。

    EwTzrR.md.png

    预处理策略

    语音经过VAD等前端处理,提取64维的Fbank系数,将Fbank系数以及其一阶、二阶作为通道数为3的图像处理,因此输入到网络中的张量大小为:

    [batch\_size imes n\_frame imes 64(frame\_size) imes 3 ]

    预处理代码示例:

    from python_speech_features import mfcc, deltamfcc, delta
    
    # nb_features Fbank coefficient
    mfcc_feat = mfcc(sig, rate, numcep=nb_features, nfilt=nb_features)
    # first-order Fbank
    delta_feat delta_feat = delta(mfcc_feat, delta(mfcc_feat, 2)
    # second-order Fbank
    double_delta_feat = delta(delta_feat, 2)
    

    End-to-End Text-Dependent Speaker Verification

    论文地址:End-to-end text-dependent speaker verification

    • 用RNN获取较长的context,搭建了端到端架构;
    • 计算余弦相似度之后用逻辑回归将问题转化为二分类问题,用偏置值控制接受或拒绝的比例;
    • 对i-vector和d-vector进行了实验比较,即使使用很少的语句也可以获得较好的表现。

    说话人识别系统流程

    一个典型的说话人识别系统,包括训练、注册和评估三部分:

    • 训练阶段:从语句提取合适的内在表示形式。通常,该表示形式和三个因素有关:模型类型(高斯模型或深度网络模型),表示层次(帧级别或者语句级别)和损失函数(最大似然或者softmax);
    • 注册阶段:说话人提供少量的语句,然后用训练过的模型提取特征,获取对应的i-vector或d-vector。最常见的做法是对少量语句的特征求均值,得到说话人对应的特征向量(m_{spk})
    • 评估阶段:假如待评估语句为(X),待评估说话人为(spk),可以使用余弦相似度函数计算语句(X)来自说话人(spk)的评估分数(S),由该分数就可以知道(X)是否来自说话人(spk)了。在评估阶段,有两种错误率会发生,分别为错误接受率和错误拒绝率,这两种错误的大小取决于阈值的选取。如果两个错误率数值相等,则称为等错误率(Equal Error Rate, EER)。

    d-vector baseline model

    利用DNN网络提取获得固定维度的向量,称为d-vector,用来表示一整个语句。

    E0eErj.png

    d-vector基线模型使用了几个连续的非线性函数将语句转化为一个向量,除最后一层是简单的线性变换外,其它层均使用ReLU激活函数。

    在训练阶段,使用Softmax作为输出,假设最后一个线性变换层的权重和偏置分别为(w_{spk})(b_{spk}),训练阶段使用的softmax loss如下:

    [Loss=-mathop{log}frac{exp(w_{spk}^Ty+b_{spk})}{sum_{ ilde{spk}}exp(w_{ ilde{spk}^T}y)+b_{ ilde{spk}}} ]

    其中,(y)为神经网络的输出。

    在注册阶段,说话人对应的特征向量(m_{spk})是所有注册语句上计算的d-vector的均值。

    在评估阶段,评估分数(S)是测试语句d-vector与说话人特征向量(m_{spk})的余弦相似度。

    端到端声纹识别框架

    E0m0kq.png

    本文提出的端到端声纹识别框架将上述三个阶段合并成一个深度神经网络,输入包含测试语句和少量的注册语句,输出是简单的接受和拒绝。训练完成之后,除了最后一层逻辑回归的偏置值标量,其它所有网络权重固定。逻辑回归的偏置值是在注册数据上人工调整以获得最佳的表现。该神经网络结构主要使用locally-connected和fully-conneted layers结构。

    E0mjAI.md.png

    在该RNN结构中,只使用RNN最后一帧的输出,从而获得单个语句级别的说话人表示形式。

    获得d-vector和说话人特征向量的评估分数(S(X,spk))之后,送入逻辑回归中以判断是否接受。模型损失函数定义为:

    [Loss=-mathop{log}(target) ]

    其中,target的取值为({accept,reject}),属于一个二值变量。

    [p(accept)=frac{1}{1+exp(-wS(X,spk)-b)} ]

    [p(accept)=-p(target) ]

    其中,超参数(-frac{b}{w})是偏置值标量。

    神经网络输入是(N+1)个语句,(N)个语句用来训练,1个用来测试。

    Generalized End-to-End Loss for Speaker Verification

    论文地址:Generalized End-to-End Loss for Speaker Verification

    本文是在上的进一步改进。与相对应,GE2E更侧重于探讨对神经网络损失函数的设计。

    神经网络的输出经过L2正则化之后,作为d-vector(下称embedding vector):

    [e_{ji}=frac{f(x_{ji;w})}{||f(x_{ji};w)||_2} ]

    其中,(e_{ji})表示说话人(j)的第(i)句话的embedding vector。定义说话人质心(c_j),也即是上述的说话人特征向量:

    [c_k=mathbb{E}_m[e_{km}]=frac{1}{M}sum_{m=1}^Me_{km} ]

    embedding vector((e_{ji}))到每个质心(c_k)的相似度矩阵定义为:

    [S_{ji,k}=wcdot mathop{cos}(e_{ji},c_k)+b ]

    其中,(w>0​)为待学习参数。

    本文提出了两种损失函数形式:

    • Softmax

    [L(e_{ji})=-S_{ji,j}+mathop{log}sum_{k=1}^N exp(S_{ji,k}) ]

    该损失函数希望尽可能拉近每一个embedding vector与其对应质心的距离,推远与其它所有的质心的距离。

    • Contrast

      [L(e_{ji})=1-sigma(S_{ji,j})+mathop{max}_{1leq k leq N,k eq j}sigma(S_{ji,k}) ]

      其中,(sigma(x)=frac{1}{1+e^{-x}})为sigmoid函数。该损失函数希望尽可能拉近embedding vector与质心的距离,推远与该embedding vector距离最近的质心之间的距离。

      E0MRxK.png如上图所示,应该尽可能拉近(e_{ji})(c_j)之间的距离,推远(e_{ji})(c_{k})之间的距离,由于(e_{ji})和负质心(c_{k'})之间的距离不是最近的,因此不会计入该损失函数中。

    为了训练稳定以及更符合常理,计算质心(c_{j})时,应排除对应的(e_{ji})

    [c_j^{(-i)}=frac{1}{M-1}sum_{m=1,m eq i}^M e_{jm}\ S_{ji,k}=left{egin{matrix} wcdot mathop{cos}(e_{ji},c_j^{(-i)})+bquad k=j; \ wcdot mathop{cos}(e_{ji,c_k})+bquad otherwise end{matrix} ight. ]

    最终的GE2E损失函数定义为(L(e_{ji})​)之和:

    [Loss=sum_{j,i}L(e_{ji}) ]

    Training

    为了利用大数据集提升在小数据集上的表现,使用了所谓的MultiReader方法:

    [L(D_1,D_2;w)=mathbb{E}_{xin D_1}[L(x;w)]+alphamathbb{E}_{xin D_2}[L(x;w)] ]

    其中,(D_1,D_2)分别为小、大数据集。可以将第二项看作是正则化项,由于(D_1)没有充足的数据,仅仅使用数据集(D_1)可能会导致过拟合。

    E01SCn.png

    文中的端到端声纹识别网络结构非常简单,由前端处理后获得40维Fbank系数送入3层LSTM中,经正则化之后即可获得embedding vector。


    Reference

    【技术专题】说话人识别(Speaker Verification)综述

    闻声识人 声纹识别技术简介

    【论文阅读】End-to-End Text-Dependent Speaker Verification

    【开发日记】Deep Speaker 开发日记之Triplet选择

    百度声纹识别论文deep speaker介绍

    百度端到端说话人识别系统 Deep Speaker 详细介绍

  • 相关阅读:
    编写更好的API
    C,C++语法基础 | 字符串 | 05
    C,C++语法基础 | 变量,表达式与顺序语句 | 01
    业务数据分析 | 深入浅出数据分析入门 | 01
    linux全套 | 目录 | 00
    linux全套 | 组管理和权限管理 | 08
    linux全套 | crond任务调度 | 09
    linux全套 | linux磁盘分区,挂载 | 10
    linux全套 | 网络配置 | 11
    linux全套 | 进程管理 | 12
  • 原文地址:https://www.cnblogs.com/mengnan/p/10813745.html
Copyright © 2011-2022 走看看