kaildi讲解
转载声明:本文为转载文章
作者:ferb2015
原文地址:https://blog.csdn.net/eqiang8848/article/details/81543599
kaldi是一个开源的语音识别工具箱,是基于c++、perl、shell编写的,可以在windows和unix 平台上编译。
中文参考资料:《kaldi的全部资料_v0.7(未完成版本).pdf》。网盘链接 提取码:yuq0
教程网页:http://www.kaldi-asr.org/doc/ 里面可以查阅脚本的用途、使用,以及建立asr过程的资料。还有网上的dan的ppt。
kaldi下载:https://github.com/kaldi-asr/kaldi。
语音识别基础知识快速入门
我的入门方式是看《语音信号处理》韩纪庆(编)的语音识别章节。
kaldi安装
简要说明:(运行环境centos7、ubuntu16.4、macos 10.13都能安装成功)
- 安装前你需要对你的 linux 进行配置,需要安装的软件apt-get、subversion、automake、autoconf、libtool、g++、zlib、libatal、wget,如何安装见《kaldi的全部资料_v0.7(未完成版本).pdf》。
git clone https://github.com/kaldi-asr/kaldi.git 选择某个路径,下载kaldi。
在命令行cd到kaldi路径下,cd到tool目录下,在命令行分别输入:
make -j nproc
extras/install_srilm.sh
install_irstlm.sh是安装语言模型。
3. make 完后,在src目录下:在命令行分别输入:
./configure
make depend
make
make阶段是编译阶段,将下载的包编译为可执行文件,耗时较长,耐心等待。
ubuntu安装遇到问题最少,centos和macos上安装都会出现一些问题,得手动解决。
遇到过的error和解决方法:
make过程中,openfst-1.6.7.tar.gz没有解压完全,因此自动又解压一遍,生成openfst-1.6.7.tar.gz.1,因此要把原openfst-1.6.7.tar.gz删掉(rm openfst-1.6.7.tar.gz),openfst-1.6.7.tar.gz.1重命名为openfst-1.6.7.tar.gz(mv openfst-1.6.7.tar.gz.1 openfst-1.6.7.tar.gz)。再次make(不需要手动解压)。
sudo make仍出现permission denied造成error。把文件夹的用户改成使用者。比如我的用户名叫work,chown -R work kaldi。
如果多次make都遇到error,建议先make clean把编译过的全删掉,再重新装。
kaldi各文件解释
- /egs:不同语料例子的执行脚本文件
- /tools:存放asr过程中用到的库
- /src:存放实际执行的c++算法
以aishell为例的ASR过程
命令行到kaldi路径下,输入
cd egs/aishell/s5
首先改cmd的配置:
vim cmd.sh
改为:
export train_cmd=run.pl #"queue.pl --mem 2G"
export decode_cmd="run.pl --mem 4G" #"queue.pl --mem 4G"
export mkgraph_cmd="run.pl --mem 8G" #"queue.pl --mem 8G"
export cuda_cmd="run.pl --gpu 1"
原文件的queue是基于集群的,这里我们用本机/服务器跑,因此改为run.sh。
:wq保存后,输入:
vim run.sh
看见data=/export/a05/xna/data改成想存放语料的路径,返回后,新建对应的文件夹。之后输入
./run.sh
就开始进行asr过程了。强烈建议逐行运行,运行当前行时,把其他暂时注释调,这样清楚看见每个阶段的过程。
过程简单说来就是:
语料数据准备 下载语料库到本地/服务器的文件夹
数据关系,词典、语言文件(text, wav.scp, utt2pk, spk2utt)准备,训练集、测试集、验证集准备
单音素(或者其他模型)训练和解码
构建解码图
解码查看结果
run.sh详细解释:
这里是简单的介绍,具体细节可以参考kaldi入门详解 aishell2步骤解释(二)
vim run.sh
查看run.sh脚本,这里逐行解释:
下载并解压aishell 178小时语料库,(音频和lexicon词典):
local/download_and_untar.sh $data $data_url data_aishell || exit 1;
local/download_and_untar.sh $data $data_url resource_aishell || exit 1;
准备词典:
local/aishell_prepare_dict.sh $data/resource_aishell || exit 1;
准备数据。分成test、dev、train集。:
local/aishell_data_prep.sh $data/data_aishell/wav $data/data_aishell/transcript || exit 1;
词典、语言文件准备,生成对应的数据关系:
Phone Sets, questions, L compilation
utils/prepare_lang.sh --position-dependent-phones false data/local/dict \
"<SPOKEN_NOISE>" data/local/lang data/lang || exit 1;
其中,数据关系保存在/data里,文件解释如下:
spk2gender 包含说话人的性别信息
spk2utt 包含说话人编号和说话人的语音编号的信息
text 包含语音和语音编号之间的关系
utt2spk 语音编号和说话人编号之间的关系
wav.scp 包含了原始语音的路径信息等
提取MFCC特征:
# Now make MFCC plus pitch features.
# mfccdir should be some place with a largish disk where you
# want to store MFCC features.
mfccdir=mfcc
for x in train dev test; do
steps/make_mfcc_pitch.sh --cmd "$train_cmd" --nj 10 data/$x exp/make_mfcc/$x $mfccdir || exit 1;
steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x $mfccdir || exit 1;
utils/fix_data_dir.sh data/$x || exit 1;
done
分为两步,先通过steps/make_mfcc.sh提取MFCC特征,再通过steps/compute_cmvn_stats.sh计算倒谱均值和方差归一化。
生成了两个文件夹:mfcc 和 exp/make_mfcc,其中 mfcc 里主要保存了提取的特征,而 exp/make_mfcc 里保存了日志,即 .log 文件。
在 steps/make_mfcc.sh 里用到的最主要的命令就是 compute-mfcc-feats 和 copy-feats,其在 src 里编译好的。
mfcc 目录里主要是 .ark 和 .scp 文件,其中 .scp 文件里的内容是语音段和特征对应,而真正的特征保存在 .ark 文件里。用下面的命令可以看清楚
copy-feats ark:mfcc/raw_mfcc_train.1.ark ark,t:-
单音素训练:
steps/train_mono.sh --cmd "$train_cmd" --nj 10 \
data/train data/lang exp/mono || exit 1;
之后会在 exp 文件夹下产生一个 mono 的目录,里面以 .mdl 结尾的就保存了模型的参数。使用下面的命令可以查看模型的内容。
$ gmm-copy --binary=false exp/mono/0.mdl - | less
构建单音素解码图:
# Monophone decoding
utils/mkgraph.sh data/lang_test exp/mono exp/mono/graph || exit 1;
mkgraph.sh主要生成了HCLG.fst和words.txt这两个重要的文件,后续识别主要利用了三个文件,分别是final.mdl、HCLG.fst、words.txt。
解码:分别针对开发集和测试集解码
steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \
exp/mono/graph data/dev exp/mono/decode_dev
steps/decode.sh --cmd "$decode_cmd" --config conf/decode.config --nj 10 \
exp/mono/graph data/test exp/mono/decode_test
解码的日志会保存在 exp/mono/decode_dev/log 和 exp/mono/decode_test/log 里。
Veterbi 对齐
# Get alignments from monophone system.
steps/align_si.sh --cmd "$train_cmd" --nj 10 \
data/train data/lang exp/mono exp/mono_ali || exit 1;
之后就是和训练单音素一样,进行其他模型的训练解码,生成声学模型和语言模型,保存在/exp中。
查看结果:
输入下面的命令来查看结果
# getting results (see RESULTS file)
for x in exp/*/decode_test; do [ -d $x ] && grep WER $x/cer_* | utils/best_wer.sh; done 2>/dev/null
总结:aishell的/s5/run.sh文件运行了gmm+hmm hybrid模型以及dnn+hmm hybrid模型。
首先用标准的13维MFCC加上一阶和二阶导数训练单音素GMM系统,采用倒谱均值归一化(CMN)来降低通道效应。然后基于具有由LDA和MLLT变换的特征的单音系统构造三音GMM系统,最后的GMM系统用于为随后的DNN训练生成状态对齐。
基于GMM系统提供的对齐来训练DNN系统,特征是40维FBank,并且相邻的帧由11帧窗口(每侧5个窗口)连接。连接的特征被LDA转换,其中维度降低到200。然后应用全局均值和方差归一化以获得DNN输入。DNN架构由4个隐藏层组成,每个层由1200个单元组成,输出层由3386个单元组成。 基线DNN模型用交叉熵的标准训练。 使用随机梯度下降(SGD)算法来执行优化。 将迷你批量大小设定为256,初始学习率设定为0.008。
被噪声干扰的语音可以使用基于深度自动编码器(DAE)的噪声消除方法。DAE是自动编码器(AE)的一种特殊实现,通过在模型训练中对输入特征引入随机破坏。已经表明,该模型学习低维度特征的能力非常强大,并且可以用于恢复被噪声破坏的信号。在实践中,DAE被用作前端管道的特定组件。输入是11维Fbank特征(在均值归一化之后),输出是对应于中心帧的噪声消除特征。然后对输出进行LDA变换,提取全局标准化的常规Fbank特征,然后送到DNN声学模型(用纯净语音进行训练)。
train_mono.sh 用来训练单音子隐马尔科夫模型,一共进行40次迭代,每两次迭代进行一次对齐操作
train_deltas.sh 用来训练与上下文相关的三音子模型
train_lda_mllt.sh 用来进行线性判别分析和最大似然线性转换
train_sat.sh 用来训练发音人自适应,基于特征空间最大似然线性回归
nnet3/run_dnn.sh 用nnet3来训练DNN,包括xent和MPE
用chain训练DNN
结果
aishell训练模型的词错误率wer和字错误率cer如下:
%WER 44.23 [ 28499 / 64428, 1821 ins, 4610 del, 22068 sub ] exp/mono/decode_test/wer_13_0.0
%WER 29.67 [ 19113 / 64428, 1567 ins, 2934 del, 14612 sub ] exp/tri1/decode_test/wer_14_0.5
%WER 29.24 [ 18841 / 64428, 1557 ins, 2813 del, 14471 sub ] exp/tri2/decode_test/wer_15_0.5
%WER 27.38 [ 17640 / 64428, 1764 ins, 2267 del, 13609 sub ] exp/tri3a/decode_test/wer_16_0.0
%WER 23.44 [ 15102 / 64428, 1468 ins, 2110 del, 11524 sub ] exp/tri4a/decode_test/wer_15_0.5
%WER 21.76 [ 14017 / 64428, 1383 ins, 1954 del, 10680 sub ] exp/tri5a/decode_test/wer_16_0.5
%WER 17.43 [ 11233 / 64428, 1077 ins, 1675 del, 8481 sub ] exp/nnet3/tdnn_sp/decode_test/wer_16_0.5
%WER 15.96 [ 10281 / 64428, 919 ins, 1672 del, 7690 sub ] exp/chain/tdnn_1a_sp/decode_test/wer_12_0.5
%CER 34.13 [ 35757 / 104765, 783 ins, 3765 del, 31209 sub ] exp/mono/decode_test/cer_11_0.0
%CER 19.56 [ 20496 / 104765, 910 ins, 1436 del, 18150 sub ] exp/tri1/decode_test/cer_13_0.5
%CER 19.16 [ 20073 / 104765, 989 ins, 1211 del, 17873 sub ] exp/tri2/decode_test/cer_13_0.5
%CER 17.24 [ 18060 / 104765, 780 ins, 1024 del, 16256 sub ] exp/tri3a/decode_test/cer_13_0.5
%CER 13.58 [ 14227 / 104765, 640 ins, 716 del, 12871 sub ] exp/tri4a/decode_test/cer_14_0.5
%CER 12.22 [ 12803 / 104765, 668 ins, 565 del, 11570 sub ] exp/tri5a/decode_test/cer_14_0.5
%CER 8.44 [ 8838 / 104765, 331 ins, 510 del, 7997 sub ] exp/nnet3/tdnn_sp/decode_test/cer_14_0.5
%CER 7.37 [ 7722 / 104765, 303 ins, 581 del, 6838 sub ] exp/chain/tdnn_1a_sp/decode_test/cer_11_1.0