2-10让“说快一点、说慢一点”也能识别数字:MFCC + DTW 孤立数字语音识别

一句话介绍: 这套程序面向 0~9 的孤立数字语音识别。它先对训练语音进行端点检测并提取 MFCC 特征,建立 10 个数字模板;识别时再对测试语音提取同类特征,通过 DTW 对齐不同语速下的特征序列,并选择匹配距离较小的数字作为识别结果。
先看它解决什么问题
同一个人说同一个数字,两次录音也很难完全一样。
例如第一次说“3”比较快,第二次说“3”比较慢,那么两段语音:
长度可能不同;
每个音节出现的时间位置不同;
原始波形无法逐点直接对齐;
即使内容相同,直接比较采样点也可能得到很大的差异。
这套程序采用的思路是:
训练语音 → 端点检测 → MFCC 特征 → 数字模板库
识别时则是:
测试语音 → 端点检测 → MFCC 特征 → DTW 时间对齐 → 与 10 个模板比较 → 输出最匹配数字
其中 MFCC 负责把原始声音转换成更适合比较的声学特征,DTW 则负责解决“同一个数字说快说慢导致时间长度不同”的问题。
1. 这个工程真正包含什么?
压缩包中的主要文件如下。
文件 |
主要作用 |
train.m |
训练阶段入口,用于建立数字语音模板 |
dtwtest.m |
DTW 识别测试相关程序 |
dtw.m |
动态时间规整匹配函数 |
mfcc.m |
MFCC 特征提取 |
vad.m |
语音活动/端点检测 |
melbankm.m |
Mel 滤波器组相关计算 |
enframe.m |
语音分帧 |
enframe.exe、enframe_mex.mexw32 |
分帧相关的编译加速版本 |
mfcc.mat |
工程已经生成好的 0~9 数字模板 |
train/ |
10 条训练语音 |
test/ |
10 条测试语音 |
基于DTW算法的语音识别原理与实现.doc |
工程附带的原理说明文档 |
因此这个项目不是单独一个 dtw.m 算法示例,而是一套完整的:
语音数据 → 端点检测 → MFCC → 模板建立 → DTW 匹配
的小型数字语音识别工程。
2. 工程识别哪些内容?
训练目录中包含:
00.wav、10.wav、20.wav、30.wav、40.wav、50.wav、60.wav、70.wav、80.wav、90.wav
测试目录中包含:
01.wav、11.wav、21.wav、31.wav、41.wav、51.wav、61.wav、71.wav、81.wav、91.wav
从文件组织可以看出,工程为 0~9 共 10 个数字分别准备了一条训练录音和一条测试录音。
可以把文件命名理解成:
数字类别 |
训练样本 |
测试样本 |
0 |
00.wav |
01.wav |
1 |
10.wav |
11.wav |
2 |
20.wav |
21.wav |
3 |
30.wav |
31.wav |
4 |
40.wav |
41.wav |
5 |
50.wav |
51.wav |
6 |
60.wav |
61.wav |
7 |
70.wav |
71.wav |
8 |
80.wav |
81.wav |
9 |
90.wav |
91.wav |
也就是说,当前工程属于小词汇量、孤立数字模板识别,而不是连续句子听写系统。
3. 训练阶段实际保存了什么?
工程自带的 mfcc.mat 可以直接确认模板库结构。
其中变量 ref 一共有 **10 个模板**,每个模板包含:
StartPoint:检测到的语音起点;
EndPoint:检测到的语音终点;
mfcc:有效语音段对应的 MFCC 特征矩阵。
10 个模板的实际尺寸如下。
数字 |
起点帧 |
终点帧 |
有效特征帧数 |
特征维数 |
0 |
66 |
158 |
93 |
24 |
1 |
54 |
137 |
84 |
24 |
2 |
72 |
150 |
79 |
24 |
3 |
38 |
153 |
116 |
24 |
4 |
42 |
137 |
96 |
24 |
5 |
53 |
146 |
94 |
24 |
6 |
78 |
158 |
81 |
24 |
7 |
76 |
180 |
105 |
24 |
8 |
89 |
172 |
84 |
24 |
9 |
79 |
190 |
112 |
24 |
这里有两个很重要的信息。
第一,不同数字经过端点检测后,保留下来的语音长度并不相同,例如数字 2 有 79 帧,而数字 3 有 116 帧。
第二,每一帧保存的是 24 维特征。
这正好说明为什么后续不能用“第 1 帧对第 1 帧、第 2 帧对第 2 帧”的简单方法比较,而需要 DTW 对不同长度的特征序列进行动态对齐。
4. 为什么程序要先做端点检测?
真实录音的前后通常存在一段静音。
如果把这些静音也加入模板匹配,会出现两个问题:
无效帧增加,DTW 计算量变大;
开始录音和结束录音的时间差异可能影响匹配结果。
工程中单独包含 vad.m,而 mfcc.mat 中又保存了每个模板的 StartPoint 和 EndPoint,可以确认这个程序会把有效语音区间单独记录下来。
因此端点检测的作用可以概括成:
整段录音 → 找到真正说话的位置 → 只保留有效数字语音 → 再进行特征提取和匹配
这相当于先回答:
“声音从哪里真正开始,到哪里真正结束?”
再进行识别。
5. MFCC 在这里是做什么的?
MFCC 是 Mel Frequency Cepstral Coefficients,梅尔频率倒谱系数。
程序没有直接拿原始 WAV 波形做 DTW,而是先通过 mfcc.m 把语音转换成特征序列。
从工程结构可以确认,MFCC 处理链至少涉及 enframe.m 的分帧和 melbankm.m 的 Mel 滤波器组。
其整体思想可以理解成:
语音 → 短时分帧 → 频谱分析 → Mel 听觉滤波 → 倒谱特征 → MFCC 序列
MFCC 的价值在于,它不要求两次录音的每个原始采样点完全一样,而是用较低维的参数描述每一小段语音的频谱结构。
对数字语音识别来说,程序真正比较的是:
数字发音过程中声学特征怎样随时间变化。
而不是比较两段 WAV 是否逐采样点完全重合。
6. 为什么不能直接比较两段 MFCC?
即使把原始语音都转换成 MFCC,同一个数字的两次发音仍然可能长度不同。
例如:
模板“5”说得慢,有 94 个特征帧;
新录制的“5”可能只有 80 多帧;
某个音节在模板中持续 10 帧,在测试语音中可能只持续 7 帧。
如果强制逐帧比较,时间位置会逐渐错开。
DTW 就是专门解决这个问题的。
7. DTW 是怎样解决语速差异的?
DTW 全称 Dynamic Time Warping,动态时间规整。
它不是要求:
模板第 20 帧只能和测试语音第 20 帧比较。
而是允许时间轴发生一定程度的“拉伸”和“压缩”。
可以把它想象成两条有弹性的时间轴:
模板:A → B → C → D → E
测试:A → B → B → C → D → E
虽然第二段语音中的某些部分持续时间更长,但 DTW 可以让一个模板帧对应多个相邻测试帧,从而寻找总体代价较小的对齐路线。
最终得到的 DTW 距离可以理解成:
在允许时间伸缩以后,两段语音特征最合理对齐时,还剩下多少差异。
距离越小,一般说明两段特征越相似。
8. 为什么 DTW 特别适合孤立数字识别?
优势一:能够处理不同长度的语音
工程中 10 个训练模板本身就有 79~116 帧的长度差异。测试语音也不可能与训练录音保持完全相同长度。
DTW 不要求两个矩阵具有相同帧数,因此更适合这种自然语音。
优势二:能够容忍局部语速变化
同一个数字并不是简单地“整体快 20%”或“整体慢 20%”。有时前半段说得快,后半段拖得更长。
DTW 的动态路径可以在不同时间位置采用不同的对齐速度,所以比简单整体缩放更灵活。
优势三:和 MFCC 的序列结构天然匹配
MFCC 把语音表示成一帧一帧的特征向量,DTW 刚好用于比较两个随时间变化的特征序列。
二者组合形成:
MFCC 负责“每一帧是什么样” → DTW 负责“这些帧怎样在时间上对齐”
这是这套程序最核心的理论逻辑。
9. 为什么不直接比较原始波形?
原始语音波形对很多细节都很敏感,例如:
麦克风距离;音量;相位;
开始录音的具体时刻;
语速;单个采样点的微小变化。
即使同一个人说同一个数字,也很难得到两条几乎一样的时域波形。
MFCC 先把原始波形压缩成更稳定的短时频谱特征,再让 DTW 处理时间变化,因此比“WAV 波形逐点相减”更符合语音识别问题本身。
10. 为什么不直接用普通欧氏距离?
普通欧氏距离通常要求两组数据长度一致,而且默认:
第 i 个元素就应该和第 i 个元素比较。
但语音中的时间关系具有弹性。
如果一个数字在测试语音中某个音节被拉长,那么后面的特征帧全部都会错位。
DTW 的优势就在于:
比较的不只是特征差异,还同时寻找最合适的时间对应关系。
因此它本质上是“对齐 + 比较”一起完成。
11. 这个程序的识别流程
从工程结构和模板文件可以把完整流程概括为两部分。
建立模板
train/ 数字语音 → VAD 端点检测 → MFCC 特征 → 保存 10 个参考模板到 mfcc.mat
测试识别
test/ **数字语音 → 同类预处理与 MFCC → 与 10 个模板分别进行 DTW → 比较匹配距离 → 输出最接近的数字**
这个方案没有神经网络训练过程,也没有大型统计模型,核心就是:
参考模板 + 特征距离匹配。
12. 这个程序本身有哪些优势?
结构完整: 同时包含训练、测试、端点检测、MFCC 和 DTW。
样例齐全: 0~9 每个数字都有训练和测试 WAV。
模板可直接检查: mfcc.mat 已经保存好 10 个数字的参考特征。
算法透明: 不是一个深度学习黑盒,整个识别逻辑可以拆成清楚的信号处理步骤。
适合教学: 能非常直观地理解“为什么同一个词说快说慢仍然能比较”。
容易替换数据: 理论上只要重新建立对应模板,就可以把数字类别换成其他少量孤立词。
13. 它适合用在哪里?
0~9 数字语音识别实验
这是当前工程最直接的用途,可以用来验证不同数字之间的 MFCC 和 DTW 距离差异。
小词汇量语音命令
例如把 10 个数字换成“开、关、上、下、左、右”等少量固定词,就可以研究简单的离线语音命令识别。
DTW 算法教学
语音天然存在语速变化,因此非常适合演示 DTW 为什么要允许时间轴非线性伸缩。
MFCC 特征教学
工程把 mfcc.m、melbankm.m、enframe.m 分开提供,可以帮助理解经典 MFCC 前端的组成。
14. 怎么运行?
从工程命名可以看出,推荐先建立或加载模板,再进行测试识别。
将 myVoice 目录作为 MATLAB 当前工作目录;
保持 train/、test/、所有 .m 文件以及 mfcc.mat 在原工程结构中;
如果需要重新建立模板,可从 train.m 开始;
如果直接使用工程已有模板,可加载 mfcc.mat;
使用 dtwtest.m 对测试语音执行 DTW 匹配;
查看不同模板距离及最终识别结果。
工程同时提供了 enframe.exe 和 enframe_mex.mexw32,说明原作者还准备了分帧的编译加速版本;在较新的 MATLAB 或非 32 位 Windows 环境中,如果 MEX 文件不兼容,可以优先使用同目录下的 enframe.m MATLAB 版本。
15. 使用自己的录音时需要注意什么?
训练和测试的录音条件尽量一致
DTW 可以解决语速变化,但它并不能自动消除所有环境差异。
如果训练语音在安静环境录制,而测试时存在强噪声、混响或麦克风距离变化,MFCC 本身也会发生改变。
每个类别只有一个模板时,代表性有限
当前工程只有 10 条训练 WAV,也就是每个数字一条训练录音。
这对于算法演示很直观,但同一个数字在不同说话人、不同语气和不同噪声环境下变化很大。
如果希望提高实际识别稳定性,可以为每个数字增加多条训练模板。
DTW 的计算量会随特征长度增加
如果模板有 M 帧、测试语音有 N 帧,传统 DTW 需要在二维匹配区域中寻找路径,因此语音越长、模板越多,计算量越大。
当前只有 10 个短数字,因此比较适合直接模板匹配。
16. 从当前工程可以确认的实际特征
项目 |
当前工程情况 |
识别类别 |
0~9,共 10 类 |
训练语音 |
10 条,每类 1 条 |
测试语音 |
10 条,每类 1 条 |
模板变量 |
ref |
模板数量 |
10 |
模板字段 |
StartPoint、EndPoint、mfcc |
MFCC 维数 |
24 |
训练有效帧长度 |
79~116 帧 |
核心匹配方法 |
DTW |
端点检测模块 |
vad.m |
Mel 滤波器模块 |
melbankm.m |
分帧模块 |
enframe.m |
这张表反映的是当前压缩包和预生成 mfcc.mat 中能够直接确认的信息。
17. 源码使用时值得注意的地方
当前模板库很小
每个数字只有一个训练模板,因此当前项目更适合作为孤立词 DTW 原理演示,不能直接等同于现代大词汇量语音识别系统。
mfcc.mat 已经保存端点后的特征
模板中的 MFCC 行数恰好等于 EndPoint - StartPoint + 1,说明参考模板对应的是端点检测后的有效语音区域,而不是整条录音的所有帧。
MFCC 是 24 维,但具体组成应以 mfcc.m 源码为准
预生成模板可以确认每帧有 24 个特征值,但仅凭模板文件不能严谨断言这 24 维具体由“多少静态系数 + 多少差分系数”组成。若要精确解释每一维的含义,需要直接核对 mfcc.m 的实现。
DTW 的具体局部距离和步进权重应以 dtw.m 为准
可以确认工程使用了自定义 dtw.m 完成动态时间规整,但仅凭文件结构和模板文件,不能可靠断言其内部是否采用普通欧氏距离、平方欧氏距离、特定步进权重或距离归一化。
因此文档中的 DTW 部分解释的是该算法在本项目中的作用和原理,不把无法从当前可确认内容中得到的实现细节写成确定事实。
18. 一句话看懂这个项目
这是一个经典的 MATLAB 孤立数字语音识别程序:它为 0~9 建立 MFCC 参考模板,利用 VAD 去掉录音前后的无效区域,再通过 DTW 对测试语音和模板的特征时间轴进行动态伸缩和匹配,从而解决同一个数字因语速不同而无法直接逐帧比较的问题。
19. 源程序下载
可二次开发工程包:https://mbd.pub/o/bread/mbd-ZpeWl51t
百度网盘链接:
https://pan.baidu.com/s/1iRiXcNdn3MFNkD3Bar7Zbg























全部评论 (0)