前面训练了TIMIT数据集和TIMIT在线识别,TIMIT是英语语音识别,现在训练中文数据集thchs30,并做在线识别。
在Kaldi中有一些中文语音识别的数据,包括:
1.aishell: AI SHELL公司开源178小时中文语音语料及基本训练脚本,见kaldi-master/egs/aishell
2.gale_mandarin: 中文新闻广播数据集(LDC2013S08, LDC2013S08)
3.hkust: 中文电话数据集(LDC2005S15, LDC2005T32)
4.thchs30: 清华大学30小时的数据集,在http://www.openslr.org/18/
第一步:数据介绍
thchs数据集包含三个文件,如下。
data_thchs30.tgz [6.4G] ( speech data and transcripts )
test-noise.tgz [1.9G] ( standard 0db noisy test data )
resource.tgz [24M] ( supplementary resources, incl. lexicon for training data, noise samples )
这个数据集包含以下内容:
数据集 | 音频时长(h) | 句子数 | 词数 |
train(训练) | 25 | 10000 | 198252 |
dev(开发) | 2:14 | 893 | 17743 |
test(测试) | 6:15 | 2495 | 49085 |
还有训练好的语言模型word.3gram.lm和phone.3gram.lm以及相应的词典lexicon.txt。其中dev的作用是在某些步骤与train进行交叉验证的,如local/nnet/run_dnn.sh同时用到exp/tri4b_ali和exp/tri4b_ali_cv。训练和测试的目标数据也分为两类:word(词)和phone(音素)。
该数据集可在 http://pan.baidu.com/s/1hqKwE00 下载到。
第二步:数据准备
1、进入/egs/thchs30,找到thchs30的介绍。2、到/thchs30下,解压三个压缩包到文件夹thchs30-openslr,thchs30-openslr与/s5目录同级。
第三步:修改代码
1、进入/s5,编辑cmd.sh,改为:export train_cmd=run.pl
export decode_cmd="run.pl --mem 4G"
export mkgraph_cmd="run.pl --mem 8G"
export cuda_cmd="run.pl --gpu 1"
2、修改并行数为为: n=2 #parallel jobs
3、修改你的数据集的位置:thchs=/D/kaldi-trunnk/egs/thchs30/thchs30-openslr
第四步:跑代码
打开run.sh。建议一条一条的跑,先把后面的注释了。大概分为数据准备、monophone单音素训练,tri1三音素训练,tri2进行lda_mllt特征变换,tri3进行sat自然语音适应,tri4做quick,后面就是dnn了。本地不建议跑dnn。
这里可以用注释的方法一条一条的跑,如下:
:<<! ! 这两句相当于c语言的/* */
到exp目录下,有跑出来的结果。我们先简单看一个tri1,打开后,有个decode_test_word,里面有个scoring_kaldi,best_wer就是它的错误率,36.15%.回到tri1下,看到final.mdl了吗,这个就是有用的东西,学出来的模型。另外还得到graph_word下面,找到words.txt,和HCLG.fst,一个是字典,一个是有限状态机。有这3个文件,就可以来使用你的识别功能了。
第五步:在线识别
1、我们用跑出来的模型在线识别。到/tools安装portaudio。先进入tools/portaudio,用./configure查看依赖,通常情况alsa显示no,通过sudo apt-get install libasound-dev可以解决。然后进入/tools,执行:./install_portaudio.sh。回到/src目录,编译扩展程序:make ext 。 之后,会看到onlinebin文件夹。里面有两个程序,online-wav-gmm-decode-faster 用来回放wav文件来识别的,online-gmm-decode-faster用来从麦克风输入声音来识别的。portaudio的问题可参考上一篇的参考链接。这里可以测试一下Ubuntu的录音机是否正常,用以下代码:
arecord -f cd -r 16000 -d 5 test.wav
代码解释:16位,16khz,录音5秒,命名为test.wav。
2、接下来跑tri1。去egs下,打开voxforge,里面有个online_demo,直接拷贝到thchs30下,和s5同级。在online_demo里面建2个文件夹online-data work,在online-data下建两个文件夹audio和models,audio下放你要回放的wav(16位,16khz),models建个文件夹tri1,把s5下的exp下的tri1下的final.mdl和35.mdl拷贝过去。把s5下的exp下的tri1下的graph_word里面的words.txt,和HCLG.fst,拷贝到models的tri1下。
3、打开online_demo的run.sh,注释掉如下代码(这段是voxforge例子中下载现网的测试语料和识别模型的。我们测试语料自己准备,模型就是tri1了):
#if [ ! -s ${data_file}.tar.bz2 ]; then
# echo "Downloading test models and data ..."
# wget -T 10 -t 3 $data_url;
#
# if [ ! -s ${data_file}.tar.bz2 ]; then
# echo "Download of $data_file has failed!"
# exit 1
# fi
#fi
4、然后,改变路径为tri1。如下:
#ac_model_type=tri2b_mmi
ac_model_type=tri1
5、最后,改变如下:
#online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85\
# --max-active=4000 --beam=12.0 --acoustic-scale=0.0769 \
# scp:$decode_dir/input.scp $ac_model/model
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85\
--max-active=4000 --beam=12.0 --acoustic-scale=0.0769 \
scp:$decode_dir/input.scp $ac_model/final.mdl
6、./run.sh开始识别。./run.sh --test-mode live 命令就是从麦克风识别(如果提示portaudio错误,可参考https://blog.csdn.net/u012236368/article/details/71628777)。
7、接下来跑tri2(tri3和tri4同理)。把s5下的exp下的tri2b下的12.mat考到models的tri2下,把final.mat考过来(好像是转移矩阵),再拷贝其他相应的文件(同tri1的思路),所以/tri2目录下包括如下文件:12.mat、35.mdl、final.mat、final.mdl、HCLG.fst、words.txt。接着修改run.sh。
7.1、把final.mat引入命令中,添加如下命令:
if [ -s $ac_model/matrix ]; then
trans_matrix=$ac_model/final.mat
fi
7.2、再修改如下(添加12.mat):
ac_model=${data_file}/models/$ac_model_type
trans_matrix="$ac_model/12.mat"
audio=${data_file}/audio
7.3、再修改如下(添加2个参数--left-context=3 --right-context=3):
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85 \
--max-active=4000 --beam=12.0 --acoustic-scale=0.0769 --left-context=3 --right-context=3\
scp:$decode_dir/input.scp $ac_model/final.mdl $ac_model/HCLG.fst \
$ac_model/words.txt '1:2:3:4:5' ark,t:$decode_dir/trans.txt \
ark,t:$decode_dir/ali.txt $trans_matrix;;
8、./run.sh开始识别
9、因为是单机没有跑dnn。如果要运行dnn:首先要将nnet1转成nnet2。可以参考链接1和链接2。
附录一——代码解释
1) local/thchs-30_data_prep.sh主要工作是从$thchs/data_thchs30(下载的数据)三部分分别生成word.txt(词序列),phone.txt(音素序列),text(与word.txt相同),wav.scp(语音),utt2pk(句子与说话人的映射),spk2utt(说话人与句子的映射)
2) #produce MFCC features是提取MFCC特征,分为两步,先通过steps/make_mfcc.sh提取MFCC特征,再通过steps/compute_cmvn_stats.sh计算倒谱均值和方差归一化。
3) #prepare language stuff是构建一个包含训练和解码用到的词的词典。而语言模型已经由王东老师处理好了,如果不打算改语言模型,这段代码也不需要修改。
附录二——算法流程
1) 首先用标准的13维MFCC加上一阶和二阶导数训练单音素GMM系统,采用倒谱均值归一化(CMN)来降低通道效应。然后基于具有由LDA和MLLT变换的特征的单音系统构造三音GMM系统,最后的GMM系统用于为随后的DNN训练生成状态对齐。2) 基于GMM系统提供的对齐来训练DNN系统,特征是40维FBank,并且相邻的帧由11帧窗口(每侧5个窗口)连接。连接的特征被LDA转换,其中维度降低到200。然后应用全局均值和方差归一化以获得DNN输入。DNN架构由4个隐藏层组成,每个层由1200个单元组成,输出层由3386个单元组成。 基线DNN模型用交叉熵的标准训练。 使用随机梯度下降(SGD)算法来执行优化。 将迷你批量大小设定为256,初始学习率设定为0.008。
3) 被噪声干扰的语音可以使用基于深度自动编码器(DAE)的噪声消除方法。DAE是自动编码器(AE)的一种特殊实现,通过在模型训练中对输入特征引入随机破坏。已经表明,该模型学习低维度特征的能力非常强大,并且可以用于恢复被噪声破坏的信号。在实践中,DAE被用作前端管道的特定组件。输入是11维Fbank特征(在均值归一化之后),输出是对应于中心帧的噪声消除特征。然后对输出进行LDA变换,提取全局标准化的常规Fbank特征,然后送到DNN声学模型(用纯净语音进行训练)
附录三——专有缩写中文解释
cmvn:倒谱均值和方差归一化
fft:快速傅里叶变换
GMM:高斯混合模型
MFCC:梅尔倒谱系数
pcm:脉冲编码调制
pdf:概率分布函数
PLP:感知线性预测系数
SGMM:子空间高斯混合模型
UBM:通用背景模型
VTLN:特征级声道长度归一化
附录四——参考
1) 训练及在线识别
https://blog.csdn.net/snowdroptulip/article/details/78950038
https://blog.csdn.net/sut_wj/article/details/71055761
https://blog.csdn.net/wx8310232/article/details/78233827
2)训练/解码脚本解读
https://blog.csdn.net/BBZZ2/article/details/72884979
https://blog.csdn.net/DuishengChen/article/details/52575926
https://blog.csdn.net/snowdroptulip/article/details/78943748