Kaldi - thchs30

文章目录

    • 关于数据
    • 运行训练
    • run.sh 解读
      • 1、设置数据地址/下载数据
      • 2、数据准备 thchs-30_data_prep.sh
        • word.txt 词序列
        • text
        • phone.txt 音素序列
        • wav.scp 语音 语音ID -- 文件地址 映射
        • utt2spk 语音 -- 说话人 映射
        • spk2utt 说话人 -- 语音的映射
      • 3、生成 mfcc 特征
      • 4、数据准备 prepare_lang.sh | format_lm.sh
      • 5、制作音素图 prepare_lang.sh | format_lm.sh
      • 6、单音素模型训练、解码、对齐
      • 7、训练三音子模型
      • 8、最大似然线性变换
      • 9、说话人自适应训练
      • 10、quick模型训练
      • 11、训练 dnn 模型
      • 12、训练 dae 模型


关于数据


你可以使用 egs/thchs30/s5/run.sh 脚本下载数据(后面将会讲到),也可以在这里下载数据包:
http://www.openslr.org/18/


这个数据集包含以下内容:

数据集 音频时长(h) 句子数 词数
train(训练) 25 10000 198252
dev(开发) 2:14 893 17743
test(测试) 6:15 2495 49085

还有训练好的语言模型 word.3gram.lm 和 phone.3gram.lm 以及相应的词典 lexicon.txt,位于 data_thchs30/lm_word/word.3gram.lm, data_thchs30/lm_phone/phone.3gram.lm

其中dev的作用是在某些步骤与train进行交叉验证的,如 local/nnet/run_dnn.sh 同时用到exp/tri4b_aliexp/tri4b_ali_cv
训练和测试的目标数据也分为两类:word(词)和phone(音素)。


运行训练

1、修改 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
# export cuda_cmd="run.pl --gpu 1"

2、修改 run.sh

路径为 data_thchs30 所在文件夹;建议填写绝对路径;

#corpus and trans directory
thchs=/Users/xx/xx/kaldi-trunk/egs/thchs30/s5/data1

3、执行训练

sh run.sh

大概有几个过程:

  • 数据准备
  • monophone单音素训练
  • tri1三因素训练
  • trib2进行lda_mllt特征变换
  • trib3进行sat自然语言适应
  • trib4做quick(这个我也不懂),
  • 后面就是dnn了

run.sh 解读

1、设置数据地址/下载数据

  • thchs 字段用来设置数据地址;
  • 这个脚本也可以下载数据, local/download_and_untar.sh $th 这个命令对应的三行 取消注释就好。
#!/usr/bin/env bash

. ./cmd.sh ## You'll want to change cmd.sh to something that will work on your system.
           ## This relates to the queue.
. ./path.sh

H=`pwd`  #exp home
n=8      #parallel jobs

#corpus and trans directory
thchs=/Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1

#you can obtain the database by uncommting the following lines
#[ -d $thchs ] || mkdir -p $thchs  || exit 1
#echo "downloading THCHS30 at $thchs ..."
#local/download_and_untar.sh $thchs  http://www.openslr.org/resources/18 data_thchs30  || exit 1
#local/download_and_untar.sh $thchs  http://www.openslr.org/resources/18 resource      || exit 1
#local/download_and_untar.sh $thchs  http://www.openslr.org/resources/18 test-noise    || exit 1

2、数据准备 thchs-30_data_prep.sh

  • local/thchs-30_data_prep.sh 主要工作是从 $thchs/data_thchs30(下载的数据)三部分分别生成
    • word.txt(词序列)
    • text(与word.txt相同)
    • phone.txt(音素序列)
    • wav.scp(语音)
    • utt2pk(句子 – 说话人 映射)
    • spk2utt(说话人 – 句子的映射)

#data preparation
#generate text, wav.scp, utt2pk, spk2utt
local/thchs-30_data_prep.sh $H $thchs/data_thchs30 || exit 1;

word.txt 词序列

/egs/thchs30/s5/data/dev $ head *
==> word.txt <==
A11_101 七十 年代 末 我 外出 求学 母亲 叮咛 我 吃饭 要 细嚼慢咽 学习 要 深 钻 细 研
A11_119 陈云 同志 同时 要求 干部 认真学习 业务 精通 业务 向 一切 业务 内 行人 学习
A11_124 另外 女单 中国队 还有 韩晶 娜 和 尧 燕 奥运 排名 第六 七位 也 可 与 高手 一 搏
A11_132 得到 李公朴 噩耗 闻一多 怒 愤 填 膺 拍案而起 怒斥 反动派 卑鄙无耻
A11_170 据 印度 官员 透露 双方 讨论 了 印度 控制 的 克什米尔 地区 目前 的 紧张 局势 问题
...
A11_203 开滦 矿务局 后 吕 家 坨 矿 张 文友 张 文富 两兄弟 同 超产 同 立功 同 当 劳动模范


text

与word.txt相同

==> text <==
A02_033 与 王伟 四平市 货车 司机 杜 大平 岳 玉杰 装卸工 刘 春山 一同 追赶 逃跑 的 案犯
A02_058 特 别是 跨 省区 电网 超 计划 用电 不仅 损害 自己 也 损害 别人 损害 电网 损害 国家
A02_085 胡耀邦 与 杨勇 确 系 嫡亲 姨 表兄弟 耀邦 的 母亲 刘 明伦 与 杨勇 的 母亲 刘 世珍 是 同胞 姐妹
A02_092 揭阳 成为 外商 投资 新 热点 建 市 一年 引进 外资 十 五亿 美元
... 
A02_206 上等 糖果 香烟 药品 等 用 玻璃纸 包装 除了 美观 外 还有 保护 物品 的 绝妙 作用

phone.txt 音素序列

==> phone.txt <==
A02_033 vv v3 uu uang2 uu ui3 s iy4 p ing2 sh ix4 h uo4 ch e1 s iy1 j i1 d u4 d a4 p ing2 vv ve4 vv v4 j ie2 zh uang1 x ie4 g ong1 l iu2 ch un1 sh an1 ii i4 t ong2 zh ui1 g an3 t ao2 p ao3 d e5 aa an4 f an4
A02_058 t e4 b ie2 sh ix4 k ua4 sh eng3 q v1 d ian4 uu uang3 ch ao1 j i4 h ua4 ii iong4 d ian4 b u4 j in3 s un3 h ai4 z iy4 j i3 ii ie3 s un3 h ai4 b ie2 r en2 s un3 h ai4 d ian4 uu uang3 s un3 h ai4 g uo2 j ia1
A02_085 h u2 ii iao4 b ang1 vv v3 ii iang2 ii iong3 q ve4 x i4 d i2 q in1 ii i2 b iao3 x iong1 d e5 ii iao4 b ang1 d e5 m u3 q in1 l iu2 m ing2 l un2 vv v3 ii iang2 ii iong3 d e5 m u3 q in1 l iu2 sh ix4 zh en1 sh ix4 t ong2 b ao1 j ie3 m ei4 
...
A02_206 sh ang4 d eng3 t ang2 g uo3 x iang1 ii ian1 ii iao4 p in3 d eng3 ii iong4 b o1 l i5 zh ix3 b ao1 zh uang1 ch u2 l e5 m ei3 g uan1 uu uai4 h ai2 ii iu3 b ao3 h u4 uu u4 p in3 d e5 j ve2 m iao4 z uo4 ii iong4

wav.scp 语音 语音ID – 文件地址 映射

==> wav.scp <==
A02_033 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_33.wav
A02_058 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_58.wav
A02_085 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_85.wav 
... 
A02_206 /Users/shushu/Documents/nlp_util/kaldi-trunk/egs/thchs30/s5/data1/data_thchs30/dev/A2_206.wav


utt2spk 语音 – 说话人 映射

如 句子ID 为 A02_033,说话人为 A02

==> utt2spk <==
A02_033 A02
A02_058 A02
A02_085 A02
A02_092 A02 
...
A02_206 A02

spk2utt 说话人 – 语音的映射

==> spk2utt <==
A02 A02_033 A02_058 A02_085 A02_092 A02_103 A02_108 A02_116 A02_119 A02_167 A02_206
A04 A04_004 A04_010 A04_026 A04_048 A04_052 A04_074 A04_125 A04_140 A04_157 A04_182 A04_197 A04_204 A04_209 A04_210 A04_235 A04_240 A04_243
A06 A06_000 A06_003 A06_011 A06_016 A06_020 A06_041 A06_077 A06_078 A06_089 A06_108 A06_109 A06_128 A06_138 A06_141 A06_145 A06_171 A06_205 A06_212 A06_231 A06_247 
...
A14 A14_010 A14_037 A14_063 A14_068 A14_076 A14_082 A14_112 A14_139 A14_148 A14_150 A14_159 A14_181 A14_191 A14_202 A14_203 A14_225 A14_241 A14_249

3、生成 mfcc 特征

#produce MFCC features
rm -rf data/mfcc && mkdir -p data/mfcc &&  cp -R data/{train,dev,test,test_phone} data/mfcc || exit 1;

for x in train dev test; do
   #make  mfcc
   steps/make_mfcc.sh --nj $n --cmd "$train_cmd" data/mfcc/$x exp/make_mfcc/$x mfcc/$x || exit 1;
   
   #compute cmvn
   steps/compute_cmvn_stats.sh data/mfcc/$x exp/mfcc_cmvn/$x mfcc/$x || exit 1;
done

#copy feats and cmvn to test.ph, avoid duplicated mfcc & cmvn
cp data/mfcc/test/feats.scp data/mfcc/test_phone && cp data/mfcc/test/cmvn.scp data/mfcc/test_phone || exit 1;


4、数据准备 prepare_lang.sh | format_lm.sh

  • prepare_lang.sh : 构建字典 L.fst文件,来准备语言模型。
    即读取 input 的资源文件,生成 data/lang 目录,是 Kaldi 的标准语言文件夹。
  • format_lm.sh: 格式化语言模型(把 arpa 的 language model 转换成 FST格式)
    主要目标就是根据语言模型生成 G.fst文件,方便与之前的 L.fst 结合,发挥fst的优势。
    脚本最后会检测 G.fst中是否存没有单词的空环,如果存在就会报错,这回这会导致后续 HLG 的 determinization 出现错误。其程序核心就是 arpa2fst。
    • 输入1:data/lang,语言文件夹;
    • 输入2:data/graph/word.3gram.lm.gz,ARPA格式的语言模型;
    • 输入3: $thchs/data_thchs30/lm_word/lexicon.txt,词典;
    • data/graph/lang:输出,G.fst语言模型

#  数据准备:准备发音词典L.fst和训练3-gram语言模型G.fst。
#prepare language stuff

# 建立一个庞大的词汇库,包括单词的训练和解码
#build a large lexicon that invovles words in both the training and decoding.
(
	# 制作词图
  echo "make word graph ..."
  
  # 在pwd下创建文件夹
  cd $H; mkdir -p data/{dict,lang,graph} && \ 
  # 将语音数据库目录的相应文件拷贝到dict目录
  cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict && \
  
  # 将两个目录的lexicon.txt文件输出到 data_thchs30/lm_word/lexicon.txt,同时过滤掉带的行,并且删除相同的重复信息
  cat $thchs/resource/dict/lexicon.txt $thchs/data_thchs30/lm_word/lexicon.txt | \
  grep -v '' | grep -v '' | sort -u > data/dict/lexicon.txt || exit 1;
  
  # 调用 utils 下的 prepare_lang.sh 构建字典 L.fst文件,来准备语言模型。
  utils/prepare_lang.sh --position_dependent_phones false data/dict "" data/local/lang data/lang || exit 1;
  
  # 将 word.3gram.lm 压缩为 word.3gram.lm.gz 并保留文件
  gzip -c $thchs/data_thchs30/lm_word/word.3gram.lm > data/graph/word.3gram.lm.gz || exit 1;
  
  # 格式化语言模型  
  utils/format_lm.sh data/lang data/graph/word.3gram.lm.gz $thchs/data_thchs30/lm_word/lexicon.txt data/graph/lang || exit 1;
)

5、制作音素图 prepare_lang.sh | format_lm.sh

这里使用的 prepare_lang.sh | format_lm.sh 和上面相似,输入输出略微不同。

# make_phone_graph
(
  echo "make phone graph ..."
  # 创建文件夹
  cd $H; mkdir -p data/{dict_phone,graph_phone,lang_phone} && \
  # 将语音数据库的目录的相应文件拷贝到dict目录
  cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict_phone  && \
  # 将 lexicon.txt 文件输出到 data/dict_phone/lexicon.txt,同时过滤掉带的行,并且删除相同的重复信息
  cat $thchs/data_thchs30/lm_phone/lexicon.txt | grep -v '' | sort -u > data/dict_phone/lexicon.txt  && \
  echo " sil " >> data/dict_phone/lexicon.txt  || exit 1;
  
  # 构建字典 L.fst文件,来准备语言模型。 
  utils/prepare_lang.sh --position_dependent_phones false data/dict_phone "" data/local/lang_phone data/lang_phone || exit 1;
  
  # 将 phone.3gram.lm 压缩为 phone.3gram.lm.gz 并保留文件
  gzip -c $thchs/data_thchs30/lm_phone/phone.3gram.lm > data/graph_phone/phone.3gram.lm.gz  || exit 1;
  
  # 调用utils下的format_lm.sh来格式化语言模型,就是把arpa的language model 转换成 FST格式。
  # 输入1: data/lang_phone,语言文件夹;
  # 输入2:data/graph_phone/word.3gram.lm.gz,ARPA格式的语言模型;
  # 输入3:$thchs/data_thchs30/lm_phone/lexicon.txt,词典;
  # 输出:data/graph_phone/lang,G.fst语言模型
  utils/format_lm.sh data/lang_phone data/graph_phone/phone.3gram.lm.gz $thchs/data_thchs30/lm_phone/lexicon.txt \
    data/graph_phone/lang  || exit 1;
)


6、单音素模型训练、解码、对齐

# monophone
steps/train_mono.sh --boost-silence 1.25 --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/mono || exit 1;

# test monophone model
local/thchs-30_decode.sh --mono true --nj $n "steps/decode.sh" exp/mono data/mfcc &

# monophone_ali
steps/align_si.sh --boost-silence 1.25 --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/mono exp/mono_ali || exit 1;


  • train_mono:训练单音子HMM模型
    过程:初始化模型 --> 生成训练图HCLG.fst --> 对标签进行初始化对齐 --> 统计估计模型所需的统计量 --> 估计参数得到新模型 --> 迭代训练 --> 最后的模型final.mdl。
    • 输入1: data/mfcc/train,用于训练的数据;
    • 输入2: data/lang,语言模型。
    • monophone 模型的训练需要用到 phones.txt这个文件;
    • 输出: exp/mono,单音素模型,一些日志和对齐文件,主要输出为 final.mdl 和 tree
  • thchs-30_decode.sh: 测试单音素模型,解码和测试部分。
    它采用刚刚训练得到的模型来对测试数据集进行解码并计算准确率等信息,实际使用mkgraph.sh建立完全的识别网络,并输出一个有限状态转换器,最后使用decode.sh以语言模型和测试数据为输入计算WER。
  • align_si.sh:这一步是为了三音素训练提供对齐基础。
    用指定src-dir中的模型对指定data-dir中的数据进行对齐,一般在训练新模型前进行,以上一版本模型作为输入,输出在
    • --boost-silence 1.25:在对齐过程中提高静音的比例;
    • data/mfcc/train:输入,标注文本
    • text;data/lang:输入,词典 L.fst;
    • exp/mono:输入,模型,tree文件;
    • 输出:对齐序列

7、训练三音子模型

#triphone
steps/train_deltas.sh --boost-silence 1.25 --cmd "$train_cmd" 2000 10000 data/mfcc/train data/lang exp/mono_ali exp/tri1 || exit 1;

# 解码测试部分,可以看到该代码和单音素的解码测试是一样的,只是少了–mono选项
#test tri1 model
local/thchs-30_decode.sh --nj $n "steps/decode.sh" exp/tri1 data/mfcc &

# 利用第一行训练得到的三音素模型来做强制对齐。代码也是和单音素时是一样的,只是输出模型的变化
#triphone_ali
steps/align_si.sh --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/tri1 exp/tri1_ali || exit 1;

  • train_deltas.sh, 训练与上下文相关的三音子模型
    三音素的训练和单音素模型的主要区别是状态绑定部分

    Usage: steps/train_deltas.sh

    • #num-leaves:叶子节点数目;
    • tot-gauss:总高斯数目;
    • data-dir:数据文件夹;
    • lang-dir:存放语言的文件夹;
    • alignment-dir:存放之前单音素对齐后结果的文件夹;
    • exp-dir是存放三音素模型结果的文件夹。

8、最大似然线性变换

  • train_lda_mllt.sh, 用来进行线性判别分析 和 最大似然线性转换
# 最大似然线性变换
# 用来做特征调整并训练新模型
#lda_mllt
steps/train_lda_mllt.sh --cmd "$train_cmd" --splice-opts "--left-context=3 --right-context=3" 2500 15000 data/mfcc/train data/lang exp/tri1_ali exp/tri2b || exit 1;

# 解码测试
#test tri2b model
local/thchs-30_decode.sh --nj $n "steps/decode.sh" exp/tri2b data/mfcc &

# 根据模型对数据进行对齐
#lda_mllt_ali
steps/align_si.sh  --nj $n --cmd "$train_cmd" --use-graphs true data/mfcc/train data/lang exp/tri2b exp/tri2b_ali || exit 1;

9、说话人自适应训练

  • train_sat.sh 用来训练发音人自适应,基于特征空间最大似然线性回归
# 说话人自适应训练
# 对特征进行FMLLR,而后训练GMM模型
#sat
steps/train_sat.sh --cmd "$train_cmd" 2500 15000 data/mfcc/train data/lang exp/tri2b_ali exp/tri3b || exit 1;

# 对自适应模型的解码及测试
#test tri3b model
local/thchs-30_decode.sh --nj $n "steps/decode_fmllr.sh" exp/tri3b data/mfcc &

# 根据FMLLR模型对数据进行对齐,可以看出核心任务是 对特征码本做FMLLR,以达到说话人自适应的目的
#sat_ali
steps/align_fmllr.sh --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/tri3b exp/tri3b_ali || exit 1;

10、quick模型训练

  • train_quick.sh, 在现有特征上训练模型。
# quick 模型训练
#quick
steps/train_quick.sh --cmd "$train_cmd" 4200 40000 data/mfcc/train data/lang exp/tri3b_ali exp/tri4b || exit 1;

# 对quick训练得到的模型进行解码测试
#test tri4b model
local/thchs-30_decode.sh --nj $n "steps/decode_fmllr.sh" exp/tri4b data/mfcc &

# 采用quick训练得到的模型对数据进行对齐
#quick_ali
steps/align_fmllr.sh --nj $n --cmd "$train_cmd" data/mfcc/train data/lang exp/tri4b exp/tri4b_ali || exit 1;

# 对开发数据集进行对齐
#quick_ali_cv
steps/align_fmllr.sh --nj $n --cmd "$train_cmd" data/mfcc/dev data/lang exp/tri4b exp/tri4b_ali_cv || exit 1;

11、训练 dnn 模型

  • run_dnn.sh 用来训练DNN,包括 xent 和 MPE
# dnn模型训练,采用DNN来训练一个声学模型
#train dnn model
local/nnet/run_dnn.sh --stage 0 --nj $n  exp/tri4b exp/tri4b_ali exp/tri4b_ali_cv || exit 1;

12、训练 dae 模型

# dae模型训练,通过对语音数据添加噪声来得到有噪音的数据,而后调用 nnet1/train_dnn.sh来对其进行训练,训练细节和dnn部分一样

#train dae model
#python2.6 or above is required for noisy data generation.
#To speed up the process, pyximport for python is recommeded.
local/dae/run_dae.sh $thchs || exit 1;


2023-01-25(周三、初四)

你可能感兴趣的:(语音,kaldi,thchs30)