Kaldi脚本分析(1)——数据准备

来源:互联网 发布:青岛软件开发薪资 编辑:程序博客网 时间:2024/06/05 03:29

1 数据准备

数据准备阶段的输出包含两个部分:一部分与“数据”相关,保存在data/train、data/dev、data/test之类的目录下,“数据”部分与特定的录音数据有关,包括训练测试集划分、音频分段、文本标注、发音标注、说话人信息等;另一部分与“语言”相关,保存在data/local、data/dict、data/lang、data/graph目录下,“语言”部分与当前使用的语言本身相关,包括发音词典、音素集合、语言模型等。

如果想用现有的识别系统和语言模型对自己时的录音数据进行解码,那么只需要重写“数据”相关,并准备数据匹配的发音词典。

 

1.1 “数据”相关

主要涉及脚本:local/thchs-30_data_prep.sh

#data preparation

#generate text, wav.scp, utt2pk,spk2utt

local/thchs-30_data_prep.sh$H$thchs/data_thchs30 ||exit 1;

 

  • 在data文件夹下创建train,dev,test文件夹,分别用于保存训练、验证、测试的初始数据。利用thchs-30_data_prep.sh脚本在每个文件夹中生成以下6个文件:
  • wav.scp,每个语句的音频文件,索引标识符一般为utterance-id。如果音频存在segment文件,则索引标识符为recording-id,记录每一个分段。
  • utt2spk,记录每个utterance属于哪个说话人,由utterance-id索引。
  • spk2utt,记录每个说话人说了那些utterances,由speaker-id索引。
  • word.txt和text,每个语句的文本标注,由utterance-id索引。这里的文本标注从原始数据集中copy而来,不用保证都在词汇表中,未出现的文本标注将映射到data/lang/oov.txt中。
  • phone.txt,每个语句的发音标注,由utterance-id索引。发音标注中的音素信息从原始数据集中copy而来。

forxin train devtest; do

 echo"cleaning data/$x"

 cd$dir/data/$x

 rm -rf wav.scp utt2spk spk2utt word.txt phone.txt text

 echo"preparing scps and text in data/$x"

 fornnin`find $corpus_dir/$x/*.wav| sort -u | xargs -i basename {} .wav`;do

     spkid=`echo$nn| awk -F"_" '{print"" $1}'`

     spk_char=`echo$spkid| sed 's/\([A-Z]\).*/\1/'`

     spk_num=`echo$spkid| sed 's/[A-Z]\([0-9]\)/\1/'`

     spkid=$(printf'%s%.2d' "$spk_char" "$spk_num")

     utt_num=`echo$nn| awk -F"_" '{print $2}'`

     uttid=$(printf'%s%.2d_%.3d' "$spk_char" "$spk_num""$utt_num")

     echo$uttid$corpus_dir/$x/$nn.wav >> wav.scp

     echo$uttid$spkid >> utt2spk

     echo$uttid`sed -n 1p$corpus_dir/data/$nn.wav.trn` >> word.txt

     echo$uttid`sed -n 3p$corpus_dir/data/$nn.wav.trn` >> phone.txt

 done

 cp word.txt text

 sort wav.scp -o wav.scp

 sort utt2spk -o utt2spk

 sort text -o text

 sort phone.txt -o phone.txt

done

 

:上述所有数据文件都需要经过排序,如果没有排序,在运行脚本时会出错。这与Kaldi的I/O机制有关,常出现的I/O操作可能需要读取多个管道流、不同类型对象或进行“合并然后排序”,所以需要保证输入是排好序的。

 

 

 

1.2 “语言”相关

主要涉及脚本:utils/prepare_lang.sh和utils/format_lm.sh

在thchs-30例程中,“语言”准备部分给出了两种:word_graph和phone_graph,前者在解码时以词为单位求WER,后者在解码时以音素为单位。一般情况下,phone-task的WER更低,但是实际语音识别准确率是指word-task。将二者放在一起,可参考对比。

word_graph准备时,在data文件夹下创建dict、lang、graph文件夹,分别存储词典(词到发音的映射列表)、语言模型(词n-gram)、词fst图。

phone_graph准备时,在data文件夹下创建dict_phone、lang_phone、graph_phone文件夹,分别存储音素词典(音素到发音的映射列表)、音素语言模型(音素n-gram)、音素fst图。

 echo"make word graph ..."

 cd$H; mkdir -pdata/{dict,lang,graph} && \

  cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict && \

cat$thchs/resource/dict/lexicon.txt$thchs/data_thchs30/lm_word/lexicon.txt| \

grep-v '<s>' | grep -v'</s>'| sort -u > data/dict/lexicon.txt ||exit1;

  utils/prepare_lang.sh--position_dependent_phonesfalse data/dict"<SPOKEN_NOISE>" data/local/lang data/lang ||exit1;

 gzip -c $thchs/data_thchs30/lm_word/word.3gram.lm> data/graph/word.3gram.lm.gz ||exit 1;

  utils/format_lm.sh data/langdata/graph/word.3gram.lm.gz$thchs/data_thchs30/lm_word/lexicon.txtdata/graph/lang ||exit 1;

 

 echo"make phone graph ..."

 cd$H; mkdir -pdata/{dict_phone,graph_phone,lang_phone} && \

  cp $thchs/resource/dict/{extra_questions.txt,nonsilence_phones.txt,optional_silence.txt,silence_phones.txt} data/dict_phone && \

  cat $thchs/data_thchs30/lm_phone/lexicon.txt| grep -v'<eps>' | sort -u >data/dict_phone/lexicon.txt  && \

 echo"<SPOKEN_NOISE> sil " >> data/dict_phone/lexicon.txt  ||exit 1;

  utils/prepare_lang.sh--position_dependent_phonesfalse data/dict_phone"<SPOKEN_NOISE>" data/local/lang_phonedata/lang_phone ||exit 1;

  gzip -c $thchs/data_thchs30/lm_phone/phone.3gram.lm> data/graph_phone/phone.3gram.lm.gz ||exit 1;

  utils/format_lm.sh data/lang_phonedata/graph_phone/phone.3gram.lm.gz$thchs/data_thchs30/lm_phone/lexicon.txt\

    data/graph_phone/lang  ||exit 1;

 

1.2.1       词图(word_graph)

1)       在data/dict文件夹下生成词典和音素列表:

  • nonsilence_phones.txt,非静音音素列表。
  • silence_phones.txt,静音音素列表。
  • optional_silence.txt,可选静音列表。
  • extra_questions.txt,从源数据集的dict文件夹中拷贝而来。除自动生成的问题集之外的一些问题,如语调或语气重音等相关的问题,一行表示一个问题,也就是一组音素。

sil

a1 ai1 an1 ang1ao1 e1 ei1 en1 eng1 i1 ia1 ian1 iang1 iao1 ie1 in1 ing1 iong1 iu1 ix1 iy1 o1ong1 ou1 u1 ua1 uai1 uan1 uang1 ueng1 ui1 un1 uo1 v1 van1 ve1 vn1

a2 ai2 an2 ang2ao2 e2 ei2 en2 eng2 er2 i2 ia2 ian2 iang2 iao2 ie2 in2 ing2 iong2 iu2 ix2 iy2o2 ong2 ou2 u2 ua2 uai2 uan2 uang2 ui2 un2 uo2 v2 van2 ve2 vn2

a3 ai3 an3 ang3ao3 e3 ei3 en3 eng3 er3 i3 ia3 ian3 iang3 iao3 ie3 in3 ing3 iong3 iu3 ix3 iy3o3 ong3 ou3 u3 ua3 uai3 uan3 uang3 ueng3 ui3 un3 uo3 v3 van3 ve3 vn3

a4 ai4 an4 ang4ao4 e4 ei4 en4 eng4 er4 i4 ia4 ian4 iang4 iao4 ie4 in4 ing4 iong4 iu4 ix4 iy4iz4 o4 ong4 ou4 u4 ua4 uai4 uan4 uang4 ueng4 ui4 un4 uo4 v4 van4 ve4 vn4

a5 ai5 an5 ang5ao5 e5 ei5 en5 eng5 er5 i5 ia5 ian5 iang5 iao5 ie5 in5 ing5 iong5 iu5 ix5 iy5iz5 o5 ong5 ou5 u5 ua5 uai5 uan5 uang5 ueng5 ui5 un5 uo5 v5 van5 ve5 vn5

aa b c ch d ee fg h ii j k l m n oo p q r s sh t uu vv x z zh

 

 

  • 读取源数据集中的/resource/dict/lexicon.txt和/data_thchs30/lm_word/lexicon.txt,去除包含'<s>'或'</s>'的行,并重新排序,存入data/dict/lexicon.txt中。
  • 多音词在词典中会有多个条目,在lexiconp.txt中,多音词的每个发音的概率均为1.0,而不是所有发音的概率和为1,这样会得到更好的识别结果。

1.0   zh ao1

1.0   zh ao2

1.0   zh e5

1.0   zh uo2

着儿1.0  zh ao1 ee er5

着凉1.0  zh ao2 l iang2

着力1.0  zh uo2 l i4

着哩1.0  zh ao2 l i5

着地1.0  zh ao2 d i4

着实1.0  zh uo2 sh ix2

着忙1.0  zh ao2 m ang2

着急1.0  zh ao1 j i2

着急1.0  zh ao2 j i2

着想1.0  zh ao2 x iang3

着想1.0  zh uo2 x iang3

着手1.0  zh uo2 sh ou3

着数1.0  zh ao1 sh u4

着火1.0  zh ao2 h uo3

着火点1.0 zh ao2 h uo2 d ian3

 

 

2)       利用utils/prepare_lang.sh脚本生成语言模型相关文件,在data/lang文件夹下:

  • word.txt,存储OpenFST格式的词符号表(wordsymbol table),每一行是文本标注字符串到整数的映射,整数从0开始按顺序标号。

<eps>0

#1

<SPOKEN_NOISE>2

SIL3

4

一一5

一丁点6

.. . . . .

 

  • phones.txt,存储OpenFST格式的音素符号表(phonesymbol table),每一行是音素或消歧符号(#1,#2等)到整数的映射,整数从0开始按顺序标号。在处理消歧符号时,增加了#0用来表示语言模型中的epsilon转移。

<eps>0

sil1

a12

a23

a34

a45

a56

.. . . . .

#0219

#1220

#2221

#3222

#4223

#5224

.. . . . .

 

  • 在data/dict/phones文件夹下,存储不同类型的音素或消歧符号列表。sets.txt中为音素集合,以便聚类时自动建立文本相关的问题集。后缀为.csl的几个文件中,nonsilence.csl存储非静音音素对应整型量(2~218),以冒号分隔;disambig.scl存储消歧符号对应整型量(219~275);silence.scl,optional_silence.scl,context_indep.scl存储静音对应的整型量(1)。同名的.int和.txt文件分别逐行存储相应的整型量和符号。

  • L.fst和G.fst是FST格式的编译词典和语言模型。

  • 通过“fstprint命令”可以查看文件中的内容,如果找不到该命令,先在s5文件夹下运行“../path”将OpenFST的安装路径添加到bash的PATH环境变量。以L.fst为例,输入是音素符号,输出是词符号。

 

3)       将源数据中的词语言模型打包并存入data/graph/word.3gram.lm.gz中,Thchs30数据集中ngram语言模型中包含的所有条目如下。以1-grams为例,词文本前面的概率表示该一元本身的log-probability,文本后面的概率表示该一元作为回退元的log-weight。

 

 

4)       将2)中生成的语言模型拷贝到data/graph/lang文件夹下,并利用脚本utils/format_lm.sh编译得到FST格式的语言模型G.fst。进而结合词典和语言模型生成LG.fst或CLG.fst。

 

1.2.2       音素图(phone_graph)

1)      在data/dict_phone文件夹下生成词典和音素列表:

  • extra_questions.txt,从源数据集的dict文件夹中拷贝而来。
  • nonsilence_phones.txt,同上。
  • optional_silence.txt,同上。
  • silence_phones.txt,同上。
  • 读取源数据集中的/data_thchs30/lm_phone/lexicon.txt,去除'<eps>',在最后一行加入"<SPOKEN_NOISE>sil ",排序,存入data/dict_phone/lexicon.txt。

2)      利用utils/prepare_lang.sh脚本生成音素的语言模型。

3)      将源数据中的音素语言模型打包并存入data/graph_phone/phone.3gram.lm.gz中。

4)      将源数据中的lexicon.txt拷贝到data/graph_phone/lang文件夹下。

 

 

附:utils/prepare_lang.sh脚本运行说明:

  • --position_dependent_phones选项指示音素是否和位置有关,选项设置为true,则需要用_B,_E, _S & _I等标识符对音素在词中的不同位置进行标记。在该例程中,选项设置为false,即音素标记与位置无关。
  • data/dict为输入路径,"<SPOKEN_NOISE>"表示将OOV用噪声替换。
  • data/local/lang为暂存路径,data/lang为输出路径。
  • 从lexicon.txt生成lexiconp.txt或反之。
  • 对phone.txt进行完整性检查。包括,phone.txt中音素是否与位置有关,在词典中出现的音素是否都包含在phone.txt中。
  • 在输出路径data/lang中新建phones文件夹,存储不同类型的音素或消歧符号。

阅读全文
0 0