当前位置: 首页 > 工具软件 > AI Shell > 使用案例 >

Kaldi入门教程 aishell脚本

匡晟
2023-12-01

Kaldi入门教程 aishell脚本

准备词典

用aishell为例子,首先运行aishell_prepare_dict.sh对lexicon.txt进行处理准备词典,会输出extra_questions.txt,nonsilence_phoes.txt,optional_silence.txt,silence_phones.txt。
这里用到了awk,什么是awk呢?awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
使用方法:

awk '{pattern+action}' {filenames}

pattern表示awk在数据中查找的内容,而action是在找到匹配内容

awk '{for(n=2;n<=NF;n++){phone[$n]=1;}} END{for (p in phones) print p}'

这里是将lexicon除第一行之外的字符串提取出来

准备数据,分为test、dev、train集

local/aishell_data_prep.sh $data/data_aishell/wav $data/data_aishell/transcript || exit 1;

使用aishell_data_prep.sh将数据分成test、dev、train集

词典、语言文件准备,生成对应的数据关系

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/dev里,文件解释如下:
spk2gender包含说话人的性别信息
spk2utt包含说话人编号和说话人编号的语音信息
text包含语音编号和语音文本之间的关系
utt2spk语音编号和说话人编号之间的关系
wav.scp包含了原始语音的路径信息
wav.scp中第一列为录音编号,第二列为音频文件路径

BAC009S0002W0122 /home/train/S0002/BAC009S0002W0122.wav

utt2spk中第一列为录音编号,第二列为讲话者id

BAC009S0002W0122 S0002

spk2utt中第一列为讲话着,后面跟着他所说的话 …

S0002 BAC009S0002W0122 BAC009S0002W0123 BAC009S0002W0124 BAC009S0002W0125 BAC009S0002W0126

txt中第一列为录音编号,第二列为讲话内容,后面我们在研究这些是怎么生成的。

BAC009S0002W0122 而 对 楼市 成交 抑制 作用 最 大 的 限 购

训练语言模型

使用text和lexicon.txt作为输入,语言模型参数3gram-mincount/lm_unpruned.gz,得到语言模型
语言模型的目的就是根据声学模型输出的结果,给出概率最大的文字序列!
https://blog.csdn.net/nsh119/article/details/80193925

使用语言模型生成有限状态机

使用format_lm.sh将语言模型转化为状态机,并进行一定的format

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

make_mfcc_pitch.sh将语音信号转化为mfcc域后提取特征,输入为train dev test中的语音文件,输出为raw_mfcc_pitch_XXX.X.ark和raw_mfcc_pitch_XXX.X.scp,以及
文件feats.scp:第一列为录音编号,第二列为ark文件路径

BAC009S0002W0122 /aishell/s5/mfcc/raw_mfcc_pitch_train.1.ark:17
BAC009S0002W0123 /aishell/s5/mfcc/raw_mfcc_pitch_train.1.ark:9751

文件wav.scp:第一列为录音编号,第二列为音频文件路径

BAC009S0002W0122 aishell1/wav/train/S0002/BAC009S0002W0122.wav
BAC009S0002W0123 aishell1/wav/train/S0002/BAC009S0002W0123.wav

脚本中可以选择是否使用VTLN(特征级声道长度标准化):
特征级声道长度标准化(归一化):计算-mfcc-feat和计算-plp-feat程序接受VTLN 扭曲因子选项
由于我们没有放spk2warp,utt2warp文件,所以这仅用于初始化线性版本的VTLN的线性变换。VTLN的作用是移动三角形频率箱的中心频率的位置。VTLN通过移动三角频率区的中心频率的位置来起作用。 移动频率区间的翘曲函数是频率空间中的分段线性函数。

在make_mfcc_pitch.sh中最重要的两个命令是cumpute-mfcc-feats 和copy-feats,其在src中编译好的,前者的作用是提取特征并产生log日志文件。后者的作用是生成特征的存储文件,raw_mfcc_pitch_XXX.X.ark和raw_mfcc_pitch_XXX.X.scp。
MFCC特征的计算是在对象MFCC中的compute方法完成的,计算过程如下:
1.遍历每一帧(通常25ms一帧,10ms滑动)
2.对每一帧
a.提取数据,添加可选扰动,预加重和去直流,加窗
b.计算该点的能量(使用对数能量,而非C0)
c.做FFT并计算功率谱
d.计算每个梅尔频点的能量,共计23个重叠的三角频点,中心频率根据梅尔频域均匀分布。
e.计算对数能量,做离散余弦变换,保留指定的系数个数
f.倒谱系数加权,确保系数处于合理的范围。

compute_cmvn_stats.sh计算倒谱均值和方差归一化,输入仍然为train dev test,输出为cmvn_XXX.ark和cmvn_XXX.scp,scp文件中是语音段和特征对应,ark中保存特征
倒谱均值和方差归一化通常是为了获得基于说话人或者基于说话语句的零均值,单位方差归一化特征倒谱。但是并不推荐使用这个方法,而是使用基于模型的均值和方差归一化,如Linear VTLN(LVTLN)。可以使用基于音素的小语言模型进行快速归一化。
均值方差可以以一段语音为单位计算,但更好的是在一个较大的数据及上进行计算,这样识别效果会更加robustness。Kaldi中计算均值和方差的代码在compute-cmvn-stats.cc, 归一化在apply-cmvn.cc。

单音素训练

steps/train_mono.sh --cmd "$train_cmd" --nj 10 \
    data/train data/lang exp/mono || exit 1;    

使用train_mono.sh脚本,输入为train的data和字典lang,
输出为exp/mono,里面以.mdl结尾的文件保存了模型的参数。使用下面的命令可以查看模型的内容。

$ gmm-copy --binary=false exp/mono/0.mdl - | less

初始化单音素模型。调用gmm-init-mono,生成0.mdl、tree。
编译训练时的图。调用compile-train-graph生成text中每句抄本对应的fst,存放在fsts.JOB.gz中。
第一次对齐数据。调用align-equal-stats-ali生成对齐状态序列,通过管道传递给gmm-acc-stats-ali,得到更新参数时用到的统计量。
第一次更新模型参数。调用gmm-est更新模型参数。
进入训练模型的主循环:在指定的对齐轮数,使用gmm-align-compiled对齐特征数据,得到新的对齐状态序列;每一轮都调用gmm-acc-stats-ali计算更新模型参数所用到的统计量,然后调用gmm-est更新模型参数,并且在每一轮中增加GMM的分量个数。

参考链接:
fengzhou_.
开拓
单音素

构建单音素解码图:

# 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。
words.tx:第一列是词,第二列是从1开始的编号,类似于一个字典

<eps> 0
21三体综合症 1
<SPOKEN_NOISE> 2
B 3
SIL 4
○ 5

解码:分别针对开发集和测试集解码

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中。
1.train_mono.sh 用来训练单音子隐马尔科夫模型,一共进行40次迭代,每两次迭代进行一次对齐操作
2.train_deltas.sh 用来训练与上下文相关的三音子模型
3.train_lda_mllt.sh 用来进行线性判别分析和最大似然线性转换
4.train_sat.sh 用来训练发音人自适应,基于特征空间最大似然线性回归
5.nnet3/run_dnn.sh 用nnet3来训练DNN,包括xent和MPE
6.用chain训练DNN

查看结果:

输入下面的命令来查看结果

# 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

 类似资料: