基于Kaldi(DNN)的小词汇量汉语语音识别平台搭建
基于Kaldi(DNN)的小词汇量汉语语音识别平台搭建
Kaldi 简介
1. Kaldi 平台介绍
kaldi是使用C++编写的一个开源的语音识别工具箱,支持GMM、DNN以及SGMM等多种模型的训练,这款工具既可以在Windows下编译也可以在Linux系统下编译,这里对Kaldi的编译是在Linux系统下(ubuntu 16.04)进行的。
2. Kaldi 安装
- Kaldi源码地址: https://github.com/kaldi-asr/kaldi。
- 先将源码下载到本地:
git clone https://github.com/kaldi-asr/kaldi.git
- 到
tool
目录下,在命令行输入:make
。
Note that “make” takes a long time; you can speed it up by running make in parallel, for instance “make -j 4” 4是机器的cpu核心数,说明比较好。 - make 完后,在
src
目录下执行:1
2
3./configure
make depend
make3. Kaldi 目录文件
安装完成后进入Kaldi文件夹,文件夹的内容见下表。其中比较重要的文件夹是"src"
和"tools"
文件夹,基于本文的工程目录在"egs"
文件夹下的"XiaDan"
文件夹中。文件夹名称 内容 src Kaldi源代码和编译脚本 tools Kaldi所依赖的外部库文件,如openfst、ATLAS等 egs Kaldi工程样例,如timit、thchs30、wsj等 misc 一些文档以及以前版本的文本信息 windows Windows环境下安装需要的文件内容 4. XiaDan 工程目录
文件夹名称 内容 wav 训练和测试音频数据文件目录 data 声学数据和字典存放目录 steps、utils、local 用于数据准备以及训练的可执行脚本文件 conf 配置信息文件夹 cmd.sh 环境变量设置脚本 path.sh 设置调用脚本和外部库路径 run.sh 语音识别脚本文件 DNN-HMM 语音识别系统搭建
基于Kaldi平台搭建DNN-HMM语音识别系统,这里针对汉语普通话建立语音识别系统,并在后期对识别率进行了分析。搭建一个完整的DNN-HMM系统首先需要准备训练数据,包括音频数据、声学数据和语言数据,这些数据需要按照一定的格式准备,完成之后使用训练脚本训练出一个基于三音素的GMM-HMM模型,然后进行强制对齐,之后使用DNN训练脚本进行DNN模型的训练。1. 数据准备
- 音频数据
在搭建识别系统前需要录制音频数据,这里使用了18个说话人,每个说话人共录制音频数据40条,其中用于训练的数据有31条,测试数据9条,文件格式为WAV,采样率为16kHZ。把录制好的数据放在可以识别特定说话人的文件夹(wav文件夹,其中wav文件夹包括train和test文件夹,分别保存训练数据和测试数据)中。音频文件命名格式为zh1101M0001,前两个字母代表汉语,1101为说话人ID,M代表性别为男性,0001为文件编号ID。
(说话人文件目录)
(部分语音数据)
- 声学数据
在进行识别训练之前,需要准备相应的声学数据,创建一些文件使Kaldi与音频文件进行关联,需要准备的声学数据文件如图所示。
(声学数据文件)
以下是对一些主要文件进行的说明:
wav.scp记录了语音文件的路径,zh1110M0001是音频数据的名称,后面是路径,中间用空格分开,如图所示。
(wav.scp文件内容)
text文件包含每一个句子所对应的文本信息,用空格将句子字词分开,部分内容如图所示。
(text文件内容)
utt2spk文件告诉ASR系统哪一个句子属于哪个特定的说话人,如图所示。
(utt2spk文件内容)
spk2utt文件告诉ASR系统哪些句子属于哪个说话人,部分内容如图所示。
(spk2utt文件内容)
- 语言数据
这部分实际是在制作字典,字典使用的是汉语的声韵母发音,使用声韵母作为基本的音素,同时加入了声调的变化。在kaldi/egs/XiaDan/data/local
目录下,创建一个新的文件夹 "dict"
。 在dict文件夹中创建如下文件:
(dict文件夹内容)
各个文件的内容如下:
silence_phones.txt
文件列出了静音音素,在这里只有一个sil。
optional_silence.txt
文件列出了可选择的静音音素,也只有一个sil。
lexicon.txt
文件包含你的字典里的每一个单词的音素,如图所示。
(发音字典文件)
nonsilence_phones.tx文件列出了你工程中的所有的非静音音素,部分音素如图所示。
(非静音音素)
2. 模型训练
准备工作完成后,就可以生成语言模型了,语言模型训练这里使用n-gram算法,可以借助sirlm
工具可以实现,生成语言模型。这里创建了shell脚本方便运行,运行脚本文件Create_ngram_LM.sh
便可得到语言模型文件。
准备好上面这些文件后就可以进行训练了,在这里训练分为三步,并保存在DNN_train.sh
脚本文件中。下表列出了用到的训练脚本及其功能。
| 脚本名称 | 脚本功能 |
| :———: | :—-: |
| make_mfcc.sh | 特征参数提取脚本 |
| train_mono.sh | 单音素HMM训练脚本,一共进行40次迭代,每两次迭代进行一次对齐操作 |
| mkgraph.sh | 建立解码网络 |
| decode.sh | 用来解码并生成WER词错率结果 |
| align_si.sh | 对指定的数据进行对齐作为新模型的输入 |
| train_deltas.sh | 用来训练与上下文相关的三音素模型 |
| train_tanh.sh | 使用tanh激活函数进行深度神经网络训练 |
具体的训练过程分为三步,即单音素训练、三音素训练和DNN训练,以下是详细的步骤。
- 首先,需要训练单音素的HMM
1
2
3
4
5
6
7从语音话语中提取特征参数:
mfcc steps/make_mfcc.sh -- nj 18 data/train exp/make_mfcc/train mfcc
然后进行单音素的训练:
steps/train_mono.sh -- nj 18 data/train data/lang_bigram exp/mono
接下来进行解码操作:
utils/mkgraph.sh -- mono data/lang_bigram exp/mono exp/mono/graph
steps/decode.sh --nj 18 exp/mono/graph data/test exp/mono/decode - 训练三音素的HMM
三音素是三个音素的序列,三音素在自然语言处理的模型中比较有用。
1 | 音素对齐: |
- 训练DNN-HMM
这里将隐马尔可夫模型的状态建模为深度神经网络,而不是通过高斯混合模型对其进行建模。因此,状态转移概率与上述三元模型保持一致,只是现在状态观测概率将由深度神经网络建模。在这里使用tanh激活函数,初始学习率0.015,最终学习率0.002,使用3个隐藏层(尽管隐藏层的数量越多,性能越好,但由于数据量少,计算资源少,在这里使用了3个隐藏层),隐藏层的节点数256。1
2
3
4首先对齐以前的三音素模型:
steps/align_si.sh -- nj 18 data/train data/lang_bigram exp/tri exp/tri_ali
重新使用状态转换模型并且训练DNN状态模型:
steps/nnet2/train_tanh.sh --initial-learning-rate 0.015 --final-learning-rate 0.002 --num-hidden-layers 3 --minibatch-size 128 --hidden-layer-dim 256 --num-jobs-nnet 10 --num-epochs 15 data/train data/lang_bigram exp/tri_ali exp/DNN3. 结果分析
模型训练后的识别结果如表所示,其中GMM-HMM模型的词错率为单音素模型的词错率,DNN-HMM是在GMM-HMM训练的基础上将状态观测概率将由深度神经网络建模。从表中可以看出,DNN较GMM对识别率有所提高,识别率受影响的因素比较多,主要因素有语言环境、训练数据、说话人口音等。训练模型 词错率 GMM-HMM 13.31% DNN-HMM 12.04% 以下是将数据量加大一倍,对同样的数据进行重复训练后得到的词错率。从表中可以看出,通过加大训练的数据量,对每一条数据进行多次训练,识别率有所提高。 训练模型 词错率 :———: :—-: DNN-HMM 9.26% 4. 在线测试
之前已经完成了语音识别系统的搭建,这里增加了在线识别功能方便查看识别结果。工程目录下新建online文件夹,online文件夹里包括服务器应用脚本、语音识别脚本、语音数据以及识别结果等。
其中server.c是服务入口文件,voice_recognized.sh和run.sh是用于语音识别的脚本文件,识别结果保存在result.txt文件中。
online-data文件夹下包括audio和models两个文件夹,其中audio里保存了语音文件;models里保存了语音识别的模型文件。
在models文件夹下,其中final.mdl是比较重要的一个文件,这个文件中保存的是学习出来的模型。另外还有words.txt和HCLG.fst,一个是字典文件,另外一个是有限状态机。通过这3个文件,便可以使用识别功能了。
将待识别的语音文件放到audio文件夹下,运行脚本文件run.sh,系统会自动查找目标文件夹online-data/audio下的语音文件并进行识别。
其中online-wav-gmm-decode-faster命令用来对wav文件进行识别的,此外还有online-gmm-decode-faster命令,这是用来从麦克风输入声音来识别的,这里我们没有用到。
至此已经完成了整个语音识别系统的搭建,从识别结果来看,识别率较低,识别系统不够完善,需要进行进一步的优化。
(本文只用作交流学习使用,如有不足,请见谅。最后附上Github地址:基于Kaldi(DNN)的小词汇量汉语语音识别平台搭建)
基于Kaldi(DNN)的小词汇量汉语语音识别平台搭建
https://veenveenveen.github.io/2021/03/26/ASR/ASR_Kaldi_DNN_Chinese/