ASR之Kaldi

Kaldi官方github地址:https://github.com/kaldi-asr/kaldi

Kaldi目录结构

./tools, ./src, ./egs 这三个目录是比较重要的。

./tools目录下面全部都是Kaldi依赖的包。其中主要有:

  1. OpenFST:Weighted Finite State Transducer library,是一个用来构造有限状态自动机的库。我们知道隐马尔科夫模型就可以看成是一个有限状态自动机的。这是最终要的一个包,Kaldi的文档里面说:If you ever want to understand Kaldi deeply you will need to understand OpenFst.诶,要学的好多。
  2. ATLAS:这是一个C++下的线性代数库。做机器学习自然是需要很多矩阵运算的。
  3. IRSTLM:这是一个统计语言模型的工具包。
  4. sph2pipe:这是宾夕法尼亚大学linguistic data consortium(LDC)开发的一款处理SPHERE_formatted数字音频文件的软件,它可以将LDC的sph格式的文件转换成其它格式。

./src目录存放的是Kaldi的源代码。

./egs存放的是Kaldi提供的一些例子。

Kaldi的编译安装:

按照README.md中说明进行操作即可

运行yesno实例

该实例是一个非常小的数据集,每一条记录都是一系列yes或者no的语音,标注是由文件名来标注的。先运行一下。

切换到./egs/yesno/s5目录下,运行sudo./run.sh命令。

经过一段时间的训练和测试,可以看到运行结果。

这里写图片描述

WER为0.00。看来这个例子识别的还是挺准的。

 

PS:WER(WordError Rate)是字错误率,是一个衡量语音识别系统的准确程度的度量。其计算公式是WER=(I+D+S)/N,其中I代表被插入的单词个数,D代表被删除的单词个数,S代表被替换的单词个数。也就是说把识别出来的结果中,多认的,少认的,认错的全都加起来,除以总单词数。这个数字当然是越低越好。

 

下面进入./yesno/s5/waves_yesno目录瞧一瞧。

 

全部都是.wav格式的音频文件。可以打开一个文件听一听,发现是一个老男人连续不停地说yes或者no,每个文件说8次。文件名中,0代表那个位置说的是no,1代表说的是yes。这个实验没有单独的标注文件,直接采用的是文件名来标注的。

 

那个waves_yesno.zip.gz数据可以在http://www.openslr.org/resources/1/waves_yesno.tar.gz上下载,解压到s5下面。也可以不下载,run.sh里就帮你做好了。你在实验前可以看下里面的说明文档。

 

运行thchs30(清华大学中文语料库)

 

https://blog.csdn.net/snowdroptulip/article/details/78943748

 

 

HCLG

 

L.fst: The Phonetic Dictionary FST

 

 

maps monophone sequences to words.

 

The file L.fst is the Finite State Transducer form of the lexicon with phone symbols on the input and word symbols on the output.

 

L_disambig.fst:The Phonetic Dictionary with Disambiguation Symbols FST

 

 

A lexicon with disambiguation symbols

 

 

G.fst:The Language Model FST

 

FSA grammar (can be built from an n-gram grammar).

 

C.fst:The Context FST

C maps triphone sequences to monophones.

Expands the phones into context-dependent phones.

 

H.fst:The HMM FST

H maps multiple HMM states (a.k.a. transition-ids in Kaldi-speak) to context-dependent triphones.

Expands out the HMMs. On the right are the context-dependent phones and on the left are the pdf-ids. 

 

HCLG.fst: final graph

 

 

总结一下:

 

 

构图过程 G -> L -> C -> H

 

          G: 作为 acceptor (输入 symbol 与输出相同),用于对grammar 或者 language model 进行编码

          L:  Lexicon, 其输出 symbol 是 words, 输入 symbol 是 phones

          C:  context-dependency 其输出 symbol 是 phones, 其输入 symbol 为表示context-dependency phones

 

              如: vector ctx_window = { 12, 15, 21 };

                      含义:id = 15 的 phone 为 中心 phone, left phone id = 12, right phone id = 21

 

          H: 包括HMM definitions,其输出 symbol 为context-dependency phones, 其输入 symbol 为transitions-ids(即 对 pdf-id 和 其它信息编码后的 id) 

 

         asl=="add-self-loops” 

          rds=="remove-disambiguation-symbols”, 

          and H' is H without the self-loops:

 

         HCLG = asl(min(rds(det(H' o min(det(C o min(det(L o G))))))))

 

 

ark文件与txt文件互相转换

      这个很简单,也只需要用到copy-feats命令

                     copy-feats ark:train.ark   ark,t:/train.txt           ark转化为txt

                     copy-feats ark,t:train.txt  ark:train.ark              txt转化为ark

 

总结:主要的文件转化是通过copy-feats这个命令,它的主要功能是将文件变成数据流,这样方便对数据进行处理。

     比如你想查看kaldi中提取的mfcc特征到底是什么样子,同样可以用copy-feats,如:

          copy-feats ark:train.ark   ark,t:-  | less

     通过一个管道用less来查看ark里面的内容。

https://blog.csdn.net/by21010/article/details/51776447

 

命令行级 I/O 机制

命令行 I/O 是指在 shell 上调用编译好的 Kaldi 工具的方法。比如,如果想查看音频文件的时长,就可以使用这样的命令 
wav-to-duration scp:wav.scp ark,t:- 
其中,wav-to-duration 是 Kaldi 中的查看时长的工具,后面两个是参数。下面具体介绍命令行级 Kaldi 的 I/O。

非表格型I/O

非表格型的 I/O 一般比较简单,一般是输入输出只包含一个或两个对象的文件或流(比如,声学模型文件,变换矩阵)。使用方式就是 shell 命令的使用方式。其中值得注意的有: 
- Kaldi 采用一种扩展的文件名进行输入输出。读取文件的文件名称为 rxfilename , 写入的文件名称为 wxfilename。 
- 在 rxfilename/wxfilename 处采用 “-” 来表示标准输入输出。 
- rxfilename/wxfilename 处可以使用管道命令,比如先用gunzip将压缩文件解压,再输入到 Kaldi 程序中,即可在文件输入路径处填入 “gunzip -c foo.gz|”。 
- rxfilename/wxfilename 后可以通过 “:” 来描述偏移量,如 “foo:1045” 表示从 foo 文件偏移 1045 个字节开始读取。 
- 使用 –binary=true/false 来控制是否使用二进制输出。默认是true。 
- 有一组 copy* 命令,可以用来查看文件。如,copy-matrix –binary=false foo.mat -。 
- Log 信息和输出会混在一起显示,但是 Log 信息是 stderr 上,所以不会传到管道中。可以通过添加 2>/dev/null 命令,将log信息重定向到 /dev/null。

下面列举一些例子: 
echo ‘[ 0 1 ]’ | copy-matrix –binary=false - - 
将矩阵 [ 0 1 ] 输入到 copy-matrix 中,再显示出来。亦可以将其表示为 
copy-matrix –binary=false ‘echo [ 0 1 ]|’ -

表格型I/O

对于一系列数据的集合,比如对应于每一句话的特征矩阵,或者每一条音频文件对应的路径,Kaldi 采用表格形式的数据表示。表格中,以没有空格的字符串为索引。Kaldi 中,称从表格文件中读取的一个字符串为 rspecifier, 写入表格文件的一个字符串为wspecifier。有两种表格文件格式:archive 和 script 。其读取方式和非表格型数据类似,也是使用 rxfilename/wxfilename的格式,其格式为[options]:path:[offset]。需要在 options 中注明是archive文件还是script文件。例如 
wav-to-duration scp:wav.scp ark,t:-

rspecifiers 和 wspecifier

rspecifiers 和 wspecifier 是 Kaldi 中定义的两种术语,是存在于表格文件中的文件名,格式类似于 rxfilename/wxfilename, 亦可以采用管道命令呢,对于ark文件,可以添加选项,如ark,s,cs:-等。

两种存储格式:script-file 和 archive-file

script-file 是一种文件指针,里面包含的是具体文件所在路径,其格式为 
key rspecifier|wspecifier 
key 是字段名字,rspecifier/wspecifier则是文件路径,rspecifier/wspecifier 可以有空格。例如 “utt1 gunzip -c /foo/bar/utt1.mat.gz”。 
archive-file 里面装的是实际的数据。其文件格式是 
key1 object1 key2 object2 key3 object3 … 
ark文件可以连接在一起,依然是一个有效的ark文件。但是如果需要的文件时有序的话,连接的时候应该要注意。 
ark文件和scp文件有可能同时写,这时可以这么写:ark,scp:foo.ark,foo.scp。

特征提取

对data下的train、dev和test数据分别调用下面两个脚本

steps/make_mfcc.sh

特征存在feats.scp中,存储的特征是每一帧13维,当用到mfcc特征的时候才计算deltas和deltas-deltas,转为39维。
脚本主要为下面几行

  $cmd JOB=1:$nj $logdir/make_mfcc_${name}.JOB.log \
    compute-mfcc-feats  $vtln_opts --verbose=2 --config=$mfcc_config \
     scp,p:$logdir/wav_${name}.JOB.scp ark:- \| \
      copy-feats --compress=$compress ark:- \
      ark,scp:$mfccdir/raw_mfcc_$name.JOB.ark,$mfccdir/raw_mfcc_$name.JOB.scp \
      || exit 1;

其中$cmd为run.pl

以data/train为例

  • 检查。检查一些文件是否存在等
  • 根据变量$nj的大小,将data/train/wav.scp平分为$nj份
  • 调用run.pl,提取特征。一个JOB处理一份wav.scp,共$nj个JOB。用到程序compute-mfcc-featscopy-feats,生成mfcc/raw_mfcc_train.JOB.ark和对应的mfcc/raw_mfcc_train.JOB.scp文件,JOB为1到$nj的数字。
  • 将$nj个mfcc/raw_mfcc_train.JOB.scp文件合成一个data/train/feats.scp文件
  • 检查。检查是否正确提取所有文件

steps/compute_cmvn_stats.sh

  • 对每个说话人计算cmvn(cepstral mean and variance normalization)。
  • 对每个说话人,对每一维(共13维)分别计算count/sum/sum-squared三组statistics,分别为1维、13维、13维。count代表该说话人所有音频文件的总帧数,sum代表所有帧里每一维的和,sum-square代表所有帧里每一维的平方的和。然后根据这三组statistics,计算均值和方差。
  • 可用copy-matrixs程序查看cmvn.scp或cmvn.ark文件,对每一个说话人,有一个28维的矩阵,前十三维是sum,然后是count,接着十三维是sum-squared,最后一个0。
  • 该脚本有三个选项:--fake--two-channel--fake-dims
    调用compute-cmvn-stats生成mfcc/cmvn_train.arkmfcc/cmvn_train.scp,然后将后者复制到data/train/cmvn.scp

https://blog.csdn.net/Xwei1226/article/details/80491538

https://blog.csdn.net/u010731824/article/details/69668765

ASR指标:

正确率:只要和原来的标签相同就算正确。

准确率:除了要正确,还需要加上因为插入其它词造成的错误。

Correct(cor) = ( N − D − S )× 100% / N =  H× 100% / N
Accurac(acc) = ( N− D− S− I  )× 100% / N =  (H - I)× 100% / N
N- total number of labels (总标签数)
D- deletion errors (删除错误)
S-  substitution errors (替换错误)
I-  insertion errors (插入错误)

ASR指标统计工具:HTK HResults

你可能感兴趣的:(ASR)