目录

摘  要

引  言

1 孤立字语音识别实验

1.1 语音识别系统和基本识别原理

1.2 语音识别系统和基本识别原理

1.3 MFCC参数算法

1.4 识别算法核心部分的具体实现

1.5 实验结果

1.6 实验结论

2  说话人识别实验

2.1 基于VQ的识别算法原理

2.2 LBG算法

2.3 实验结果

2.4 实验结论 

3 附录(部分核心代码)

3.1 baum_welch算法

3.2 viterbi算法

3.3 LBG算法

4 参考文献


摘  要

        本文研究了两种不同的语音识别算法—隐马尔可夫模型(HMM)和矢量量化(VQ),并在模式匹配原理的基础上,设计并实现了在 Matlab 环境中,以HMM为基础、选用MFCC参数为特征参数的孤立字语音识别实验,和以VQ为基础、码本设计采用 LBG算法的说话人识别实验。

引  言

        语音是人类交流和交换信息中最便捷的工具和最重要的媒体,因此,语音识别(Speech Recognifiion)在人机交互中有着及其重要的位置。简单地说,语音识别就是指让机器明白人说的话,即准确地识别出语音的内容,从而使机器可以根据人的意图去执行各种相关的指令。

        语音识别技术的研究已经进行了五十多年。尤其是近二十年来,语音识别技术一直是人们研究的热点。语音识别技术是集声学、语音学、语言学、计算机科学、信号与信息处理和人工智能等诸领域的一门交叉学科,研究难度较大。因此,目前语音识别技术的研究成果还远没有达到使计算机和人之间能自然交流的这个终极目标。但是随着数字信号处理技术和计算机技术的发展,专家预计在未来10年内,将实现“与机器进行语音交流,让机器听到并理解人的语音”这一人类梦想,届时语音识别技术将进入工业、家电、通信、汽车电子、医疗、家庭服务、消费电子产品等人类社会的各个领域。

        本文研究了两种不同的语音识别算法,并在Matlab平台上分别做了两次实验。

        第一个实验是以HMM(隐马尔柯夫模型)识别算法为基础,提取出孤立字的MFCC ( Mel频率倒谱参数),以此采用Baum-Welch算法训练并建立孤立字语音特征参考模板库,最终实现孤立字的语音识别。实验证明该方法有较好的识别效果。

        第二个实验是以VQ(矢量量化)识别算法为基础,码本设计采用 LBG算法,实验时,分别采用的参数有12个倒谱系数MFCC、一阶差分MFCC、二阶差分MFCC和一个能量共36个参数。将说话人的特征提取训练和匹配后,使用待测样本进行测试,结果表明,识别正确率很高,这说明VQ用于说话人识别是相当有效的。

1 孤立字语音识别实验

        孤立字语音识别是语音信号处理学科研究和应用的一个重要领域,与计算机科学、通信与信息科学以及模式识别等学科都有非常密切的关系,内容较为抽象。通过一定的试验,有助于加深对孤立字语音识别相关知识的理解。

1.1 语音识别系统和基本识别原理

        语音识别系统根据对说话人说话方式的要求,可以分为孤立字(词)语音识别系统,连接词语音识别系统以及连续语音识别系统;根据对说话人的依赖程度,可以分为特定人和非特定人语音识别系统。孤立字识别系统用于识别孤立发音的字(词)。孤立字在字与字之间存在发音停顿,单字之间的端点检测比较容易;同时一般对单字的发音都比较认真,且单字之间的协同发音影响较小,较容易得到较高的识别率。采用模式匹配原理的语音识别系统组成如图1所示。

图1  模式匹配原理语音识别系统

1.2 语音识别系统和基本识别原理

        本文涉及的孤立字语音识别采用了模式匹配原理。由于语音信号具有相当大的随机性,即使是同一个人在不同的时刻所讲的同一句话、发的同一个音,也不可能有完全相同的时间长度。对于采用模板匹配法的识别系统,这些时间长度的变化会影响测度的估计,从而降低系统的识别率,因此时间的伸缩是必不可少的。本文采取了一种有效的策略:马尔可夫模型技术(HMM)。

        隐马尔可夫模型(Hidden Markov Model—HMM)用隐含的状态对应于声学层相对稳定的发音单位,如图2所示,该 HMM 包含四个状态。随着时间的变换,各个状态之间可以发生转移,也可以在一个状态内驻留。每个观察向量都有相应的输出概率。用概率密度函数计算语音参数对 HMM 的输出概率,通过搜索最佳状态序列,以后验概率为准则找到识别结果。

图2  隐马尔可夫模型状态图

1.3 MFCC参数算法

        人的听觉器官类似于一个特殊的非线性系统,它响应不同频率信号的灵敏度是不同的,基本上是一个对数的关系。近年来,一种能够比较充分利用人耳这种特殊的感知特性的参数得到了广泛的应用,这就是Mel尺度倒谱参数(Mel -scaled Cepstrum Coefficients),或称为Mel频率倒谱参数,简称为MFCC。大量的研究表明,MFCC参数能比其它参数更好地提高识别性能。

1.4 识别算法核心部分的具体实现

        本文所有的算法均用Matlab实现。

(一)HMM模型训练

        这一部分最重要的算法是Baum-Welch 算法,这个算法实际上是用来解决HMM训练的,即HMM参数估计问题的。或者说,给定一个观察值序列O=o1,o2,⋯,oT,该算法能确定一个M={A,B,π},使P(O/M)最大。Baum-Welch算法利用递归的思想,使P(O/M)局部放大,最后得到优化的模型参数M={A,B,π}

下面给出利用Baum-Welch算法进行HMM训练具体步骤:

1)适当地选择和的初始值。一般情况下可以按如下方式设定:

给予从状态转移出去的每条弧相等的转移概率:

给予每一个输出观察符号相等的输出概率初始值:

并且每条弧上给予相同的输出概率距阵;

2)给定一个(训练)观察值符号序列O=o1,o2,⋯,oT,由初始模型计算等γt(i,j),并且,由上述重估公式,计算aijbij(k)

3)再给定一个(训练)观察值符号序列O=o1,o2,⋯,oT,把前一次的aijbij(k)作为初始模型计算γt(i,j)等,由上述重估公式,重新计算 aij 和 bij(k)

4)如此反复,直到aijbij(k)收敛为止;

图3  HMM模型训练模块的流程图

(二)HMM模型识别

        Viterbi算法应用于HMM的识别问题,也称解码问题。它通过应用了动态规划的思想避免了复杂度很高的运算,为识别时效性提供了强有力的支持。这个算法并不难理解,这里只是对其一个细节进行阐述。Viterbi算法实际上解决P(I|O,λ)最大化的问题,给定观测序列求其最可能对应的状态序列。算法首先需要导入两个变量δψδ是在时刻t状态为i的所有单个路径(i1,i2,...,it)中概率的最大值:

由定义可得变量δ的递推公式:

设定初始值δ1(i)=πibi(oi)之后就不断迭代,终止情况是:

图4  用HMM模型进行识别的流程图

1.5 实验结果

        本实验的孤立字语音采用数字1-10,每组语音分别为:“一,二,三,四,五,六,七,八,九,十”,每组语音取样八次,得到同一语音的八个语料。训练数据tra_data.mat如下,为1*10共10个 cell元组,每个cell元组有1*8共八个语料:

        运行程序hmm_train.m后得到的训练模型如下:

       运行程序hmm_recog.m,随机选择一条待识别语音,对HMM模型进行识别的结果如下:

        程序运行时同时调入四组语音用于估算 HMM 参数。模板训练过程中,先对每个字分别用十个个语音建立各自的特征参数模型,然后用统计聚类的方法将同一个字的四个特征参数模型聚类,得到反映说话人特征尽量少,而反映语意特征尽量多的参数模型。如果先前同一个字的各个参数模型类间距离过大,不能通过聚类得到反映共同特征的参数模型,训练程序自动退出迭代过程,进入下一个语料 HMM 模板的训练,同时该语料 HMM 模板将空缺,识别时所对应的语音将不能被识别。模板训练调用的语音组数可以随着语料的增加而设置增加,参与模板训练的语料越多,系统的识别正确率越高,但所耗费的时间也随之增加,同时聚类时溢出的风险也增加。

1.6 实验结论

        对于相同的语料,以 MFCC 参数作为特征参数,正确识别率达到 90%;对所采集的语料,识别参与模板计算语音时,正确识别率达到 100%。为了验证实验程序的非特定人特性,采用一组没有参与模板训练且与训练语料语意相同的语音进行识别,实验结果表明,正确识别率有所下降。原因在于参与模板训练的语料不够丰富。要达到对说话人的较高独立性,用于训练模型的语料数量是巨大的。这将消耗较多的运算时间。

2  说话人识别实验

        说话人识别是语音识别的一个分支,它和语音识别的区别在于,它并不注意语音信号中的语义内容,而是希望从语音信号中提取出个人的信息特征。从这点上说,说话人识别是企求挖掘出包含在语音信号中的个性因素,而语音识别是企求从不同人的语音信号中寻找共同因素。

        说话人识别可分为2个范畴,即说话人辨认(Speaker Identification)和说话人确认(Speaker Verification)。前者是把未标记的语句判定为属于N个参考说话人之中的某一个所说,是一个多者择一的问题.后者则是根据说话人的语句确定是否与参考说话人相符,这种确认是两者择一的问题,即回答肯定(得到确认),或回答否定(拒绝承认)。对说话人识别来说,又可以分为与文本有关的(Text - dependent)和与文本无关的(Text-independent)2种方式。“与文本有关”即是说话人按规定的文本发音或按提示发音,这在一定程度上使问题大为简化,但大多数情况下,我们面对的是与文本无关的环境下的识别问题。

2.1 基于VQ的识别算法原理

        将VQ用于说话人识别时,其工作框图如图5所示。当进行识别时,将被测试的特征矢量序列送入某个人参考模板的VQ编码器。然而这里需要得到的并不是量化的下标,而是各个测试矢量与它的最邻近码矢之间的距离也即量化误差)。因为它反映了测试矢量与参考模板之间的匹配程度。接着就可以将它们的平均距离作为判决依据,如果距离小于门限就承认“是某个人”,否则就不承认“是某个人”。

图5  VQ识别系统工作框图

        这种用有限个码矢量作为模板,去反映一个人的发声特点的作法,并没有考虑特征矢量出现的时间次序,因此它是一种静态的模板。算法工作时,并不去跟踪说话内容的变化,而只是判断输入的每一个特征矢量是否符合一定的特征,或者说在某些特定的区域当中。有时候听到一个人说话,尽管听不清他说什么,但是却能够判断出说话的人是谁,也是这个道理。这里,实际上是将某一个人产生的特征矢量序列视为一个具有特定分布的多维随机变量,其概率密度主要集中于某些特定的区域中。于是可以用有限个码矢量代表这些区域。对不同的人这些区域各不相同,因此模板能够有效地代表它所对应的人。

2.2 LBG算法

        矢量量化是一种很重要的数字信号处理方法。它的主要工作是聚类,聚类的方法有很多,在语音识别中常用的有:K均值算法(K-Means)、分裂法等。

        在解决了VQ进行说话人识别的运行问题之后,还需要解决VQ的码本设计问题。希望寻找一个最能够表达某说话人的发声特点的码本,让码本中的各个码矢量能够分别代表各个概率密度的集中区域。这样,码本的设计目标与常规的VQ码本设计目标就一致了,都是为实现最小的量化误差,于是可以使用有效的LBG算法。

        LBG算法是一种需要大量训练样本集的迭代算法。它实际上是基于下面的事实:设所有选择某个码矢Y的输入矢量X的集合为S它也被叫作量化区域),为了使此集合中所有矢量与它们的代表码矢Y的均方误差达到最小,那么Y应该等于S中所有矢量质心。

LBG算法的大致步骤如下:

第一步:初始化。给定全部参考矢量集合S,设定失真控制门限δ, 算法最大迭代次数L,以及初始码本{Y10,Y20,….,YJ0},设置总失真D(0)=∞,初始迭代次数m=1,最大迭代次数为L。  

第二步:迭代。

1)根据最邻近准则将S分成J个子集,

2)计算总失真,

3)计算新码字:每一个码字为其对应子集的质心,

4)计算相对失真改进量,

与失真控制门限比较,如δm>δ,则转入5);

δm≤δ,则转入6);

5)若m大于L,则转入6),否则m+1转入1) ;

6)得到最终的码书

2.3 实验结果

        聚类数k选择8;特征参数使用12个倒谱系数MFCC、一阶差分MFCC、二阶差分MFCC和一个能量共36个参数。

一共选取了4个说话人语音作为训练样本:

运行vq_books.m完成说话人样本的训练:

运行speaker_test.m对5个说话人的语音进行测试,其中每个说话人的都有4条语料,如下图所示:

2.4 实验结论 

从运行结果可以看出:

1)前四个说话人的每条语料都被准确地辨别,并归类为正确的测试者;而第五个人的四条语料中,有一条语料识别错误,被归类为“系统内人”。

2)总体来说,错误率只有5%,识别正确率很高,这说明VQ用于说话人识别是相当有效的。

3)MFCC对于VQ说话人识别是较好的参数;

4)测试语音长度的增加可使错误率大大下降,如果测试语音长度为8个字以后,一般错误率可降到0。

5)增加训练语音的遍数也可以改善识别性能。

3 附录(部分核心代码)

3.1 baum_welch算法

function hmm=baum_welch(hmm,obs)
mix=hmm.mix; %高斯混合模型
N=hmm.N; %HMM的状态数
K=length(obs); %训练数据样本数
SIZE=size(obs(1).fea,2); %特征矢量的个数

for loop = 1:40
   % ----计算前向, 后向概率矩阵
   for k=1:K
     param(k)=getparam(hmm,obs(k).fea);
   end
   %----重估转移概率矩阵A
   for i=1:N-1
     demon=0;
     for k=1:K  
        tmp=param(k).ksai(:,i,:);
        demon=demon+sum(tmp(:)); %对时间t,j求和
     end
     for j=i:i+1  
        nom=0;
        for k=1:K  
            tmp=param(k).ksai(:,i,j);
            nom=nom+sum(tmp(:));  %对时间t求和
        end
        hmm.trans(i,j)=nom/demon;
     end
   end

   %----重估输出观测值概率B
   for j=1:N %状态循环
     for l=1:hmm.M(j) %混合高斯的数目
        %计算各混合成分的均值和协方差矩阵
        nommean=zeros(1,SIZE);
        nomvar=zeros(1,SIZE);
        denom=0;
        for k=1:K  %训练数目的循环
           T=size(obs(k).fea,1);  %帧数
           for t=1:T   %帧数(时间)的遍历
             x=obs(k).fea(t,:);
             nommean=nommean+param(k).gama(t,j,l)*x;
             nomvar=nomvar+param(k).gama(t,j,l)*(x-mix(j).mean(l,:)).^2;
             denom=denom+param(k).gama(t,j,l);
           end
        end
        hmm.mix(j).mean(l,:)=nommean/denom;
        hmm.mix(j).var(l,:)=nomvar/denom;
   
        %计算各混合成分的权重
        nom=0;
        denom=0;
        for k=1:K
          tmp=param(k).gama(:,j,l);
          nom=nom+sum(tmp(:));
          tmp=param(k).gama(:,j,:);
          denom=denom+sum(tmp(:));
        end
        hmm.mix(j).weight(l)=nom/denom;
     end
   end
end

3.2 viterbi算法

function [prob,q]=viterbi(hmm,O)
%Viterbi算法
%输入:
%hmm--hmm模型
%O--输入观察序列,T*D,T为帧数,D为向量维数
%输出:
%prob--输出概率
%q--状态序列

init=hmm.init; %初始概率
trans=hmm.trans; %转移概率
mix=hmm.mix;  %高斯混合
N=hmm.N;  %HMM的状态数
T=size(O,1); %语音帧数

%计算log(init)
ind1=find(init>0);
ind0=find(init<=0);
init(ind1)=log(init(ind1));
init(ind0)=-inf;

%计算log(trans);
ind1 = find(trans>0);
ind0 = find(trans<=0);
trans(ind0) = -inf;
trans(ind1) = log(trans(ind1));

%初始化
delta=zeros(T,N); %帧数×状态数
fai=zeros(T,N);
q=zeros(T,1);

%t=1;
for i=1:N
    delta(1,i)=init(i)+log(mixture(mix(i),O(1,:)));
end

%t=2:T
for t=2:T
    for j=1:N
        [delta(t,j),fai(t,j)]=max(delta(t-1,:)+trans(:,j)');
        delta(t,j)=delta(t,j)+log(mixture(mix(j),O(t,:)));
    end
end
%最终概率和最后节点
[prob q(T)]=max(delta(T,:));

%回溯最佳状态路径
for t=T-1:-1:1
    q(t)=fai(t+1,q(t+1));
end

3.3 LBG算法

function v=lbg(x,k)
%lbg:完成lbg均值聚类算法
% lbg(x,k) 对输入样本x,分成k类。其中,x为row*col矩阵,每一列为一个样本,
% 每个样本有row个元素。
% [v1 v2 v3 ...vk]=lbg(...)返回k个分类,其中vi为结构体,vi.num为该类
% 中含有元素个数,vi.ele(i)为第i个元素值,vi.mea为相应类别的均值
[row,col]=size(x);
%u=zeros(row,k);%每一列为一个中心值
epision=0.03;%选择epision参数
delta=0.01;
%u2=zeros(row,k);
%LBG算法产生k个中心
u=mean(x,2);%第一个聚类中心,总体均值
for i3=1:log2(k)
    u=[u*(1-epision),u*(1+epision)];%双倍
    %time=0;
end
    D=0;
    DD=1;
    while abs(D-DD)/DD>delta   %sum(abs(u2(:).^2-u(:).^2))>0.5&&(time<=80)   %u2~=u
        DD=D;
        for i=1:2^i3            %初始化
            v(i).num=0;
            v(i).ele=zeros(row,1);
        end
        for i=1:col %第i个样本
            distance=dis(u,x(:,i));%第i个样本到各个中心的距离
            [val,pos]=min(distance);
             v(pos).num=v(pos).num+1;%元素的数量加1
            if v(pos).num==1    %ele为空
                v(pos).ele=x(:,i);
            else
                v(pos).ele=[v(pos).ele,x(:,i)];
            end
        end
        for i=1:2^i3 
            u(:,i)=mean(v(i).ele,2);%新的均值中心
            for m=1:size(v(i).ele,2)
                D=D+sum((v(i).ele(m)-u(:,i)).^2);
            end
        end
    end
%u=u;
for i=1:k  %更新数值
    v(i).mea=u(:,i);
end

4 参考文献

[1]李潇, 王大堃. 基于Matlab的孤立字语音识别试验平台[C]中国自动化学会;中国仪器仪表学会. 中国自动化学会;中国仪器仪表学会, 2006.

[2]王宏, 郭艳丽, 贾新民. 基于HMM的孤立字识别[J]. 昌吉学院学报, 2006, 000(001):94-98.

[3]王淑春, 吴善培. 提高多说话人孤立数字语音识别率的一些措施[J]. 北京邮电学院学报, 1992(02):29-33.

[4]付维. 基于HMM的机器人语音识别系统的研究[D]. 武汉科技大学.

[5]陈晓霖. 基于隐马尔可夫模型的语音识别方法的研究[D]. 山东大学.

[6]涂建华. 基于隐马尔可夫模型及矢量量化进行非特定人语音识别的研究[J].  1989.

[7]韩雁,陈利华.说话人计算机识别系统的设计与实现[J].浙江大学学报(工学版),2001,(2).

[8]贾宾,朱小燕,罗予频,等.消除溢出问题的精确Baum-Welch算法[J].软件学报,2000,(5).

[9]尉洪, 周浩, 杨鉴. 基于矢量量化的组合参数法说话人识别[J]. 云南大学学报(自然科学版), 2002, 24(2):96-100.

[10]袁玉倩. 改进的基于矢量量化的文本相关说话人识别方法研究[D]. 河北工业大学, 2006.

[11]张玉娇. 基于矢量量化(VQ)的说话人识别的研究[D]. 南京理工大学, 2015.

[12]丁艳伟, 戴玉刚. 基于VQ的说话人识别系统[J]. 电脑知识与技术, 2008.

[13]江太辉. 基于VQ的说话人识别算法与实验[J]. 计算机工程与应用, 2004, 40(9):3.

[14]Rosenberg A.E..Automatic speaker verification: A review[J].Proceedings of the IEEE,1976,64(4).475-487.

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐