yesno初体验

  |   0 评论   |   124 浏览

背景

yesno是kaldi中语音识别(ASR)的一个例子。

语音识别原理

语音识别即由语音转换为文字,具体来说由声学输出A(1, T) 到 单词序列W(1,R)的最大化概率:

argmaxP(W(1,R) | A(1,T))

根据贝叶斯定律,可以将上面的概率转换为已知单词序列W(1,R)的分布,求声学输出A(1,T)的计算问题。

argmaxP(A(1,T) | W(1,R)P(W(1,R))

这里的 P(A(1,T) | W(1,R) 称为声学模型, P(W(1,R))称为语言模型。

yesno初体验

执行yesno例子

执行

cd kaldi/egs/yesno/s5
./run.sh

结果

…………
local/score.sh: scoring with word insertion penalty=0.0,0.5,1.0
%WER 0.00 [ 0 / 232, 0 in , 0 del, 0  ub ] exp/mono0a/decode_te t_ye no/wer_10_0.0

WER为字错误率,WER=0.00表示全部识别正确。

介绍

yesno 数据集中,包含60个音频文件。

每个音频文件,都包含8个音频片断。每个音频片断为 ken 或者 lo,即希伯来语的 yes / no。这里音频片断与音频文件名是对应的。即文件名 0_0_0_0_1_1_1_1.wav 的音频片断为 lo lo lo lo ken ken ken ken

yesno 例子中做的事情为:用数据集中的一半数据30个用于训练,另一个数据30个用于测试,来准确的将 ken / lo 的发声转换为文本。

数据准备

kaldi数据集都需要有音频文件和讲稿文件。

text

讲稿文件,每行一句话,格式为:

<utt_id> <transcript>

1_0_0_0_0_0_0_0 YES NO NO NO NO NO NO NO
1_0_0_0_0_0_0_1 YES NO NO NO NO NO NO YES

注:这里的utt_id中不含扩展名。

wav.scp

标识唯一Id对应的音频文件,语法格式为:

<file_id> <带路径的wav文件名 / 获取.wav文件的命令>

0_0_0_0_1_1_1_1 waves_yesno/0_0_0_0_1_1_1_1.wav
0_0_0_1_0_0_0_1 waves_yesno/0_0_0_1_0_0_0_1.wav

utt2spk

标识每句话的说话者,语法格式为:

<utt_id> <speaker_id>

本例中只有一句说话者,所以为:

1_0_0_0_0_0_0_0 global
1_0_0_0_0_0_0_1 global

spk2utt

反向索引,可以通过小工具 s5/utils/utt2spk_to_spk2utt.pl 来得到

最后数据目录如下:

data
├── test_yesno
│   ├── spk2utt
│   ├── text
│   ├── utt2spk
│   └── wav.scp
└── train_yesno
    ├── spk2utt
    ├── text
    ├── utt2spk
    └── wav.scp

词典准备

构建语言知识:词典和音素词典

词典

本例子,只有 YESNO 两个词,假设它们都为单音素词 YN
同时,考虑到还有单词之间的“沉默”,用额外的音素“SIL”表示。

因此,词典文件 input/phones.txt 为:

SIL
Y
N

完整的词典文件有5个,分别为:

文件名含义
lexicon.txt词素 - 音素对的完整列表
lexicon_words.txt单词 - 音素对列表
silence_phones.txt无声音素列表
nonsilence_phones.txt非无声音素列表
optional_silence.txt可选无声音素列表

在yesno例子中,文件如下:

% cat lexicon.txt
<SIL> SIL
YES Y
NO N
% cat lexicon_words.txt
YES Y
NO N
% cat silence_phones.txt
SIL
% cat nonsilence_phones.txt
Y
N
% cat optional_silence.txt
SIL

最后需要将词典文件,进行有限状态转换(FST),转换成kaldi接受的数据结构。

utils/prepare_lang.sh --position-dependent-phones false <RAW_DICT_PATH> <OOV> <TEMP_DIR> <OUTPUT_DIR>

本例中:

参数
<RAW_DICT_PATH>data/local/dict
<OOV>"<SIL>"
<TEMP_DIR>data/local/lang
<OUTPUT_DIR>data/lang

最终会得到一个 arpa格式的语言模型文件,本例中为 lm_tg.arpa,内容如下:

% cat lm_tg.arpa

\data\
ngram 1=4

\1-grams:
-1	NO
-1	YES
-99 <s>
-1 </s>

\end\

这个 arpa 文件需要转换成FST,本例中通过 local/prepare_lm.sh 生成 G.fst文件。

特征提取

MFCC是将音频文件的频谱信息转换为13维的特征向量。

提取 MFCC 梅尔频率倒谱系数

通过 make_mfcc.sh 工具,通过三个参数,分别指定处理器数量,训练集数据位置,和结果输出位置。

steps/make_mfcc.sh --nj <N> <INPUT_DIR> <OUTPUT_DIR>

yesno例子中,如下:

steps/make_mfcc.sh --nj 1 data/train_yesno exp/make_mfcc/train_yesno mfcc  

归一化倒谱特征

通过 make_mfcc.sh 工具,通过两个参数,分别指定训练集数据位置,和结果输出位置。

steps/compute_cmvn_stats.sh <INPUT_DIR> <OUTPUT_DIR>

INPUT_DIROUTPUT_DIR 和上例中的一样。

yesno例子中,如下:

steps/compute_cmvn_stats.sh data/train_yesno exp/make_mfcc/train_yesno mfcc

训练单音素模型

在特征提取完成后,这里开始训练声学模型。本例中训练不依赖于上下文的单音素模型。

steps/train_mono.sh 
  --nj <N>
  --cmd "$train_cmd" \
  --totgauss 400 \
  <训练数据路径> <语言定义路径> <输出路径>

yesno中实际如下:

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

到了这里,我们就有了声学模型和语言模型。

图解码

解码,即新的输入,是如何通过 AM & LM词图的。

执行:

# Graph compilation
utils/mkgraph.sh data/lang_test_tg exp/mono0a exp/mono0a/graph_tgpr

将得到一个FST图,路径为 exp/mono0a/graph_tgpr/HCLG.fst

找到最佳路径

steps/decode.sh 
    --nj 1 \
    --cmd "utils/run.pl" \
    exp/mono0a/graph_tgpr \
    data/test_yesno \
    exp/mono0a/decode_test_yesno

结果为 exp/mono0a/decode_test_yesno/lat.1.gz,包含了解码器的第1个纯种处理的发言词图。

直接使用解码网络HCLG来识别

kaldi识别解码一段语音的过程是:首先提取特征,然后过声学模型AM,然后过解码网络HCLG.fst,最后输出识别结果。

准备测试集

test_yesno
├── spk2utt
├── text
├── utt2spk
└── wav.scp

提取特征

./steps/make_mfcc.sh --nj 1 data/test_yesno exp/make_mfcc/test_yesno
utils/validate_data_dir.sh: Successfully validated data-directory data/test_yesno
./steps/make_mfcc.sh: [info]: no segments file exists: assuming wav.scp indexed by utterance.
./steps/make_mfcc.sh: Succeeded creating MFCC features for test_yesno

过声学AM

过解码网络HCLG.fst

./steps/decode.sh --nj 1 --cmd "utils/run.pl" exp/mono0a/graph_tgpr data/test_yesno_good exp/mono0a/decode_test_yesno

输出识别结果

参考

  • 《深度学习——语音识别技术实践,柳若边》