【语音识别】详解kaldi的数据和模型文件——librispeech

在基于GMM-HMM的传统语音识别里,比音素(phone)更小的单位是状态(state)。一般每个音素由三个状态组成,特殊的是静音(SIL)由五个状态组成。这里所说的状态就是指HMM里的隐藏的状态,而每帧数据就是指HMM里的观测值。每个状态可以用一个GMM模型表示(这个GMM模型的参数是通过训练得到的)。在识别时把每帧数据对应的特征值放进每个状态的GMM里算概率,概率最大的那个就是这帧对应的状态。再从状态得到音素(HMM负责),从音素得到词(字典模型负责),从词得到句子(语言模型负责),最终完成识别。

第一次编译kaldi很可能会缺各种东西,最好有管理员权限来安装。


git clone https://github.com/kaldi-asr/kaldi.git kaldi --origin upstream
cd kaldi

cd tools
extras/check_dependencies.sh //缺什么就安装什么,需要管理员权限
make

cd ../src
./configure --shared
make depend -j 8
make -j 8

kaldi本身内置了很多个语料库的asr示例,librispeech示例是一个英语的常用语料库,总共有960小时的数据。此外,中文常用语料库为aishell2,需要申请。以下按照训练流程来查看生成的文件。

打开kaldi/egs/librispeech/s5,其中cmd.sh为集群相关的配置,若为单机训练,则改为

export train_cmd=run.pl
export decode_cmd=run.pl
export mkgraph_cmd=run.pl

然后就是主要的训练脚本,run.sh,第一行的 data 修改为自己准备存放的语料库路径。
该脚本由 20 个 stage 组成,可以一个一个 stage 自己放到命令行跑,观察生成了什么。

if [ $stage -le 1 ]; then
  for part in dev-clean test-clean dev-other test-other train-clean-100; do
    local/download_and_untar.sh $data $data_url $part
  done
  local/download_lm.sh $lm_url data/local/lm
fi

步骤2,将数据重构成kaldi所需的形式,将对每个集生成一个文件夹.

if [ $stage -le 2 ]; then
  for part in dev-clean test-clean dev-other test-other train-clean-100; do
    local/data_prep.sh $data/LibriSpeech/$part data/$(echo $part | sed s/-/_/g)
  done
fi

每个文件夹里,比较重要的文件有 text、wav.scp、utt2spk、spk2utt、feats.scp、cmvn.scp。
其中,前三项需要手工编制,后三项可根据前三项自动生成。

[En]

Among them, the first three items need to be prepared manually, and the latter can be generated automatically according to the first three items.

$ls data/train_clean_100
cmvn.scp  conf  feats.scp  frame_shift  spk2gender  spk2utt  split20  text  utt2dur  utt2num_frames  utt2spk  wav.scp

$head -3 train_clean_100/text
103-1240-0000 CHAPTER ONE MISSUS RACHEL LYNDE IS SURPRISED MISSUS RACHEL LYNDE LIVED
103-1240-0001 THAT HAD ITS SOURCE AWAY BACK IN THE WOODS OF THE OLD CUTHBERT
103-1240-0002 FOR NOT EVEN A BROOK COULD RUN PAST MISSUS RACHEL LYNDE'S DOOR

$head -3 train_clean_100/wav.scp
103-1240-0000 flac -c -d -s /home/fwq/Project/kaldi/kaldi/data/LibriSpeech/LibriSpeech/train-clean-100/103/1240/103-1240-0000.flac |
103-1240-0001 flac -c -d -s /home/fwq/Project/kaldi/kaldi/data/LibriSpeech/LibriSpeech/train-clean-100/103/1240/103-1240-0001.flac |
103-1240-0002 flac -c -d -s /home/fwq/Project/kaldi/kaldi/data/LibriSpeech/LibriSpeech/train-clean-100/103/1240/103-1240-0002.flac |

$head -3 train_clean_100/utt2spk
103-1240-0000 103-1240
103-1240-0001 103-1240
103-1240-0002 103-1240

$head -3 train_clean_100/spk2utt
103-1240 103-1240-0000 103-1240-0001 103-1240-0002 103-1240-0003 ....

103-1241 103-1241-0000 103-1241-0001 103-1241-0002 103-1241-0003 ....

1034-121119 1034-121119-0000 1034-121119-0001 1034-121119-0002 1034-121119-0003 ....

$head -3 train_clean_100/feats.scp
103-1240-0000 /home/fwq/Project/kaldi/kaldi/egs/librispeech/s5/mfcc/raw_mfcc_train_clean_100.1.ark:14
103-1240-0001 /home/fwq/Project/kaldi/kaldi/egs/librispeech/s5/mfcc/raw_mfcc_train_clean_100.1.ark:18444
103-1240-0002 /home/fwq/Project/kaldi/kaldi/egs/librispeech/s5/mfcc/raw_mfcc_train_clean_100.1.ark:39292

$head -3 train_clean_100/cmvn.scp
103-1240 /home/fwq/Project/kaldi/kaldi/egs/librispeech/s5/mfcc/cmvn_train_clean_100.ark:9
103-1241 /home/fwq/Project/kaldi/kaldi/egs/librispeech/s5/mfcc/cmvn_train_clean_100.ark:257
1034-121119 /home/fwq/Project/kaldi/kaldi/egs/librispeech/s5/mfcc/cmvn_train_clean_100.ark:508
步骤3,准备词典,并生成语言模型保存于 data/lang_nosp。

if [ $stage -le 3 ]; then
  local/prepare_dict.sh --stage 3 --nj 30 --cmd "$train_cmd" \
   data/local/lm data/local/lm data/local/dict_nosp

  utils/prepare_lang.sh data/local/dict_nosp \
   "" data/local/lang_tmp_nosp data/lang_nosp

  local/format_lms.sh --src-dir data/lang_nosp data/local/lm
fi

着重看语言模型文件夹。

$ls lang_nosp
L.fst  L_disambig.fst  oov.int  oov.txt  phones  phones.txt  topo  words.txt

$ls lang_nosp/phones
align_lexicon.int  context_indep.txt  extra_questions.int  nonsilence.txt        roots.int  silence.csl    wdisambig_phones.int
align_lexicon.txt  disambig.csl       extra_questions.txt  optional_silence.csl  roots.txt  silence.int    wdisambig_words.int
context_indep.csl  disambig.int       nonsilence.csl       optional_silence.int  sets.int   silence.txt    word_boundary.int
context_indep.int  disambig.txt       nonsilence.int       optional_silence.txt  sets.txt   wdisambig.txt  word_boundary.txt

$head -3 lang_nosp/phones.txt
<eps> 0
SIL 1
SIL_B 2
$head -5 lang_nosp/words.txt
<eps> 0
!SIL 1
<SPOKEN_NOISE> 2
<UNK> 3
A 4

$cat lang_nosp/oov.txt
<UNK>
$cat lang_nosp/oov.int
3

$cat lang_nosp/topo
....

<TopologyEntry>
<ForPhones>
1 2 3 4 5 6 7 8 9 10
</ForPhones>
<State> 0 <PdfClass> 0 <Transition> 0 0.25 <Transition> 1 0.25 <Transition> 2 0.25 <Transition> 3 0.25 </State>
<State> 1 <PdfClass> 1 <Transition> 1 0.25 <Transition> 2 0.25 <Transition> 3 0.25 <Transition> 4 0.25 </State>
<State> 2 <PdfClass> 2 <Transition> 1 0.25 <Transition> 2 0.25 <Transition> 3 0.25 <Transition> 4 0.25 </State>
<State> 3 <PdfClass> 3 <Transition> 1 0.25 <Transition> 2 0.25 <Transition> 3 0.25 <Transition> 4 0.25 </State>
<State> 4 <PdfClass> 4 <Transition> 4 0.75 <Transition> 5 0.25 </State>
<State> 5 </State>
</TopologyEntry>
....

步骤4,扩展成三元和四元的语言模型,生成两个新的语言模型文件夹。

if [ $stage -le 4 ]; then

  utils/build_const_arpa_lm.sh data/local/lm/lm_tglarge.arpa.gz \
    data/lang_nosp data/lang_nosp_test_tglarge
  utils/build_const_arpa_lm.sh data/local/lm/lm_fglarge.arpa.gz \
    data/lang_nosp data/lang_nosp_test_fglarge
fi
$ls lang_nosp_test_tglarge/
G.carpa  L.fst  L_disambig.fst  oov.int  oov.txt  phones  phones.txt  topo  words.txt
$ls lang_nosp_test_fglarge/
G.carpa  L.fst  L_disambig.fst  oov.int  oov.txt  phones  phones.txt  topo  words.txt

然后看模型文件。
步骤8,训单因素模型并解码。

if [ $stage -le 8 ]; then

  steps/train_mono.sh --boost-silence 1.25 --nj 20 --cmd "$train_cmd" \
                      data/train_2kshort data/lang_nosp exp/mono

  (

    utils/mkgraph.sh data/lang_nosp_test_tgsmall \
                     exp/mono exp/mono/graph_nosp_tgsmall

    for test in test_clean test_other dev_clean dev_other; do
      steps/decode.sh --nj 20 --cmd "$decode_cmd" exp/mono/graph_nosp_tgsmall \
                      data/$test exp/mono/decode_nosp_tgsmall_$test
    done
  )&
fi

步骤9,用单音素模型对齐后,再训三音素模型。

if [ $stage -le 9 ]; then

  steps/align_si.sh --boost-silence 1.25 --nj 10 --cmd "$train_cmd" \
                    data/train_5k data/lang_nosp exp/mono exp/mono_ali_5k

  steps/train_deltas.sh --boost-silence 1.25 --cmd "$train_cmd" \
                        2000 10000 data/train_5k data/lang_nosp exp/mono_ali_5k exp/tri1
fi

步骤10,用三音素模型对齐后,再训LDA+MLLT模型。

if [ $stage -le 10 ]; then

  steps/align_si.sh --nj 10 --cmd "$train_cmd" \
                    data/train_10k data/lang_nosp exp/tri1 exp/tri1_ali_10k

  steps/train_lda_mllt.sh --cmd "$train_cmd" \
                          --splice-opts "--left-context=3 --right-context=3" 2500 15000 \
                          data/train_10k data/lang_nosp exp/tri1_ali_10k exp/tri2b
fi

步骤11,用LDA+MLLT模型对齐后,再训LDA+MLLT+SAT模型。

if [ $stage -le 11 ]; then

  steps/align_si.sh  --nj 10 --cmd "$train_cmd" --use-graphs true \
                     data/train_10k data/lang_nosp exp/tri2b exp/tri2b_ali_10k

  steps/train_sat.sh --cmd "$train_cmd" 2500 15000 \
                     data/train_10k data/lang_nosp exp/tri2b_ali_10k exp/tri3b
fi

步骤12,在100h干净数据上,用LDA+MLLT+SAT模型对齐后,再训LDA+MLLT+SAT模型。

if [ $stage -le 12 ]; then

  steps/align_fmllr.sh --nj 20 --cmd "$train_cmd" \
    data/train_clean_100 data/lang_nosp \
    exp/tri3b exp/tri3b_ali_clean_100

  steps/train_sat.sh  --cmd "$train_cmd" 4200 40000 \
                      data/train_clean_100 data/lang_nosp \
                      exp/tri3b_ali_clean_100 exp/tri4b
fi

Original: https://blog.csdn.net/tobefans/article/details/125434241
Author: weiquan fan
Title: 【语音识别】详解kaldi的数据和模型文件——librispeech

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/497912/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球