SVM+MFCC在0-9单词识别应用示例

来源:互联网 发布:古墓丽影崛起 for mac 编辑:程序博客网 时间:2024/05/18 15:54

一、要求

1.数据是16KHz采样的,需要降采样到8KHz后使用。
2.考虑选择12维MFCC+12维其差分共24维作为提取的特征
4.训练及识别,分别给出训练集和测试集的识别率。
5.任选一种识别方法(BP/RBF/GMM/DHMM/SVM/ADABOOST)实现识别任务。
6.能够读出和所提供数据库完全一样格式的数据,并给出识别结果显示,包括每一个数字的识别率和最终的平均识别率。
7.描述所进行的一切步骤细节。


二、特征提取
1.语料数据库分配
   和上一个实验所使用的语料库一致,同样是分成两半,一般用来训练,一般用来测试。
   本次试验我分别采取过以下几种方法来选择训练样本集和测试样本集。
① 取每个数字样本的前一半,例如数字1文件夹下面有280个样本,选择前面140额样本当作测试集。
② 每个数字文件夹下面有280个样本,每个人是10样本排列,每次分别取每个人前面5个样本当作训练集,后5个当作测试集。
③ 把每个数字下所有样本当作一个大集合,分别取出奇数命名的样本作为训练集,剩下的偶数命名的样本便充当测试集,或者取出偶数作为样本,奇数作为训练集。
   总结发现: 除了第一种方法,其它两种方法种取样对最终识别率影响差别不是很大。第三种方法,取奇数命名的文件样本的识别率是这三种取法里面最高的,表明这种这法取得语音信号特征也是最全面的。
2.特征选取
   在上一实验中浅要的分析了mfcc和lp特征对于单词识别的优劣,
所以在这个实验中考虑到鲁棒性问题就决定继续沿用这一特征来作为识别手段。
3.特征提取
   1. 预滤波:考虑到接下来使用8KHz频率下采样,保留的将是0-4000Hz频率段的信息,本次实验使用了一个滤波器函数function x = pre_process(y,fs) ,滤波范围[300,3400]的带通滤波器对采集到的信号进行抗混叠滤波。将符合人耳和发声特性信息保留。
   2. 下采样:由于matlab中melbank函数默认参数为8000Hz,所以为了不造成分帧过程中帧移时长错误,再不改变voicebox中函数默认参数前提下,实验中利用 x=downsample(x,2)将得到的16KHz信号降采样为8KHz采样率的语音信号。
   3. 端点检测和归一化:首先将信号归一化x=x/max(abs(x));然后计算设定判定静音短时能量阈值以及静音最大。当静音判定结束之后,标记出信号strat点,同理如果静音超过静音最大长度,标记出end点。这样在特征提取时候极大减少信号中的无用信息,减少特征矩阵维度从而极大减少计算量。除了在dtw动态规整有用之外,“静音”部分带来所有样本的mfcc特征相似度增加,减少了一定的的识别率。
   4. mfcc特征提取:和上一个实验提取特诊操作顺序一致,只是在窗的选择上使用的是缺省值三角窗(triangular shaped filters),在分析窄带信号有着较强的抗干扰能力,旁瓣小,没有负旁瓣。具有很好特征提取能力以及较好避免了信号二次污染。窗长任然是帧数一半平移。
   5. 特征矩阵规整: 虽然经过端点检测,但是每个样本信号长度是不一样的,所以有些信号是10帧*24维,有些是4帧*24维,这就造成了保存特征的矩阵维度也不同。为了便于后面的特征模版训练,需要统一每个样本特征维度。本次试验做法是,检测到如果某个样本特征长度大于5帧,那么就对其每帧信号与相邻的帧进行求取欧式距离来判断他们的相似度,最后保留欧式距离最大的5帧信号,这样即统一了特征矩阵维度,也去除了帧信号之间的冗余度。当判断这某个样本特征长度小于5帧时候,y_mfcc=[x_mfcc;zeros(N-m,n)];然后在后面补0作为信号静音特征。如图,把14帧信号特征整定到了5帧。


图1. 整定前后特征举证对比图


   6. 样本集存贮: 将规整后的训练样本集特征向量和测试集样本特征向量分别保存在trainmfcc.mat和testmfcc.mat。

三、识别测试(SVM)
  1. 选取SVM理由及步骤
   考虑到样本并不是很多,而SVM的优点正好就是小样本分类性好,大规模训练样本和多分类就难以实施。本次试验采用svm方法去分类特征矢量训练拟合,并且用于识别。SVM 的最终决策函数只由少数的支持向量所确定,计算的复杂性取决于支持向量的数目,而不是样本空间的维数,这在某种意义上避免了“维数灾难”。而本次识别结果为10种,相对于24维特征数目很少,所以支持向量机也会很少。而少数支持向量决定了最终结果,这不但可以帮助我们抓住关键样本、“剔除”大量冗余样本,而且注定了该方法不但算法简单,而且具有较好的“鲁棒”性。
   首先是训练所有包含所有分类的支持向量机(SVM)。本次试验做法是分别用某个数字特征向量胞腔(cell,140(14人*10句)*120(5帧*24维))十个胞腔分别求出最佳分类器存放在svmStruct{i,j}这个结构体之中,例如svmStruct{5,6}表示的是数字5特征向量与数字6特征向量训练出的一个分类器,这个分类器可能会很好识别出样本特征属于5或者6。
    用来训练函数:function [svm_struct, svIndex] = svmtrain(training, groupnames, varargin);其中training为用于训练分类的矩阵数据,本实验用的是两个不同数字样本集合training=[trainmfcc{i};trainmfcc{j}];意思是把第i个和第j个数字的所有样本特征向量保存在training矩阵中。Groupnames为分组变量,本实验选取为group=[ones(numx,1);zeros(numx,1)];将上面训练集分为0,1两类的正确识别结果矩阵,数字i分类结果为1,数字j分类结果为0。Varargin为变长度输入宗量,意思是这个输入量是不确定长度的,依靠核函数选取来确定他需要输入哪些参数,详情可以参考doc svmtrain。本次试验选取核函数rbf ,sigma取值为6.4.后面我们详细分析为什么这么选取。最后返回的分类器svmStruct{i,j}是一个结构体,里面包含了许多了分类结果,例如0 1,0 2,0 3,5 6等,为了不重复训练识别机,所以i<j的,不然造成svmStruct{i,j},svmStruct{j,i}或是更严重svmStruct{i,i}识别机。
   2. 识别方式
   由于在上面训练出的识别机是一个结构体集合,所以每次只能在两个数字之间进行分类所以我们具体识别时候也只能在svmStruct遍历地取出每个识别机知道找出识别结果。
   我们选用的识别函数为function SVMCLASSIFY(SVMSTRUCT, TEST);输出分类结果为我们刚才定义的group矩阵中的分类结果0或者1。
   经典的支持向量机算法只给出了二类分类的算法,而在本次试验中要解决多类的分类问题。可以通过多个二类支持向量机的组合来解决。我们用到了DAG算法来遍历svmStruct{i,j}识别机,直到j=i+1的时候找出识别结果。定义DGA首节点为svmStruct{1,10},经过不断i++和j--去遍历多有可能性。如图数字5识别简要流程。

图2. 数字5识别过程DAG算法流程图
   3. 识别结果

图3.SVM识别结果
训练集的数字0的识别率为 100.000000%
训练集的数字1的识别率为 100.000000%
训练集的数字2的识别率为 100.000000%
训练集的数字3的识别率为 100.000000%
训练集的数字4的识别率为 100.000000%
训练集的数字5的识别率为 100.000000%
训练集的数字6的识别率为 100.000000%
训练集的数字7的识别率为 100.000000%
训练集的数字8的识别率为 100.000000%
训练集的数字9的识别率为 100.000000%
训练集总的识别率为 100.000000%
表1.SVM的训练集中每个数字的识别率和总的识别率
测试集的数字0的识别率为 97.142857%
测试集的数字1的识别率为 99.285714%
测试集的数字2的识别率为 94.285714%
测试集的数字3的识别率为 97.857143%
测试集的数字4的识别率为 99.285714%
测试集的数字5的识别率为 97.857143%
训练集的数字6的识别率为 98.571429%
训练集的数字7的识别率为 95.000000%
训练集的数字8的识别率为 97.857143%
训练集的数字9的识别率为 97.857143%
训练集总的识别率为 97.500000%
表2.SVM的测试集中每个数字的识别率和总的识别率

   4. 分析:
   可以看到测试集训练出的识别机再去识别测试集时,识别结果几乎是确定的。而测试集进行识别的结果也很高,其中最低的是数字7的识别率为95%,最高的是数字3的识别率为99.2857%,平均识别率也有97.5%.无论是在识别率还是识别时间和训练时间都要远远优越于DTW,甚至也比VQ+DTW都好。至于为什么会这么好,我在选取SVM那一节已经讲述。

  
   下面我们来讨论一下整个过程中会影响识别率的关键因素。
① 对数据做归一化(simple scaling)
     归一化就是要把你需要处理的数据经过处理后限制在你需要的一定范围内。 归一化有很多好处,在维数非常多的时候,首先可以防止某一维或某几维对数据影响过大。其次归一化是为了后面数据处理的方便,程序可以运行更快,保证程序运行时收敛加快。 所以一开始我在提取mfcc参数之后便开始对参数进行归一化操作:xmfcN=xmfc/max(max(temp*abs(xmfc)));之前在端点检测时候读取原是信号时候默认对信号还进行了一次幅度归一化操作:x=x/max(abs(x));虽然两次归一化对象不同,但是最后识别率反而相比mfcc参数不归一化操作还降低。我在打开mfcc参数表时候发现里面很多参数都很小,可能是由于信号幅值归一化之后,短时能量也会同比例降低,导致最后mfcc系数很小甚至很多系数都快要超出精度了,所以我选择了取消mfcc归一化操作保证特征矩阵数据真实性。
② 预滤波处理
   考虑到经过下采样后,频域会出现周期延拓,边缘部分可能出现频带叠加产生噪声。于是选用了一个[300,3400]的抗混叠滤波器,实际效果对识别率提高了一个百分点左右。
③ 核函数选取
   常选用的内核函数有:线性核函数(linear),多项式核函数(quadratic),RBF核函数,sigmoid核函数 又叫做S形内核。常用的线性函数和RBF比较多,对比线性函数和RBF优劣最终选用了RBF核函数。
   虽然线性函数与RBF能达到差不多效果,但是考虑到本次样本特征仅仅分为10类,而且训练样本数目达到1400,而且RBF也可以模拟出线性函数效果。Linear核:主要用于线性可分的情形。对于高维的就可能会力不从心。在使用RBF只要耐心调好参数一定会有一个比较于Linear核好的结果。本次取值gamma为6.2。
④ 两个重要参数coast和gamma
本次试验调用的matlab自带的svm入门函数,并没有下载libsvm去编译。所以函数没有惩罚因子这个接口,只有gamma接口,本次gamma取值6.4。

附:
1 MATLAB自带的svm实现函数仅支持分类问题,不支持回归问题;而libsvm不仅支持分类问题,亦支持回归问题。 
2 MATLAB自带的svm实现函数仅支持二分类问题,多分类问题需按照多分类的相应算法编程实现;而libsvm采用1v1算法支持多分类。 
3MATLAB自带的svm实现函数采用RBF核函数时无法调节核函数的参数gamma,貌似仅能用默认的;而libsvm可以进行该参数的调节。 
4libsvm中的二次规划问题的解决算法是SMO;而MATLAB自带的svm实现函数中二次规划问题的解法有三种可以选择:经典二次方法;SMO;最小二乘。
  


















0 0
原创粉丝点击