基于NN-HMM的语音唤醒总结

  学习语音唤醒识别已有3个月,从基础理论开始,到看论文移植代码,在牺牲了无数的头发的青春后逐渐对语音唤醒识别有了一定的了解,本着好记性不如烂笔头的原则,记录下自己的一些理解和想法,与大家一起学习进步,若有不正确之处,还望赐教!
  PS:涉及到保密问题,该博客没有任何代码,欢迎注明出处的转载

NN-HMM的语音唤醒的流程

  语音唤醒的流程的流程可用以下一张图来概括(图的出处见水印)

vgg实现语音识别 hmm语音识别流程_神经网络


  基本上可以概括为以下四个步骤:

    (1)音频的前处理(非必须,上图未体现)

    (2)特征提取

    (3)声学模型(本文中对应NN部分)

    (1)语言模型(本文中对应HMM部分)

  接下来的章节将一一对这些部分进行不完整也不保证完全准确的阐述。

语音的前处理

  语音的前处理大致包括以下内容:
    1)降噪
    2)AGC
    3)回声消除
    4)去混响
    5)VAD
    6)波束形成
    7)等等
这些前处理或多或少都能提升对后续语音唤醒的效果,具体内容在此不赘述。

特征提取

  特征提取是在将语音分帧后,进一步压缩语音内容的方法,在语音上通常用的几种特征及其提取方法如下图所示:

vgg实现语音识别 hmm语音识别流程_语音识别_02


其中FBank/MFCC/PLP是被使用最多的三种特征。

神经网络

  神经网络的输入为n帧的特征,n可取10/20/40/等,完全取决于你的帧宽和神经网络的大小,当然n如果太小,就会无法识别出一些如:iang这样较长的音素,而n如果太大,又会导致多个音素混叠在一起,无法识别出发音较短的音素,比如一些声母。

  神经网络的个数,取决你对音素表的分类,当仅仅是唤醒时,以唤醒词“懒懒的话”为例,其音素为l an3 l an3 d e h ua1,这样我们可以把l分为一类,d分为一类,h分为一类,an3分为一类,e分为一类,ua分为一类,剩下的我们不关心的音素分为一类,当然,考虑到一些安徽的同学l n不分(非地图炮,但本科研究生有很多安徽的同学确实如此),我们也可以把ln分为一类,或者是福建的同学hf不分(也不是地图炮,博主本人就是福建的,氮素,我分得清huafa),我们也可以把fh分为了一类,还有就是中文发音碰到两个第三声时第一个音要变成第二声,所以我们也要把an2an3分为一类。此外还有很多其他的因素要考虑,在此不做赘述。

  这样做不仅可以提高唤醒的效果,还可以减少后续的解码时的路径,减小解码图的尺寸,提高唤醒速度,对于特定的唤醒词中断来说基本很有好处地。当然,既然对特定的好,那就对通用的不友好,即扩展修改起来就很费劲了。

  至于网络的中间部分,DNN,CNN,RNN等等网络都可以用来试试,层数,神经元个数,激活函数等都能修改修改,只要训练出来的网络能将你想分类的音素区分出来就行,不过对于语音唤醒来说,一般都是在本地终端进行,所以神经网络不能太复杂,否则可能会有芯片算力不足,唤醒延时太长,或是内存不够等问题,实际上一般几层的全连接网络对多数唤醒词都够用了。

强制对齐

  提到网络训练,就不得不提强制对齐(因为是在训练网络时训练的,故也称之为嵌入式训练),之所以将其单独提出来,是因为它当时困扰了我这个小白很久,后来经过长时间的博客搜索和代码阅读我才慢慢的理解。

  首先,强制对齐的目的是将字级别的语音标签升级为音素级别的语音标签,在收集语音数据的时候,我们常常会记录下这段语音的内容,比如“我们去吃饭吧”,但问题是,我们的神经网络输出的标签是音素的类别,我哪个晓得某一帧的语音对应的是哪个音素?手动标记不仅繁琐而且还有可能很不准。这个时候就需要做强制对齐了,我愿称其为永远滴神,刚了解其运作原理时着实挺震撼的。这,大概就是学习的魅力吧!

  至于其内容,我就稍微偷个懒,毕竟下面这个链接写的通俗易懂,我就不再重复造轮子了,只要你稍微对EM有些些了解,应该都是能看得懂的。

vgg实现语音识别 hmm语音识别流程_无法识别_03

FST解码

写累了,后续以后补上