Kaldi-yesno详解

在Kaldi的egs文件下有很多基于公共语音数据库的训练步骤及测试结果,其中也有中文的,本文就相对很简单的yesno样例结合脚本以及脚本运行结果进行详细的解析,以更好地理解语音识别的整体流程。

总括

我们先来看一下run.sh脚本

cd ./egs/yesno/s5/

vi run.sh

========================================================================

#!/bin/bash

train_cmd="utils/run.pl"
decode_cmd="utils/run.pl"

if [ ! -d waves_yesno ]; then
  wget
http://www.openslr.org/resources/1/waves_yesno.tar.gz || exit 1;
  # was:
  # wget
http://sourceforge.net/projects/kaldi/files/waves_yesno.tar.gz || exit 1;
  tar -xvzf waves_yesno.tar.gz || exit 1;
fi

train_yesno=train_yesno
test_base_name=test_yesno

rm -rf data exp mfcc

# Data preparation

local/prepare_data.sh waves_yesno
local/prepare_dict.sh
utils/prepare_lang.sh --position-dependent-phones false data/local/dict "<SIL>" data/local/lang data/lang
local/prepare_lm.sh

# Feature extraction
for x in train_yesno test_yesno; do
 steps/make_mfcc.sh --nj 1 data/$x exp/make_mfcc/$x mfcc
 steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x mfcc
 utils/fix_data_dir.sh data/$x
done

# Mono training
steps/train_mono.sh --nj 1 --cmd "$train_cmd" \
  --totgauss 400 \
  data/train_yesno data/lang exp/mono0a
 
# Graph compilation 
utils/mkgraph.sh data/lang_test_tg exp/mono0a exp/mono0a/graph_tgpr

# Decoding
steps/decode.sh --nj 1 --cmd "$decode_cmd" \
    exp/mono0a/graph_tgpr data/test_yesno exp/mono0a/decode_test_yesno

for x in exp/*/decode*; do [ -d $x ] && grep WER $x/wer_* | utils/best_wer.sh; done

音频文件下载

if [ ! -d waves_yesno ]; then
  wget
http://www.openslr.org/resources/1/waves_yesno.tar.gz || exit 1;
  # was:
  # wget
http://sourceforge.net/projects/kaldi/files/waves_yesno.tar.gz || exit 1;
  tar -xvzf waves_yesno.tar.gz || exit 1;
fi

文件如下

每个wav文件中的发音都是Yes, No。其中,文件名中的1代表Yes,0代表No,从文件名可以知道wav的内容,这种格式方便后面的数据准备,当然文件存在大量发音的时候不可能采用如此的文件命名方式。

数据准备

wav文件预处理

local/prepare_data.sh waves_yesno

结果保存在s5/data/train_yesno和s5/data/test_yesno中,主要有下面几个文件

text  :音频文件id(文件名)与单词的对应

wav.scp :音频文件id与音频文件的对应

utt2spk :音频文件id与说话人的对应

spk2utt:说话人id与音频文件id的对应

其大致步骤为:将60个音频文件提取出文件id,其中30个作为训练,剩余30个作为测试。根据文件名中的1和0获取音频文件的内容。将其写入相应的文件,在实际大规模音频内容的情况下,需要自己制作上面的文件来做数据准备。

字典准备

local/prepare_dict.sh

结果保存在s5/data/local/dict/目录下面

lexicon.txt:完整的词位(包含静音SIL)-音素对

lexicon_words.txt:单词-音素对

silence_phones.txt: 非语言学音素

nonsilence_phones.txt:语言学音素

optional_silence.txt :备选非语言音素

 其大致步骤为:将input的文件夹下的已经写好的文件复制到该目录下,并加入SIL。

lang目录

utils/prepare_lang.sh --position-dependent-phones false data/local/dict "<SIL>" data/local/lang data/lang

结果保存在s5/data/lang/目录下

phones.txt:音素与整形的对应(openfst格式的symbol tables),以后的操作单词将以整形数字代替

words.txt:单词与整形的对应(openfst格式的symbol tables),以后的操作音素将以整形数字代替

L_disambig.fst:加消歧符号的字典fst(可以被kaldi识别的字典)

L.fst:字典fst(可以被kaldi识别的字典)

topo:音素状态转移图(HMM)Y,N每个音素为三种状态;SIL为五种状态

oov:词汇表之外的单词会映射到该文件中

phones:该目录下有许多关于音素集的信息。同一类信息可能有三种不同的格式,分别以.csl、.int和.txt结尾。感兴趣的话可以逐个打开查看!~~~

语言模型

 local/prepare_lm.sh 

该脚本其实很简单,将已经生成好的语言模型(s5/input/task.arpabo)转化为Kaldi格式的G.fst,其结果在s5/data/lang_test_tg目录下,有关语言模型创建可参考语音识别-SRILM安装与使用

特征向量提取

for x in train_yesno test_yesno; do
 steps/make_mfcc.sh --nj 1 data/$x exp/make_mfcc/$x mfcc
 steps/compute_cmvn_stats.sh data/$x exp/make_mfcc/$x mfcc
 utils/fix_data_dir.sh data/$x
done

结果在s5/mfcc/目录下

 其中ark文件为MFCC的特征向量;scp文件是音频文件或说话人与相应ark文件的对应关系;前缀cmvn为说话人,raw为音频文件。有关MFCC可以参考语音识别-MFCC特征提取

单音素训练

steps/train_mono.sh --nj 1 --cmd "$train_cmd" \
  --totgauss 400 \
  data/train_yesno data/lang exp/mono0a

该步的输出在s5/exp/mono0a/目录下,该步骤将生成声学模型。

构图

utils/mkgraph.sh data/lang_test_tg exp/mono0a exp/mono0a/graph_tgpr

该步骤生成最终的HCLG.fst.

解码

steps/decode.sh --nj 1 --cmd "$decode_cmd" \
    exp/mono0a/graph_tgpr data/test_yesno exp/mono0a/decode_test_yesno

结果在s5/exp/mono0a/decode_test_yesno/目录下

查看结果

for x in exp/*/decode*; do [ -d $x ] && grep WER $x/wer_* | utils/best_wer.sh; done

 egs下面各个文件夹的脚本不一样,但步骤都差不多。天气太热了,坐不住,其有些细节方面未涉及,也算是详解吧,哈哈!~~~

 

 

 

 

 

没有更多推荐了,返回首页