语音识别HTK代码学习手册
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
,
,
;对于连续分布的 HMM,记 t 时刻的观察
值概率为
一个离散型的 HMM 模型可以简约的记为
。
二、关于语音识别的 HMM 的三个基本问题
1. 已知观察序列 。
和模型参数 ,如何有效的计算
a. 直接计算
当 N=5,T=100 时大概需进行
b. 前向算法
定义 t 时刻的前向变量(forward variable) 可以通过迭代的方法来计算各个时刻的前向变量:
1) 初始化(Initialization) 当 t=1 时
2) 递归(Induction)
当
时
2-1 次乘法!
,
2-2
即:
2-3
3) 终结(Termination)
2-4 乘法次数大约为:N2T
c. 后向算法
定义 变量:
t 时 刻 的 后 向 变 量 ( backward variable) ,可以通过迭代的方法来计算各个时刻的后向
则最优序列可以通过
2-7
,
2-7
求得。不过,这样求得的最优序列有些问题。如果
,那么这个
最优序列本身就不存在。这里讨论的最佳意义上的最优序列,是使
最
大化时的确定的状态序列。即,使 的状态序列。
最大化时确定
定义 的
为 t 时刻沿一条路径
最
大
概
,且 ,输出观察序列
率
,
即
:
2-8
下面介绍迭代计算 的 Viterbi 算法: 1) 初始化(Initialization)
/* MHEAP 和 MSTAK 块数据结构定义 */ typedef struct _Block{ /* MHEAP
size_t numFree; /* 空闲元素数目
,MSTACK
*/
,空闲字节数 */
size_t firstFree; /* 第一个空闲元素索引
1) 初始化(Initialization)
当 t=T 时
,
2-5
2) 递归(Induction)
当
时
即: 3) 终结(Termination)
,
2-6
2-7 乘法计算次数约为:N2T
2. 已知观察序列 定一个状态序列
和模型参数 ,在最佳意义上确 。
定义一个后验概率变量(posteriori probability variable)
3-1 定义 3.2 给定训练序列 和模型 , 时刻 Markov 链处在状态 的概率定 义如下
3-2
定义 3.3 给定训练序列 和模型 ,从状态 转移出去的概率为 定 义 3.4 给 定 训 练 序 列 和 模 型 , 从 状 态 转 移 到 状 态 的 概 率 为
利用 Baum-Welch 重估算法可以得到使
,
回溯变量:
,
2) 递归(Induction)
即:
2-8
2-9
3) 终结(Termination)
2-10
2-11 4) 回溯状态序列
,
2-12
3. 已知观察序列
数使
最大。
和模型参数 ,如何调整模型参
定义 3.1 给定训练序列 和模型 , 时刻 Markov 链处在状态 和 时 刻处在状态 的概率定义如下
HTK 把堆结构分为三大类:
1. M-HEAPS:元素大小固定,new/free 操作执行次序无限制,可全局重 置(global reset)。
2. M-STACK:元素大小可变,最后分配的空间必须先释放,可全局重置。
3. C-HEAPS:元素大小可变,new/free 操作执行次序无限制,全局重置 无效(直接使用 malloc 和 free 函数)。
1. Baum-Welch 重估公式的理论基础
局部最大时的参数更新公式。
引理 3.1 设 ,
,为正实数, ,
么,由对数函数的凹特性,有如下结论
,为非负实数,那
3-3 定义辅助函数如下
3-4
其中, 为更新前模型参数, 为更新后模型参数,
为
训练序列,
为可能的状态序列。
利用
和引理 3.1 易得
3-5
式 3-5 构成了重估公式得理论基础,对辅助函数
,只要能够找到 ,
使
,从而
,这样,更新后的模型 在拟和训
练序列 方面就比更新前的模型 要好,使 公式就称之为 Baum-Welch 重估公式。
最大而得到的 的参数更新
引 理 3.2
,
,在
的约束条件下,函数
的唯一最大值点为
。
证明如下
求
最大值
令
得:
利用凹函数特性可知此最大值唯一。
2. 离散 HMM 模型的重估公式
第二就是关于内存分配释放操作本身。如果你的程序会相当频繁的执行 malloc 和 free 函数,那么程序将会费去大量的 CPU 时间来执行它们。
为了解决以上两个问题,尽可能的提高内存利用率,HTK 设计了一个内存 管理子系统,利用自定义的堆结构(Heap)来进行内存分配和释放。HTK 内存 分配和释放的主要思想是一次向操作系统要大一些的内存块,然后在将它分成 小块供上层程序使用,不需要时只需释放那个大内存块。
二、数据结构
1. 堆数据结构定义
typedef enum{MHEAP,MSTAK,CHEAP} HEAPTYPE; // 堆类型定义
typedef unsigned char* ByteP; // 无符号字符(8 位)指针 typedef void* Ptr; typedef struct _Block *BlockP;
HMM 的理论基础
一、 HMM 定义
1. N: 模 型 中 状 态 的 数 目 , 记 t 时 刻 Markov 链 所 处 的 状 态 为
百度文库
2. M:每个状态对应的可能的观察数目,记 t 时刻观察到的观察值为
3. :初始状态概率矢量,
,
,
4. A:状态转移概率矩阵,
,
,
5. B: 观 察 值 概 率 矩 阵 ( 适 用 于 离 散 HMM) ,
,同理可证:
HTK 内存管理
一、 HTK 内存管理概述
C 语言编程中,遇到的关于内存分配和释放的问题主要有如下两个方面。
第一是指针维护问题。试想,你写的一个程序执行了一系列内存空间分配 (通常是由 malloc 函数完成)操作,为了能够在以后适当的时候(通常是你不 再需要那些内存时)可以将分配的内存空间释放(通常是由 free 函数完成), 你必须小心谨慎的维护好这些指向分配的内存空间的指针。有经验的程序员大 概都会有这样的感受,维护这些指针并非易事!特别是当程序比较复杂时,尤 为如此。如果你一不小心(其实这很容易)丢掉了某些指针,那么操作系统将 无法回收那些内存(这便是我们常说的内存泄漏问题),除非你的程序死了。