2018-11-27 23:31:21 entoon 阅读数 7354

matlab程序设计实例——语音识别
经典的语音识别流程如下
语音输入——去噪滤波——特征提取——形成模板库——输入测试语音——匹配模板库——得出结论。

在语音处理时最常用的是DTW进行模式匹配,运用MFCC作为识别特征。

这种思路可以做很多的语音识别设计。

例如单一的词语或者语句识别,做说话人的识别,做说话的语气情感识别等

除此之外还可以利用HMM进行语音识别,思路相似,这是一种基于统计的模型,也有着很不错的运用。

一些主要的程序代码如下(matlab)
%设置模板
ncoeff=12; %mfcc系数的个数
fMatrix1 = cell(1,5);
fMatrix2 = cell(1,5);
fMatrix3 = cell(1,5);
fMatrix4 = cell(1,5);
fMatrix5 = cell(1,5);
fMatrix6 = cell(1,5);
fMatrix7 = cell(1,5);

for i = 1:5
q = [‘SpeechData\1’ num2str(i) ‘.wav’];
[speechIn1,FS1] = audioread(q);
z=speechIn1(:,1);
speechIn1 = my_vad(z);

fMatrix1(1,i) = {mfccf(ncoeff,speechIn1,FS1)}; 

end

for j = 1:5
q = [‘SpeechData\2’ num2str(j) ‘.wav’];
[speechIn2,FS2] = audioread(q);
z=speechIn2(:,1);
speechIn2 = my_vad(z);
fMatrix2(1,j) = {mfccf(ncoeff,speechIn2,FS2)};
end

for k = 1:5
q = [‘SpeechData\3’ num2str(k) ‘.wav’];
[speechIn3,FS3] = audioread(q);
z=speechIn3(:,1);
speechIn3 = my_vad(z);
fMatrix3(1,k) = {mfccf(ncoeff,speechIn3,FS3)};
end

for k = 1:5
q = [‘SpeechData\4’ num2str(k) ‘.wav’];
[speechIn4,FS4] = audioread(q);
z=speechIn4(:,1);
speechIn4 = my_vad(z);
fMatrix4(1,k) = {mfccf(ncoeff,speechIn4,FS4)};
end
for k = 1:5
q = [‘SpeechData\5’ num2str(k) ‘.wav’];
[speechIn5,FS5] = audioread(q);
z=speechIn5(:,1);
speechIn5 = my_vad(z);
fMatrix5(1,k) = {mfccf(ncoeff,speechIn5,FS5)};
end
for k = 1:5
q = [‘SpeechData\6’ num2str(k) ‘.wav’];
[speechIn6,FS6] = audioread(q);
z=speechIn6(:,1);
speechIn6 = my_vad(z);
fMatrix6(1,k) = {mfccf(ncoeff,speechIn6,FS6)};
end
for k = 1:5
q = [‘SpeechData\7’ num2str(k) ‘.wav’];
[speechIn7,FS7] = audioread(q);
z=speechIn7(:,1);
speechIn7 = my_vad(z);
fMatrix7(1,k) = {mfccf(ncoeff,speechIn7,FS7)};
end

%将数据保存为mat文件
fields = {‘One’,‘Two’,‘Three’,‘Four’,‘Five’};
s1 = cell2struct(fMatrix1, fields, 2); %fields项作为行
save Vectors1.mat -struct s1;
s2 = cell2struct(fMatrix2, fields, 2);
save Vectors2.mat -struct s2;
s3 = cell2struct(fMatrix3, fields, 2);
save Vectors3.mat -struct s3;
s4 = cell2struct(fMatrix4, fields, 2);
save Vectors4.mat -struct s4;
s5 = cell2struct(fMatrix5, fields, 2);
save Vectors5.mat -struct s5;
s6 = cell2struct(fMatrix6, fields, 2);
save Vectors6.mat -struct s6;
s7 = cell2struct(fMatrix7, fields, 2);
save Vectors7.mat -struct s7;

%%%%%匹配模板%%%
ncoeff = 12; %MFCC参数阶数
N = 5; %10个数字
fs=100000; %采样频率
duration2 = 5; %录音时长
k = 7; %训练样本的人数

speech = audiorecorder(fs,16,1);
disp(‘Press any key to start 5 seconds of speech recording…’);
pause
disp(‘Recording speech…’);
recordblocking(speech,duration2) % duration*fs 为采样点数
speechIn=getaudiodata(speech);
disp(‘Finished recording.’);
disp(‘System is trying to recognize what you have spoken…’);
z=speechIn(:,1);
speechIn= my_vad(z); %端点检测
rMatrix1 = mfccf(ncoeff,speechIn,fs); %采用MFCC系数作为特征矢量
rMatrix = CMN(rMatrix1); %归一化处理

Sco = DTWScores(rMatrix,N); %计算DTW值
[SortedScores,EIndex] = sort(Sco,2); %按行递增排序,并返回对应的原始次序
Nbr = EIndex(:,1:1) %得到每个模板匹配的2个最低值对应的次序

[Modal,Freq] = mode(Nbr(😃); %返回出现频率最高的数Modal及其出现频率Freq

Word = char(‘hello’,‘matlab代码’,‘工作室’,‘欢迎’,‘你’);
if mean(abs(speechIn)) < 0.01
fprintf(‘No microphone connected or you have not said anything.\n’);
elseif (Freq <2) %频率太低不确定
fprintf(‘The word you have said could not be properly recognised.\n’);
else
fprintf(‘You have just said %s.\n’,Word(Modal,:));
end

%%%%来自私人定制程序文案工作室%%%%
https://weidian.com/?userid=1808020072&wfr=wx&sfr=app&source=shop&from=singlemessage

2015-04-03 12:31:22 fandaoerji 阅读数 11399

HMM+GMM语音识别技术详解级PMTK3中的实例

本人正在攻读计算机博士学位,目前一直再学习各种模型啊算法之类的。所以一直想把自己的学习过程总结一下,所以就开通了这个博客。

这两天一直再看语音识别方面的知识,想把自己的理解总结一下,希望对其他学习的人有所帮助。

提前需要掌握的知识:

  • 语音信号基础:语音信号的表示形式、分帧、特征(MFCC)、音素等等
  • HMM模型:离散隐马尔科夫模型级3个问题的求解方法
  • GMM:混合高斯模型,用于连续隐马尔科夫模型。

语音数据处理

语音信号计算机中是采用PCM编码按时间序列保存的一连串数据。计算机中最原始语音文件是wav,可以通过各种录音软件录制,录制是包括三个参数

  • fs:采样率 8000Hz 115200Hz 等等,代表每1秒保存的语音数据点数
  • bits:每个采样点用几个二进制保存
  • 通道:很多音频都有左右2个通道,在语音识别中通常有一个通道的数据就够了。

下面是一个 apple.wav 文件在matlab中的例子:

[x fs bit]=wavread('apple.wave');
plot(x);
--------------
fs =8000
bits =16
--------------

这里写图片描述

x读取到的声音文件数据,长度是2694个采样点数据,其中wavread已经把每个采样点的16bit二进制转换成了-1~+1之间的实数了。所以声音对于我们出来来说就是一个一位数组了。
刚才的apple.wave这个声音时间才是0.33675秒长语音,但数据量还是巨大的。所以语音信号做各种处理时不是把整个x去做运算,而是把他分割固定的一小段一小段的样子,叫做帧。帧应该多长呢?通常用20ms作为一个帧长。那20ms中包括多少个采样点呢,这个和采样速率fs有关。T=1/fs是采样间隔,那么一帧的数据长度 N=帧时间长度/T=帧时间长度(单位秒)*fs(单位Hz)
上例子中 N=(20ms/1000)*8000=160
分帧后的效果
这里写图片描述
上图中帧和帧是挨着的,实际中通常让他们有一定的重贴,这样帧序列可以更好的反应语音信号特点。
接下来语音信号处理都是针对每个帧来处理了,而且帧长是固定,这样处理起来比较方面的 。上例子可以一帧数据包括160个点,

    Fs = 8000;
    framesize = 80;%真长
    overlap = 20;%帧课重叠部分长度
    frames = enframe(x, hamming(framesize), overlap);
    >> size(frames)
        131    80

这样刚才的语音就分成了131个帧了,每帧包含80数据。
80个数据点对于我们来说也比较多的,能不能再进一步减少呢?当然可以这就是特征提取了。现在语音识别中常用的特征是MFCC(可以参照:http://blog.csdn.net/xiaoding133/article/details/8106672)。我们需要知道80个数据点最后提取了多长的特征呢?答案是12个点。
这样语音数据就被进一步缩小了变成131个帧,每帧12点数据了。这样有2个好处:(1)运算量降低 (2)特征比原始语音有更好的分辨能力。到此语音数据的处理部分就可以告一段落了。接下来的问题是这些语音数据和HMM模型怎么关联起来呢?

HMM模型

HMM模型的基本知识一定要读A tutorial on Hidden Markov Models and selected applications in speech recognition, L. Rabiner, 1989, Proc. IEEE 77(2):257–286. 相信我这个英文写的HMM说明比很多中文网站里写的要好懂很多。这里假设大家都懂了HMM模型是什么,我主要说一下,HMM模型怎么用到语音识别的吧。
先从最简单的少词汇量的识别情况说起。

少词汇量语音识别

假设我们要识别的词汇只有 ‘apple’ ‘banana’ ‘kiwi’ ‘lime’ ‘orange’ ‘peach’ ‘pineapple’ 这7个单词。那假设找了15个人,每人说一遍这8个单词然后录音,分别保存成apple01.wav apple02.wav等。这样就得到了每次词15个录音,总共105个wav文件。这就是原始数据。这些数据需要按前面所说分辨成MFCC特征文件。

在少词汇量识别中可以为每个词汇建立一个HMM模型。这个例子中可以建立7个HMM。HMM模型描述包括:

  • 状态个数N:整数
  • 转移概率A:N×N矩阵
  • 初始概率π:N×1矩阵
  • 观察序列概率B:N×T矩阵 T是观察符号集个数
  • 观察符号:模型输出的东西,可以是数值也可以是向量

其中模型参数B有很多讲究。如果是离散HMM那么B就是个每个状态下可能产生观察符号的概率,对于连续HMM就不能用离散概率来描述输出符号了。举一个例子,论文中有掷骰子的例子,这个HMM的观察符号是离散的1、2、3、4、5、6中的一个。他们观察的情况可以用概率来描述。现在我举一个连续HMM的例子,我有2个小球,一个红色,一个绿色,他们的重量不一样。有一个盒子长度和宽度分别是100cm。最开始我随机取一个球扔进盒子里,等球最后停止运动时记录下它在盒子中的坐标(如下图所示)。然后投掷一个硬币若是正面继续使用刚才的球重复试验,否则换另一个球重复试验。
这里写图片描述
为这个过程建立一个HMM模型来描述。其中
N=2分别代表目前用的是红球还是绿球
π=[0.5 0.5] 试验开始我随机取了一个球因此取到红球或绿球的概率一样
A=[
0.8 0.2
0.2 0.8
] 假设我用的硬币质量不均匀,出正面的概率是0.8 背面是0.2
O={x,y} 把球落入盒子的坐标作为观察序列。
假设第一个试验得到的坐标是 {10.5 38.8},第二次{76.5 18.3}依此类推。现在的问题是HMM中的B矩阵怎么描述?显然我的观察序列可能出现的坐标有无穷多种(假设是实数坐标),所以离散HMM无法试用了,因为无法穷举我所有的可能的输出。那怎么办呢?可以把观察符号集可以看做是服从连续分布的二维随机变量。连续变量只能用概率密度函数去描述了,而直接说取某个值的概率是无意义的(因为都是无穷小)。我们最熟知分布有:均匀分布、高斯分布等等。那刚才的例子中观察符号的出现服从什么分布?显然我们不知道具体分布。那有没有近似的方法呢?有,那就是混合高斯模型GMM(参照http://blog.pluskid.org/?p=39)。先简化一个,假设观察序列符合高斯分布,那问题是这个假设的高斯分布的均值和方差是多少呢?只要知道这2个参数我们就知道了这个实验的观察符号的服从规律了。那我们假设是不是合理呢?通常情况下自然界很多事情都服从高斯分布,如果这例子本来就不是高斯分布这时我们无法用某个我们已知的概率分布去描述,这时可以用多个高斯分布的线性叠加来描述,这既是GMM。
接下来说一下HMM的隐含性。刚才的例子我已经告诉了N,A,π这些参数,但如果我不告诉你这些参数,而我再幕布后做了这个实验(当然我自己知道,你现在不知道)做了10000次,得到了10000个观察符号,就是观察序列O。然后我把这个O给你,你能不能把我用的N,A,π,观察符号概率分布参数 预测出来?这就是HMM的训练问题。当然这实验是我设计的,所以我是已经知道了各个参数的,你不知道。但很多自然界中的情况我们是提前不能知道参数,而只能看到输出序列,所以我们需要找到系参数让他最能符合这个输出序列(EM算法)。上面的例子如果我不知道参数,只知道观察序列,那么可以这么做,先假设系统的各个参数,然后不停的改变参数让P(O|λ)最大。其中λ={π A μ Σ} 其中{μ Σ}值假设输出时连续单高斯分布时的均值和协方差(多为输出时对应均值向量和协方差矩阵)。
说了很多,再回到语音识别的问题上。要识别7个单词,那就建立7个HMM,那第一个问题HMM的状态用几个?这个需要根据情况来定,看看状态代表什么含义。在整词建模中我们可以认为每个状态代表一个音素,比如apple(ae p l)就是有3个音素构成,那么给apple的HMM定义3个状态。banana(b ax n aa n ax)由6个音素构成,可以用6个状态HMM建模。为了简单也可以为每个词都建立相同状态数的HMM模型,这时就不能说状态精确代表是音素了,可能对应的半音素或几个音素。第二个HMM的观察序列是什么?用语音数据每一帧的MFCC数据作为一个观察符号,一个语音文件的全部MFCC就是观察序列。显然上例子中我的观察符号是2维向量,语音识别例子里就变成12维向量了,而且是连续形式的。第三个问题状态转移有什么限制?用left-right形式的HMM
这里写图片描述
这种HMM的A=[
0.2 0.8 0
0 0.2 0.8
0 0 1
] (其中数值时假设的)
这时由语音信号的特点决定的这个类型的HMM。因为如果每个状态代表一个音素,语音一般是一个音素接一个音素这样说,很少出现跳过中间音素,自循环的跳转主要对应发音时声音可能拉长或缩短对应这种情况。
第四个问题每个状态下的观察符号的概率用什么描述?假设单高斯分布(或混合高斯分布,更精确)。
这样一个这个HMM 的定义就有了 λ={N π A μ Σ}
接下来就用各自的观察序列训练各自的模型(就是找到最优的π A μ Σ的问题)。
接下来说一下识别方法。假设有了一段语音那他们到底是哪个单词的发音呢?先把语音分帧变成MFCC序列O,然后分别计算
P(O|λ_apple)
P(O|λ_banana)
P(O|λ_kiwi)
P(O|λ_lime)
P(O|λ_orange)
P(O|λ_peach)
P(O|λ_pineapple)
取最大值作为识别结果输出。这个计算时HMM的第一个问题,可以用前向后项算法计算。
致词希望我把有限词汇量的问题说清楚了,具体算法层面的细节需要仔细阅读上面给出的参考论文。

连续大词汇量语音识别

HMM模型

给每个词单独建立一个HMM的思路在连续大词汇量语音识别中显然不再试用了(词语太多了,而且连续说话时词语的发音会有不同)。那怎么办呢?使识别单元缩小,目前使用较多的是音素
ONE w ah n
YOUNG y ah ng
这时英文单词one,young的音素,其中ah就是他们公共都有的音素了,这样音素真个语音中就比较少了。给出每个单词由哪些音素构成的叫做读音词典,想做语音识别必须先要有读音词典,英文读音词典例子。连续语音识别的基本思想是找出所有音素(数量大概有几十或几百个吧,但要比单词数量少了很多了这就是选择音素的愿意),然后为每个音素建立一个HMM,然后用各自的音素数据训练各自的HMM模型。
其中HMM模型和语音对应的关系和单个词时的一样,同样用每帧的MFCC特征作为HMM的观察符号(帧是最小单位,比如one这个词的发音包含3个音素,one的wav数据可以分成几百个帧,所以一个音素可以包含多个帧)HMM状态数通常用5个,其中第一个和最后一个状态没有实际意义,中间三个状态分别代表音素开始阶段、音素稳定阶段、音素结束阶段,这三个状态才发射观察序列,头和尾的状态不发射,头和尾状态其他音素连接时一般要去掉的。如下图所示一个音素模型的HMM结构:
这里写图片描述
这样就能碰另一个问题,一个发音数据中我们怎么知道每个音素从哪儿开始到哪儿结束呢?这叫做音素标注问题。现在有2种做法一种是HMM训练用已经标注的wav文件,另一种是不需要标注也能训练HMM。所谓标准一般需要人工进行,需要听声音,然后判断每个音素的边界。比如one为例0~80ms是发音“w”,81~136ms是发音”ah”,136~536ms是“n”。英文里有timit语料库,有音素标准文件。当然这个标注会非常耗费人力的工作,现在也有语音无需标准就能训练HMM的办法的叫做embedded training (嵌入式训练) ,只需给出语音文件和音素序列就可以比如 语音文件是one.wav 音素信息是“w ah n”,而不用详细给出音素分界线。
有了音素以后就可以用串联音素模型构成字的HMM模型(当然要借助发音词典)。比如英文SIX(s ih k s)由4个音素组成,每个音素又由3状态的HMM构成(连接时头和尾状态要去掉),那么整个SIX的HMM就下图所示(Sb代表第一个音素‘s’的开始阶段的状态):
这里写图片描述
同理如果有一个句子“call nine one one”,同样可以为它建立HMM模型(先用音素串联构成词,词串联构成句子)。这个句子的音素构成是“k ao l n ay n w ah n w ah n”,总共有12个音素。句子的HMM的A矩阵和B矩阵是有各个音素HMM的A矩阵和B矩阵构成的。比如音素“k”HMM定义的A矩阵如下:
A_k=[
0 1 0 0 0
0 1/2 1/2 0 0
0 0 1/2 1/2 0
0 0 0 1/2 1/2
0 0 0 0 0
]

A_ao=[
0 1 0 0 0
0 1/2 1/2 0 0
0 0 1/2 1/2 0
0 0 0 1/2 1/2
0 0 0 0 0
]

A_l=[
0 1 0 0 0
0 1/2 1/2 0 0
0 0 1/2 1/2 0
0 0 0 1/2 1/2
0 0 0 0 0
]

那”call”的HMM的A矩阵就是
A_call=[
0 1 0 0 0 0 0 0 0 0 0
0 1/2 1/2 0 0 0 0 0 0 0 0
0 0 1/2 1/2 0 0 0 0 0 0 0
0 0 0 1/2 1/2 0 0 0 0 0 0
0 0 0 0 1/2 1/2 0 0 0 0 0
0 0 0 0 0 1/2 1/2 0 0 0 0
0 0 0 0 0 0 1/2 1/2 0 0 0
0 0 0 0 0 0 0 1/2 1/2 0 0
0 0 0 0 0 0 0 0 1/2 1/2 0
0 0 0 0 0 0 0 0 0 1/2 1/2
0 0 0 0 0 0 0 0 0 0 0
]
句子以此类推。A矩阵中和多地方都是0,代表不可能的状态转移。句子中的B矩阵和音素的B矩阵一样,但一个句子音素可能出现多次,因此B矩阵是可以共享的。

Embedded Training

我们的目的是训练各个音素的HMM模型参数,用这个HMM模型去代表语音的音素。最简单的训练方式是我们有很多音素对应的观察序列,然后用Baum-Welch算法(EM算法的一个实现方式)去训练A、B矩阵。但前面说过我们很难从一个句子或词语的发音中精确的找到音素、甚至是伴音素的边界。为了解决这个苦难一般采用embedded training的方式。embedded training需要的数据包括:
①训练用的句子的文本文件、例子: call nine one one !
②读音词典。例子:
CALL k ao l
NINE n ay n
ONE w ah n
③语音文件。sen01.wav sen02.wav
④音素列表级音素原始HMM定义
embedded training的基本思路是:读取一个句子的文本、把文本表示的一个句子转成用音素表示的句子(利用读音词典)、利用原始音素HMM定义串联起来构成句子的HMM定义(可能是非常长的HMM了)。然后把一个句子的wav文件转换成帧、提取特征,变成长的特征序列。然后把整个句子的特征序列看做是句子HMM模型的观察序列,直接却训练长的句子HMM模型(这时和普通的HMM模型一样用Baum-Welch算法)。句子训练好以后实际上各个音素也训练好了(因为句子的A、B矩阵就由音素的A、B矩阵构成)。看下图:
这里写图片描述
算法步骤如下:
1.为每个训练句子建立整句HMM模型
2.初始化整句HMM模型的A矩阵,其中开始和结束状态外,每个状态只能到自己或下一个状态,概率分别是0.5
3.所有状态的B矩阵(一般用混合高斯模型)用全部训练样本的均值和方差初始化高斯模型的均值和方差
4.多次执行Baum-Welch算法。

语音解码

如上所属如果所有音素的HMM都训练好了,那么现在来了一个声音文件、怎么转换成文本呢?这就是语音解码问题。“给定一个音素模型的观察序列,和他对应的概率最大的文字序列是什么?”这就是解码问题。

观察序列 O=o1,o2,o3,...,ot,
文本序列 W=w1,w2,w3,...,wt,
这里写图片描述
识别就是在给定观察序列(代表的是声音信息)下,在所有的文字序列集合中哪个的概率最高的问题。把概率最高的文字序列看做是语音识别的结果。计算P(W|O)的难度比较大,所以这里通过贝叶斯公式进行转换如下:
这里写图片描述
其中P(W)是文字先验概率(N-gram模型可以描述),P(O|W)是已知文字下获得观察序列O的概率叫做声学模型(HMM模型可以描述)。P(O)在分母上,对所有的W都是一样的所以可以忽略不用计算。那就变成:
这里写图片描述
这两项概率一般需要做一些权重的修正,实际中经常使用:
这里写图片描述
第二个公式取对数后的形式(计算一般用对数概率),其中LMSF是语言模型的放大倍数同行取5~15之间的数,N:文字长度,WIP是常数叫做word insertion penalty

连续语音识别中解码的难点:
- 连续语音中词与词的边界是不知道的
- 给出一段语音信号,其中包含的额文字个数是未知的
- 搜索全部可能性是很难的,比如总共有M个词,语音长度是V个帧,全部组合是Mv这么多可能性,无法全部遍历。

解码的基本思路:
用训练好的音素模型为每个字构建HMM模型(字个数应该包含目标语种中全部或常用的字)。其中字与字之间的关系用语言模型来描述(N-gram)。字和发音序列之间的关系用HMM模型来描述。利用这两部分信息构建一个庞大的网状结构(具体实现形式可以有很多种)叫做搜索空间,然后在这个上运行搜索算法(有Viterbi算法、Viterbi with Beam-Pruning、Token传递算法等等)获得最优可能的文字序列作为识别结果。

其中搜索空间可以看成是三层结构:网络层、字层、HMM层。如图所示:
这里写图片描述
对未知的语音序列,假设有T个帧构成。从识别网络所有可能入口开始经过T个HMM发射状态都叫做一个识别路径。每个路径都可以计算一个对数概率值。每个路径可能包含 音素HMM状态之间的转移、音素边界之间的转移和字边界之间的转移三部分。HMM内部概率可以由HMM模型计算、音素边界可以用固定概率、字边界转移概率可以用语言模型的N-gram概率提前获得。
Token Passing Algorithm
每个Token代表识别网络中的一个路径,内部存储该条路径的概率和回溯信息。t=0时刻,每个可能的开始节点(对应于音素HMM的状态)生成一个token。每经过1帧(t=t+1)token向所有可能的下一个节点传播(当前节点和多个节点有连接时token复制)。每次转播到发射节点(音素边界、字边界也看做是节点但不发射观察序列)时暂停,然后token里记录的对数概率增加(参考转移概率A和观察序列矩阵B),然后再传播。可以规定每个节点最多同时保持N个token(最简单情况N=1,保留多个token中概率最高的一个进行传播,或者采取一些剪枝策略(purning))。其中token穿过字边界时可以把N-gram模型的概率加入到token的对数概率里,这样就综合考虑和音素模型和语言模型了。同时穿过字边界时需要记录路径,最后结束时用回溯列出识别文字(从这一点上看识别网络中不存的字肯定是无法识别的了)。

三音素模型

所有上述内容都用单音素模型了,实际中通常使用三音素模型(Triphone)。需要考虑上下音素的协同发音情况。例子:
单音素:BRYAN → B R AY AX N
三音素:BRYAN → SIL-B+R B-R+AY R-AY+AX AY-AX+N AX-N+SIL
其中“-”代表当前音素,“+”代表后续音素,“-”号前的代表前面的音素。三音素的好处就是音素级别建模更精确了,不如本来有50个音素,单因素只需要训练50个HMM,三音素就出现503=12500个HMM需要训练了。参数就会变得巨大,相比训练数据就会稀疏很多了。解决方案就是:三音素合并、状态共享等。并不是所有的三音素都合法、其次有些三音素很接近利用一些聚类的方式可以合并三音素减少模型数量。其次观察矩阵B对于很多音素出现再不同的三音素里可能是差不多的,这时就可以共享同一个B矩阵了(详细省略)。
至此原理部分基本讲完了,希望大家能看懂
主要用的资料有:

HMM基础论http://www.cs.ubc.ca/~murphyk/Software/HMM/rabiner.pdf
HTK说明文档 htkbook.pdf (网上可下载)
【Speech and Language Processing】Daniel Jurafsky & James H. Martin 提取码:ceye

本文中有些图是摘自上述资料。

实例

PMTK是matlab中机器学习工具包。包含了很多现成的模型和算法。下面主要用他的HMM模型做一下语音识别。其中和HMM有关的代码都在pmtk3\toolbox\LatentVariableModels\hmm里面。下面是一些函数的使用说明:

创建HMM模型
function model = hmmCreate(type, pi, A, emission)
type:类型,有discrete:离散  gauss:高斯,每个状态用单个高斯分布描述  mixgausstied:混合高斯,但所有状态都用相同的分布   studentpi:初始状态概率
A:转移矩阵
emission:发射状态描述(对应于离散时的B矩阵,但PMTK里用一个结构体描述,可以对应离散和连续多种情况,这个参数一般用其他函数生成)

快速状态符合高斯分布的HMM,这个函数里调用hmmCreate取创建,其中pi  A都随机生成,emission用condGaussCpdCreate函数生成、均值和方差也随机生成
function model = mkRndGaussHmm(nstates, d)
nstates:状态个数
d:一个观察符号的维度

运行HMM模型nsamples(默认1)次,每次状态转移len次(就是得到的观察序列长度是len),observed是生成的样本,hidden是对应的状态
function [observed, hidden] = hmmSample(model, len, nsamples) 

HMM训练函数
function [model, loglikHist] = hmmFitEm(data, nstates, type, varargin)
data:观察序列
nstates:状态个数
type:类型,有discrete:离散  gauss:高斯  mixgausstied:混合高斯   student:
varargin:可变参数,这里可以携带很多参数,一般采用 'name','value','name','value' 的形式
调用例子
model = hmmFit(data, 2, 'gauss', 'verbose', true, 'piPrior', [3 2], 'emissionPrior', prior, 'nRandomRestarts', 2, 'maxIter', 10);
【'verbose', true, 'piPrior', [3 2], 'emissionPrior', prior, 'nRandomRestarts', 2, 'maxIter', 10】就是属于varargin部分,比如【'maxIter', 10】代表最大迭代次数是10,其他都是算法中要用到的指标,可以指定也可以走默认值。

HMM训练函数
function [model, loglikHist] = hmmFit(data, nstates, type, varargin)hmmFitEm一样,内部就是调用的hmmFitEmhmmLogprob(trueModel, observed):计算对数概率,再模型trueModel下,观察到observed的概率是多少。出来的都是负数,绝对值越大表示概率越接近0(越小)

path=hmmMap(model, X):再模型model下,观察数列X最后可能的路径计算函数(viterbi算法)。

给出模型和观察序列X,该函数计算HMM中常用的5个指标
function [gamma, logp, alpha, beta, B] = hmmInferNodes(model, X)
% logp = log p(X | model)   对数概率
% alpha(i, t) = p(S(t)=i | X(:, 1:t)    (filtered)   α变量
% beta(i,t) propto p(X(:, t+1:T) | S(t=i))   β变量
% gamma(i,t)  = p(S(t)=i | X(:, 1:T))   (smoothed)  γ变量
% B - soft evidence  根据X推算出来的B矩阵

下面是做少量词汇识别的 main.m 代码
其中用了MFCC转换用到了HTK MFCC MATLAB
HMM模型用了PMTK3的库PMTK3
语音文件和load_audio_from_folder.m代码来自hmm-speech-recognition

googlecode国内访问不了的话有些资源可能下载不了
我自己写全代码下载链接:提取码 nd5h
pmtk3 和 mfcc 自行下载并安装或把路径制定到你自己的matlab环境里,我在win7+matlab2010a 环境运行正常

clc;  clear all;  close all;

fs=8000;

Tw = 25;                % analysis frame duration (ms)  帧长
Ts = 10;                % analysis frame shift (ms)  帧移
alpha = 0.97;           % preemphasis coefficient  语音增强
M = 20;                 % number of filterbank channels   
C = 12;                 % number of cepstral coefficients MFCC个数
L = 22;                 % cepstral sine lifter parameter  
LF = 300;               % lower frequency limit (Hz)  
HF = 3700;              % upper frequency limit (Hz)

%训练用数据
[train_signals train_labels] = load_audio_from_folder('train');%读取语音文件、生成标签数据
%转MFCC参数
train_feature={};
for speech=train_signals
    [ MFCCs, FBEs, frames ] = mfcc( speech{1}, fs, Tw, Ts, alpha, @hamming, [LF HF], M, C+1, L );    
    train_feature(end+1,1)={MFCCs};
end;

%测试用数据
[test_signals test_labels] = load_audio_from_folder('test');%读取语音文件、生成标签数据
%转MFCC参数
test_feature={};
for speech=test_signals
    [ MFCCs, FBEs, frames ] = mfcc( speech{1}, fs, Tw, Ts, alpha, @hamming, [LF HF], M, C+1, L );    
    test_feature(end+1,1)={MFCCs};
end;

%% HMM模型建立和训练
d = C+1; %一个观察符号的维度
nstates = 5;%状态个数
nmix    = 3; % 混合高斯分布个数

%训练apple的HMM
pi0=[1  0  0  0  0]; %初始状态概率
trans0=[1/2  1/2   0   0     0  ; %转移概率 
        0    1/2  1/2   0    0  ; 
        0    0    1/2  1/2   0  ; 
        0    0     0   1/2  1/2 ; 
        0    0     0    0    1  ];


models={};
[unique_train_labels, ~, indices] = unique(train_labels);%重复去掉,只取唯一值
for i = 1:length(unique_train_labels)
    display(sprintf('modeling %s...', char(unique_train_labels(i))))

    %发射概率初始值计算
    stackedData = cell2mat(train_feature(indices == i)')';%训练用数据
    mu = zeros(d, nmix);%均值
    Sigma = zeros(d, d, nmix);%方差
    for k = 1:nmix
        XX             = stackedData + randn(size(stackedData));
        mu(:, k)       = colvec(mean(XX));%所有训练数据的均值
        Sigma(:, :, k) = cov(XX);%所有训练数据的方差
    end
    M = normalize(rand(nstates, nmix), 1);%混合高斯系数
    emission = condMixGaussTiedCpdCreate(mu, Sigma, M);%发射状态描述结构体获得

    %训练HMM
    %verbose:是否打印信息
    %nRandomRestarts:随机训练几次
    %maxiter:最大迭代次数
    %nmix:混合高斯个数
    %pi0:HMM初始状态概率
    %trans0:HMM初始转移概率
    %emission0:初始发射状态描述
    %piPrior:防止除数为0的情况出现   a/b=a+piPrior/b+piPrior  变成这种形式
    %transPrior:防止除数为0的情况出现   a/b=a+piPrior/b+piPrior  变成这种形式
    models(end+1,1) = {hmmFit(train_feature(indices == i), nstates, 'mixGaussTied', 'verbose', false, ...
                        'nRandomRestarts', 3, 'maxiter', 50, 'nmix', nmix,...
                        'pi0',pi0,'trans0',trans0,'emission0',emission, ...
                        'piPrior',pi0,'transPrior',trans0.*10)}; 
end;

%训练样本识别率计算
errorcount=0;
for j=1:length(train_feature)
    p=zeros(length(unique_train_labels),1);
    for i = 1:length(unique_train_labels)
        p(i)=hmmLogprob(models{i}, train_feature(j));%计算概率值
    end;
    [~, i]=max(p);%取最大概率的模型作为识别
    %display(sprintf('"%s" is recognized as "%s"', train_labels{j},char(unique_train_labels(i))))
    if ~strcmp(train_labels{j},char(unique_train_labels(i)))
        errorcount=errorcount+1;%错误累计
    end;
end;
display(sprintf('train accuracy is %0.2f', (length(train_feature)-errorcount)*100/length(train_feature)));

%% 测试样本识别率计算
errorcount=0;
for j=1:length(test_feature)
    p=zeros(length(unique_train_labels),1);
    for i = 1:length(unique_train_labels)
        p(i)=hmmLogprob(models{i}, test_feature(j));%计算概率值
    end;
    [~, i]=max(p);%取最大概率的模型作为识别
    %display(sprintf('"%s" is recognized as "%s"', test_labels{j},char(unique_train_labels(i))))
    if ~strcmp(test_labels{j},char(unique_train_labels(i)))
        errorcount=errorcount+1;%错误累计
    end;
end;
display(sprintf('test accuracy is %0.2f', (length(test_labels)-errorcount)*100/length(test_labels)));

load_audio_from_folder.m 代码

function [audio_signals, word_labels] = load_audio_from_folder(audio_folder)
    audio_signals = {};
    word_labels = {};

    for word_folder = struct2cell(dir(audio_folder))
        for word_file = struct2cell(dir(sprintf('%s/%s/*.wav', audio_folder, char(word_folder(1)))))
            file_path = sprintf('%s/%s/%s', audio_folder, char(word_folder(1)), char(word_file(1)));
            [x fs bit]=wavread(file_path);
            audio_signals(end + 1) = {x(:,1)}; %#ok<AGROW>
            word_labels(end + 1) = word_folder(1); %#ok<AGROW>
        end
    end
end

待改进的地方有:
1. MFCC特征现在只用了最原始MFCC,可以把一介差分、二介差分加入构成39维度的特征
2. 连续语音识别模型建立
3. 连续语音三音素和参数共享等

可以自己进一步实现上述功能,不过也可以直接使用HTK工具。不过上述内容可以加深对HMM的理解,并有助于提高自己的编程能力。

全部结束感谢大家的阅读!

2020-03-23 19:25:18 u014365862 阅读数 151

前部分既然实战,那就直接代码,理论不清楚的看这里:

(1)04 隐马尔可夫模型 (HMM)
https://blog.csdn.net/u014365862/article/details/105007027
(2)一个隐马尔科夫模型的应用实例:中文分词: https://blog.csdn.net/u014365862/article/details/54891582

'''
下面抽取5次,得到已知的观察序列,
来对HMM的参数进行估计,即使用MultinomialHMM进行参数的训练

'''

import numpy as np
import hmmlearn.hmm as hmm

states = ['盒子1', '盒子2', '盒子3']
obs = ['白球', '黑球']
n_states = len(states)
m_obs = len(obs)

model2 = hmm.MultinomialHMM(n_components=n_states, n_iter=20, tol=0.001)
X2 = np.array([
    [0, 1, 0, 0, 1],
    [0, 0, 0, 1, 1],
    [1, 1, 0, 1, 0],
    [0, 1, 0, 1, 1],
    [0, 0, 0, 1, 0]
])
model2.fit(X2)
print("输出根据数据训练出来的π")
print(model2.startprob_)
print("输出根据数据训练出来的A")
print(model2.transmat_)
print("输出根据数据训练出来的B")
print(model2.emissionprob_)
输出根据数据训练出来的π
[  9.99999998e-01   1.81378454e-09   8.05262820e-30]
输出根据数据训练出来的A
[[ 0.30459785  0.18910843  0.50629372]
 [ 0.44920744  0.35079347  0.19999909]
 [ 0.48427612  0.45080508  0.0649188 ]]
输出根据数据训练出来的B
[[ 0.9600675   0.0399325 ]
 [ 0.48750091  0.51249909]
 [ 0.02464824  0.97535176]]

解码问题:已知观察序列,求什么样的隐藏状态序列最可能生成一个给定的观察序列

import numpy as np
import hmmlearn.hmm as hmm

# 首先定义变量
status = ['盒子1', '盒子2', '盒子3']   # 隐藏的状态集合
obs = ['白球', '黑球']    # 观察值集合
n_status = len(status)    # 隐藏状态的长度
m_obs = len(obs)          # 观察值的长度
start_probability = np.array([0.2, 0.5, 0.3])   
'''
初始概率分布: π 表示初次抽时,抽到1盒子的概率是0.2,抽到2盒子的概率是0.5,抽到3盒子的概率是0.3
'''
transition_probability = np.array([
    [0.5, 0.4, 0.1],
    [0.2, 0.2, 0.6],
    [0.2, 0.5, 0.3]
])
'''
状态转移概率矩阵 A[0][0]=0.5 表示当前我抽到1盒子,下次还抽到1盒子的概率是0.5
'''
emission_probalitity = np.array([
    [0.4, 0.6],
    [0.8, 0.2],
    [0.5, 0.5]
])
'''
观测概率矩阵 B:如最初的图,B[0][0]=0.4,表示第一个盒子抽到白球概率0.4,B[0][1]=0.6,表示第一个盒子抽到黑球概率0.6

以上各个参数解释请参考下面链接:
https://www.jianshu.com/p/da633461684f
https://www.jianshu.com/p/0f175b9781de
'''

# 下面开始定义模型
'''
hmmlearn中主要有两种模型,分布为:GaussianHMM和MultinomialHMM;
如果观测值是连续的,那么建议使用GaussianHMM,否则使用MultinomialHMM

参数:
初始的隐藏状态概率π参数为: startprob;
状态转移矩阵A参数为: transmat;
状态和观测值之间的转移矩阵B参数为: emissionprob_(MultinomialHMM模型中)或者在GaussianHMM模型中直接给定均值(means)和方差/协方差矩阵(covars)

'''

model = hmm.MultinomialHMM(n_components=n_status)  # 观测值,球的黑或白,是离散的,n_status隐藏状态的长度
model.startprob_ = start_probability
model.transmat_ = transition_probability
model.emissionprob_ = emission_probalitity


'''
下面运行viterbi预测问题。已知观察序列(白球 黑球 白球 白球 黑球),
求什么样的隐藏状态序列(盒子2 盒子3 盒子2 盒子2 盒子3)最可能生成一个给定的观察序列。

status = ['盒子1', '盒子2', '盒子3']
obs = ['白球', '黑球'] 

'''

se = np.array([[0, 1, 0, 0, 1]]).T   # (白球 黑球 白球 白球 黑球)
logprob, box_index = model.decode(se, algorithm='viterbi')
print("颜色:", end="")
print(" ".join(map(lambda t: obs[t], [0, 1, 0, 0, 1])))
print("盒子:", end="")
print(" ".join(map(lambda t: status[t], box_index)))
print("概率值:", end="")
print(np.exp(logprob)) # 这个是因为在hmmlearn底层将概率进行了对数化,防止出现乘积为0的情况

输出结果如下:

颜色:白球 黑球 白球 白球 黑球
盒子:盒子2 盒子3 盒子2 盒子2 盒子3
概率值:0.002304

理解了hmm理论和简单的实践,再看一下如何用在语音识别上的:

语音信号预处理:

分帧:

首先说说我们做信号处理的目的----获得个频率成分的分布,而实现的该功能的数学方法就是FFT ,FFT要求输入信号时平稳的,语音作为非平稳信号要实现就要通过分帧

这里分帧就涉及到帧长,对于帧长要满足的条件有两点:

1、正常语速下,音素的持续时间大约是 50~200 毫秒,所以帧长一般取为小于 50 毫秒。

2、语音的基频,男声在 100 赫兹左右,女声在 200 赫兹左右,换算成周期就是 10 毫秒和 5 毫秒。既然一帧要包含多个周期,所以一般取至少 20 毫秒。

综上帧长一般取为 20 ~ 50 毫秒,20、25、30、40、50 都是比较常用的数值,以上摘自知乎逻辑上很合理的解释,我通常听见的是(10-30ms)

一帧的数据长度 N=帧时间长度/T=帧时间长度(单位秒)*fs(单位Hz) 

加窗:

加窗的目的是让一帧信号的幅度在两端渐变到 0。渐变对傅里叶变换有好处,可以提高变换结果(即频谱)的分辨率,具体的数学就不讲了

加窗的代价是一帧信号两端的部分被削弱了,没有像中央的部分那样得到重视。弥补的办法是,帧不要背靠背地截取,而是相互重叠一部分。相邻两帧的起始位置的时间差叫做帧移,常见的取法帧移与帧长的比值一般取为0~1/2。

通常加窗之后我们可以通过FFT变化实现特征数的降维以及提取出比原始语音更具表征力的特征

以上可以理解为若干帧对应一个音素,若干音素对应一个单词,如果我们想要识别对应的单词状态,我们只要知道对应的帧状态就行,用计算机能识别的方式最简单的就是概率匹配,这些概率我们就可以通过声学模型获得,所以要做的就是通过训练获得合适的模型参数以拟合好的匹配效果。

GMM+HMM算法

语音识别就分为三步:第一步,把帧识别成状态(难点)。第二步,把状态组合成音素。第三步,把音素组合成单词。第一步可以当做gmm做的,后面都是hmm做的。

声学模型:描述一种语言的基本单位被称为音素Phoneme,例如BRYAN这个词就可以看做是由B, R, AY, AX, N五个音素构成的。英语中貌似有50多个音素,可以用50几个HMM state来表示这些音素,这种表示方法就是context independent模型中的单音素monophone模式。然而语音没有图像识别那么简单,因为我们再说话的时候很多发音都是连在一起的,很难区分,所以一般用左中右三个HMM state来描述一个音素,也就是说BRYAN这个词中的R音素就变成了用B-R, R, R-AY三个HMM state来表示。这样BRYAN这个词根据上下文就需要15个state了,根据所有单词的上下文总共大概需要几千个HMM state,这种方式属于context dependent模型中的三音素triphone模式。这个HMM state的个数在各家语音识别系统中都不一样,是一个需要调的参数。所以声学模型就是如何设置HMM state,对于信号中的每一frame抽怎样的特征,然后用训练什么分类器。

 

可以理解为整个GMM+HMM网络其实主要是为了HMM网络服务的,为什么这么说,先说说HMM对于语音识别需要解决的问题,比如把一系列MFCC特征正确的识别成对应HMM state 系列。这个过程涉及两个概率需要学习,一是把当前frame的特征识别为这个state的概率,也就是通常HMM中说的Likelihood---这里指计算层面(也是GMM中的mean vector 和covariance matrix ),即GMM网络是为了获得当前state状态概率的,二是上个state转化为这个state的概率也就是状态转移概率Transition probabilities,这个过程是HMM中说的 Decoding---这里指计算层面。一个序列转化为另一个序列理论上有指数级种转化方式,所以每一个frame只取概率最高的那个state,这样的路线选择方法被称为Viterbi 方法。

下面结合实际语音输入讲讲整个过程:

首先我们在训练阶段,我们是知道这段语音所表示的句子吧。我们通过句子,然后分词,然后分成每个音素,在隐马尔科夫(HMM)模型中一般用3-5个上述的单元表示一个音素。简单的理解就是我们每个音素的均值和方差矩阵知道,通过我们的句子我们也知道每个音素间的转移概率矩阵。当然,这些是HMM里的事情。提取特征后的第一步就完成了,简单的说就是为了拟合多维高斯函数。

一开始,我们设置每个音素的均值和方差分别为0和1,转移概率矩阵在htk里也是可以设置两头小中间大,这个对于5个状态的hmm,即每个音素分为5个状态。这步就是初始化hmm。

然后,生成各个音素的hmm。这个可以根据发音字典和原始的hmm来生成。

最后,我们根据训练数据来训练音素级的hmm。这里用到hmm的三大问题。通过训练,我们会得到三个参数:初始状态概率分布π、隐含状态序列的转移矩阵A(就是某个状态转移到另一个状态的概率观察序列中的这个均值或者方差的概率)和某个隐含状态下输出观察值的概率分布B(也就是某个隐含状态下对应于)

 

参考:

(1)GMM-HMM语音识别模型 原理篇

: https://blog.csdn.net/abcjennifer/article/details/27346787

(2)https://zhuanlan.zhihu.com/p/63753017

(3) 基于GMM-HMM的语音识别系统(1):https://zhuanlan.zhihu.com/p/107693481

2019-03-07 18:55:21 weixin_43409302 阅读数 1883

一、项目简介

  • 语音识别是人工智能领域的一个重要的应用场景,那么程序究竟是如何听懂语音的呢?
  • 本文将用真实的音频案例,用代码呈现语音识别的基本原理和流程。
  • 同时,将各种声音信号的MFCC矩阵进行可视化,“把声音的美丽画成图”。

1、基本原理

计算机只能识别二进制的数字信息,是无法直接识别音频信息的。因此让机器具有听懂“人话”的功能,必须要将声音的模拟信号转化为数字信号;就是利用模型将声音的音频数据进行量化,并根据需求进行特征提取(一般提取声音信号的MFCC-梅尔频率倒谱系数矩阵),转化为特征矩阵。然后利用大量的相关特征举证对模型进行训练,使模型具备声音分类的功能。
详细原理见:https://blog.csdn.net/bvngh3247/article/details/80778165

2、案例数据

  • 本文采集7类声音数据(7种水果的英文读音wav文件)
  • 7类分别为:apple(苹果),banana(香蕉),orange(橘子),lime(青柠檬),
    kiwi(猕猴桃),peach(桃子),pineapple(菠萝)
  • 训练集各准备14个样本,测试集各一个样本

3、源代码及数据集地址

二、模型创建

1、导入相关工具包

  • 核心工具包:hmmlearn,scipy.io.wavfile,python_speech_features
import os
import warnings
import numpy as np
import scipy.io.wavfile as wf
import python_speech_features as sf
import matplotlib.pyplot as mp
import hmmlearn.hmm as hl
# 过滤代码运行中无关的警告日志
warnings.filterwarnings(
    'ignore', category=DeprecationWarning)
np.seterr(all='ignore')

2、定义语音识别的各类函数

# 定义声音文件的标签和路径的映射字典函数
def search_speeches(directory, speeches):
    # 如果路径不是文件夹则报出异常
    if not os.path.isdir(directory):
        raise IOError("路径" + directory + '不是文件夹')
    # 获取文件夹中的子目录
    for entry in os.listdir(directory):
        # 获取分类文件夹的名称作为分类标签
        label = directory[directory.rfind(
            os.path.sep) + 1:]
        # 拼接新的文件路径
        path = os.path.join(directory, entry)
        # 如果路径为文件夹则继续递归向内查询
        if os.path.isdir(path):
            search_speeches(path, speeches)
        # 如果路径为'.wav'后缀的文件名
        elif os.path.isfile(path) and \
                path.endswith('.wav'):
            # 判断speeches中是否存在label标签
            if label not in speeches:
                speeches[label] = []
            speeches[label].append(path)
    return speeches
# 获取数据集的MFCC矩阵和标签列表
def gen_matrix(speeches):
    path_x, path_y = [], []
    # 获取wav文件类型标签和文件集
    for label, filenames in speeches.items():
        mfccs = np.array([])
        # 遍历每一个wav文件
        for filename in filenames:
            # 提取wav文件的采样率和信号值
            sample_rate, sigs = wf.read(filename)
            # 获取每个音频文件的mfcc
            mfcc = sf.mfcc(sigs, sample_rate)
            if len(mfccs) == 0:
                mfccs = mfcc
            else:
                mfccs = np.append(mfccs, mfcc, axis=0)
        path_x.append(mfccs)
        path_y.append(label)
    return path_x, path_y
# 进行模型训练,获取训练后的模型集
def model_train(path_x, path_y):
    models = {}
    for mfccs, label in zip(path_x, path_y):
        # 利用HMM算法创建模型
        model = hl.GaussianHMM(
            n_components=4, covariance_type='diag',
            n_iter=1000)
        # 获取每个训练样本训练得到的model
        models[label] = model.fit(mfccs)
    return models
# 模型预测,获取样本测试的标签集
def model_pred(path_x, path_y, models):
    pred_test_y = []
    for mfccs in path_x:
        # 初始化最优模型得分和对应的类别
        best_score, best_label = None, None
        # 获取模型和对应的标签
        for label, model in models.items():
            # 计算模型的测试得分
            score = model.score(mfccs)
            # 选择每个类别对应的最优模型参数
            if (best_score is None) or \
                    best_score < score:
                best_score, best_label = score, label
        pred_test_y.append(best_label)
    return pred_test_y
# 定义可视化函数,绘制wav文件对应的MFCC图像
def visualize(path_x, path_y):
    for mfcc, label in zip(path_x, path_y):
        mp.matshow(mfcc.T, cmap='jet', fignum=label)
        mp.title(label, fontsize=20)
        mp.xlabel('Sample', fontsize=14)
        mp.ylabel('Feature', fontsize=14)
        mp.tick_params(which='both', top='False',
                       labeltop='False', labelbottom='True',
                       labelsize=10)
        mp.show()

3、模型训练阶段

# 训练模型阶段
# 获取训练集的标签、文件字典
train_path = 'speeches/training'
train_speeches = {}
train_speeches = search_speeches(
    train_path, train_speeches)
# print(train_speeches)
# 获取格式化训练样本数据集
train_x, train_y = gen_matrix(train_speeches)
# 获取训练模型集合
models = model_train(train_x, train_y)
# print(len(models))

4、模型测试阶段

# 模型预测阶段
# 获取测试集的标签、文件字典
test_path = 'speeches/testing'
test_speeches = {}
test_speeches = search_speeches(
    test_path, test_speeches)
# print(test_speeches)
# 获取格式化训练样本数据集
test_x, test_y = gen_matrix(test_speeches)
# 获取预测结果集
pred_test_y = model_pred(
    test_x, test_y, models)
print('True Value:\n', pred_test_y)
print('Predict Value:\n', test_y)

由上图可见,预测结果均正确,模型是可用的。

5、wav文件可视化

# 可视化各种类别的MFCC图像
visualize(test_x, test_y)

那么来看看声音到底长什么样吧?!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
参考地址:https://blog.csdn.net/bvngh3247/article/details/80778165
https://blog.csdn.net/weixin_38246633/article/details/80648975
https://blog.csdn.net/qq_42584444/article/details/84345613

没有更多推荐了,返回首页