语音识别Viterbi解码

语音识别解码过程使用的是Viterbi算法,本质上是一种动态规划算法,能够得到全局最优解。为了进一步减少计算复杂度,引用了Beam Search 算法,可以在损失微小性能的条件下提高解码速度,Beam Search无法保证全局最优解。

Viterbi解码算法

Viterbi解码

如果从起点到终点有一条最终路径,那么这条路径子路径也是从起点到相应时刻点的最优路径。如上图,红线是一条从起点到终点的最优路径,那么从起点到时刻4的红线部分也是该时间段的最优路径。换句话说,任一时刻,只需记录到该时刻所有状态的最优路径即可,以时刻4为例,在时刻4,只需记录时刻4上经过三个状态S1,S2,S3的最优路径即可,也就是只需要记录三条路径,接着到时刻5,时刻5的S3状态有两条路径经过,取其中最优路径,时刻5的S2、S1状态类似,也就是说到了时刻5,仍然只需要记录三条路径即可
所以每一时刻需要做两次循环,外层循环现在时刻所有状态,内层循环现在时刻某一状态到下一时刻所有状态。时间复杂度N^2,所有时间段时间复杂度TN^2。上图中,N=3,实际大规模语音识别中任一时刻的状态可能很大,比如5000个,这样即使使用了维特比,时间复杂度还是太大,实际中为了解决这个问题,引入了Beam Search算法

Beam Search 算法

Viterbi解码中涉及到现在时刻state数目以及下一时刻state数目,如果我们想要提高解码速度,需要对这两个数值都做缩减。
实际做法是设置阈值,减少语音识别中现在时刻以及下一时刻状态数目,具体做法是:

  1. 对所有状态排序,最优状态放最前面,最优状态得分=best_weight
  2. 设置一个beam,设置阈值1=cur_cutoff,cur_cutoff=best_weight+beam,所有得分在cur_cutoff以内的,保留,反之丢弃,现在时刻的state数目减少。
  3. 计算到下一时刻的最优路径得分new_weight。
  4. 设置一个adaptive_beam, 设置阈值2=next_cutoff,next_cutoff=new_weight+adaptive_beam,所有得分在next_cutoff以内的,保留,反之丢弃,下一时刻的state数目减少。

kaldi实际解码过程中,cur_cutoff、next_cutoff这两个阈值是计算出来,涉及到的传入参数包括:config_.beam,config_.beam_delta,config_.max_active,config_.min_active。之所以引入max_active,min_active是为了保证任意时刻的state数目在[min_active,max_active]之间,单纯的只用beam,有可能会导致某一时刻state数目过大或者过小。

具体Kaldi代码解析见Kaldi 解码代码解析

Reference

http://kaldi-asr.org/doc/index.html

注1: 安德鲁·维特比(Andrew J. Viterbi),CDMA之父,IEEE Fellow ,高通公司创始人之一,高通首席科学家。他开发了卷积码编码的最大似然算法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 隐马尔可夫模型(Hidden Markov Model,HMM) 最初由 L. E. Baum 和其它一些学者发表...
    vlnk2012阅读 6,807评论 3 47
  • Beam Search 简介 一、概要 传统的广度优先策略能够找到最优的路径,但是在搜索空间非常大的情况下,内存...
    MiracleJQ阅读 10,001评论 0 6
  • 真理藏在反常出
    金蟾云世界阅读 107评论 0 0
  • 一、 细节是什么? 细节是在群里弱弱地问了个问题,然后居然接到虞潇君的好友请求,是在他的微信名中“yxjcxf-5...
    小晓真儿阅读 1,017评论 2 2
  • 有一天一个女生冲进校长办公室 对校长说: 【有个男子一直在骚扰我给我写信】 并把所有信件倒在了桌子上 校长阅读后 ...
    Toptatoo阅读 182评论 0 0