本文主要受参考自: http://blog.csdn.net/by21010/article/details/51506292 以及: https://www.zhihu.com/question/35833334
最近看essen源码,感觉对于ASR 的一下之前的比较基础的算法很生疏, 在知乎上看到这个链接,感觉讲的比较通俗易懂,拿来再理解一下。
decoder是根据字典, 声学模型和语音模型,将输入的语音特征失量序列转化为字符序列。
声学模型是对声学、语音学、环境的变量、说话人性别、 口音等的差异的知识表示, 而语言模型是对一组字序列构成的知识表示。
声学模型用lstm+ctc训练,得到语音特征到音素的映射; 语言模型用SRILM工具做LM 的训练得到 3-gram and 4-gram, 是词与词、词与句子的映射, 字典是字词对应的音素index集合,是字词 和 音素之间的映射
‘’’
haibing注: 所谓声学模型就是把语音的声学特征分类对应到(解码)音素或字词这样的单元 语言模型接着把字词解码成一个完整的句子
‘’‘
先说语言模型:
语言模型表示某一字序列发生的概率,一般采用链式法则,把一个句子的概率拆解成器中的每个词的概率之积。设W是由w1, w2,...,wn组成的,则P(W)可以拆成(由条件概率公式和乘法公式):
P(W) = P(w1)P(w2/w1)P(w3/w1,w2)...P(wn/w1,w2,..wn-1), 每一项都是在之前所有词的概率条件下,当前词的概率。
由马尔卡夫模型的思想,最常见的做法就是用N-元文法,即假定某一个字的输出只与前面N-1个字出现的概率有关系, 这种语言模型叫做 n-gram模型(一般n取3, 即t rigram), 这时候我们就可以这么表示:
P(W) = P(w1)P(w2|w1)P(w3|w1,w2)P(w4| w1,w2,w3)...P(wn/wn-1,wn-2,...,w1) #条件太长的时候,概率就不好估计了,三元文法只取前两个词
= P(w1)P(w2|w1)P(w3|w1,w2)P(w4| w2,w3)...P(wn/wn-1,wn-2)
对于其中的每一项条件概率都可以用贝叶斯公式求出, 在所有的语料中统计出相邻的字发生的概率,再统计出单个字出现的概率, 代入即可。
‘’‘
wang yun ( https://www.zhihu.com/people/maigo )注:
做一下解释, 这个地方的n-gram是根据字符串序列建立的,所以一个n-gram就相当于词组, 必然会有 一些词组没有出现过,但是也存在发生的概率,所以需要算法生成这些生僻词组的概率。
直观的将: n大了之后主要的问题是许多n-gram在训练数据中没有出现过。如果一个n-gram整体没有出现过,但去掉一个词后得到的(n-1)-gram出现过,那么估计出的概率就是0;如果连这个(n-1)-gram都没有出现过,那么概率就无法估计了。常用的解决的办法就是:smoothing(eg: Good-Turing smoothing)和 fall back to lower-order n-grams(采用更小的n-gram)。 见《数学之美》
’‘’
再说声学模型:
声学模型的任务是计算P(X/W), 即给定文字之后发出这段语音的概率(最后利用贝叶斯,求P(X/W)是使用)。 首先第一问题: 怎么才能知道每个单词发什么音呢? 这就需要另外一个模块,叫做词典,看eesen的源码在数据准备阶段就是先求出词对应音素的dict, 它的作用就是把单词串转化成音素串,然后再求的语言模型和 训练声学模型(用lstm+ctc 训练声学模型).
有了dict的帮助,声学模型就知道给定的文字串该依次发哪些音了。不过为了计算语音跟音素串的匹配程度,还需要知道每个音素的起止时间。 这是利用动归来进行的,可以高效的找到音素的分界点,使得没一段语音与音素的匹配程度(用概率表示)之积最大。实际使用的算法称为viterbi算法,它不仅仅考虑了每一段语音和音素的匹配程度,还考虑了各个音素之间转换的概率(转换概率通过HMM估计) 实际中使用的比音素更小的单位,原理一样(不是很确定,值得是一帧数据(25ms)吗,一帧不到不到一个音素的长度?)