kaldi特征提取详解

举报
可爱又积极 发表于 2021/11/26 13:37:09 2021/11/26
【摘要】 Kaldi的特征提取和读取波形文件的代码会提取标准的MFCC和PLP特征,它会设置合理的默认值并且提供很多人都可能要微调的选项(比如mel滤波器组的bin的个数,最大和最小的频率范围等等)。代码值能读取pcm格式的.wav文件。这些文件的后缀通常是.wav或者.pcm(有些.pcm后缀其实是sphere文件,需要用工具转成wav)。如果用户的录音不是wav文件,那么需要自行用命令行工具转换。...

Kaldi的特征提取和读取波形文件的代码会提取标准的MFCC和PLP特征,它会设置合理的默认值并且提供很多人都可能要微调的选项(比如mel滤波器组的bin的个数,最大和最小的频率范围等等)。代码值能读取pcm格式的.wav文件。这些文件的后缀通常是.wav或者.pcm(有些.pcm后缀其实是sphere文件,需要用工具转成wav)。如果用户的录音不是wav文件,那么需要自行用命令行工具转换。因为LDC的数据很多是sphere格式,所以我们提供了安装sph2pipe工具的脚本。

命令行工具compute-mfcc-feats和compute-fbank-feats分别用于计算MFCC和fbank特征。不带参数运行它们,就会有输出帮助。

计算MFCC特征
下面我们介绍命令行工具compute-mfcc-feats计算MFCC特征的过程。这个程序需要两个参数:用于读取.wav文件的rspecifier(key是utterance id)和一个wspecifier来把特征写出去(key也是utterance id);更多解释请参考The Table concept和Specifying Table formats: wspecifiers and rspecifiers。通常输出的是一个ark文件,它包含了所有wav的特征,为了快速通过key定位,我们还需要一个对于的索引scp文件,详细可以参考Writing an archive and a script file simultaneously。这个程序并不增加delta特征(需要的话参考命令行工具add-deltas)。对于立体声,它可以通过–channel选项来指定通道(比如–channel=0或者–channel=1)。

MFCC的计算是通过Mfcc来实现计算的,它有一个Compute函数来根据wav计算特征。

MFCC的计算过程如下:

计算wav文件的帧数(默认帧长25ms,帧移10ms)
对于每一帧:
抽取这一帧的数据,进行可选的dithering(添加微小的随机噪声),preemphasis和直流去除(均值为零),然后乘以一个窗口函数(比如Hamming窗)
计算能量(如果是使用log能量而不是MFCC第一个系数作为特征的话)
FFT然后计算功率谱
计算每一个bin的能量;也就是23个有重叠的三角形滤波器,这些滤波器在美尔尺度上是均匀步长的。
计算log能量,然后进行DCT,保留13个系数,如果第一个使用能量,那么用前面计算的能量替换第一个系数。
可选的提升(lifting)倒谱,把它缩放的合适的范围。
选项里指定的最小频率–low-freq和最大频率–high-freq用于控制三角形滤波器组的频率范围。默认的最小频率是0,最大频率是Nyquist频率,也就是采样频率的一半,我们也可以自己指定这两个值。比如对于16KHz采样的语音,我们可以指定 --low-freq=20 and --high-freq=7800

Kaldi的特征提取和HTK有一些不同,大部分不同来自于默认值的设置。如果使用选项–htk-compat=true,并且参数设置是正确的,那么得到的特征会非常接近HTK的特征。最大的差异是Kaldi不支持能量的max归一化。这是因为我们希望特征的计算是无状态的,这样我们就可以逐帧的计算特征。compute-mfcc-feats有一个选项–subtract-mean,它用于减去特征的均值。这里使用的是每一个utterance的均值;也有基于说话人所有utterance的归一化方法(参考cepstral mean and variance normalization)。

1. 注意事项
首先要训练好模型,用到3个文件,分别是:
final.mdl(训练模型得到的模型文件)
final.mat(用来特征转换)
HCLG.fst(fst文件)
此外要提供待解码音频文件或路径.scp文件:
wav.scp(音频路径.scp文件)
2. 流程图:
st=>start: 开始
op1=>operation: compute-mfcc-feats
op2=>operation: copy-feats
op3=>operation: compute-cmvn-stats
op4=>operation: apply-cmvn
op5=>operation: splice-feats
op6=>operation: transform-feats
op7=>operation: nnet-latgen-faster
st->op1->op2->op3->op4->op5->op6->op7
流程每一步意义如下:
使用compute-mfcc-feats提取特征,生成对应的特征文件feats.ark;
使用copy-feats来拷贝特征文件,并创建特征的scp文件,生成feat.scp feat.ark ;
使用compute-cmvn-stats计算CMVN归一化,得到cmvn.scp cmvn.ark ;
使用apply-cmvn得到了applycmvn.ark文件;
使用splice-feats来继续变换特征 ,拼接相邻帧的特征;
使用transform-feats来进行特征转换,为了解码调用 ;
最后通过得到的transform.ark进行解码的操作,得到解码后的lattice文件 。
3. 具体流程指令:
首先列出具体文件,这里我就按照自己的文件给出了,如果用别的,改相应文件就行了
wav.scp(里面是保存了wav的绝对路径)
final.mdl(训练模型得到的模型文件)
final.mat(用来特征转换)
HCLG.fst(fst文件,用于解码)
使用compute-mfcc-feats生成对应的特征文件feats.ark:
compute-mfcc-feats --use-energy=false scp:wav.scp ark:feats.ark
使用copy-feats来拷贝特征文件,并创建特征的scp文件,生成feat.scp feat.ark
copy-feats ark:feats.ark ark,scp:feat.ark,feat.scp
使用compute-cmvn-stats计算CMVN归一化,得到cmvn.scp cmvn.ark
compute-cmvn-stats scp:feat.scp ark,scp:cmvn.ark,cmvn.scp
使用apply-cmvn,得到了applycmvn.ark文件
apply-cmvn scp:cmvn.scp scp:feat.scp ark:applycmvn.ark
使用splice-feats来继续变换特征
splice-feats --left-context=3 --right-context=3 ark:applycmvn.ark ark:splice.ark
使用transform来进行特征转换,为了解码调用
transform-feats final.mat ark:splice.ark ark:transform.ark
最后通过得到的transform.ark进行解码的操作,得到一个晶格文件
nnet-latgen-faster [options] <nnet-in> <fst-in|fsts-rspecifier> <features-rspecifier> <lattice-wspecifier>
4.我自己的流程

我这里用的模型输入就是40维,所以没有splice-feats这个步骤:

compute-fbank-feats --use-energy=false --sample-frequency=8000 --num-mel-bins=40 scp:wav.scp ark:feats.ark
copy-feats ark:feats.ark ark,scp:feat.ark,feat.scp
compute-cmvn-stats scp:feat.scp ark,scp:cmvn.ark,cmvn.scp
apply-cmvn --norm-means=true --norm-vars=false scp:cmvn.scp scp:feat.scp ark:applycmvn.ark
nnet3-latgen-faster --acoustic-scale=1.0 --frame-subsampling-factor=3 --max-active=7000 --min_active=200 --lattice-beam=8.0 --extra_left_context=0 --extra_right_context=0 --extra_left_context_initial=-1 --extra_right_context_final=-1 --beam=15.0 --word-symbol-table=../module_dir/tdnnf_test/words.txt ../module_dir/tdnnf_test/final.mdl ../module_dir/tdnnf_test/HCLG.fst ark:applycmvn.ark "ark:|lattice-scale --acoustic-scale=10 ark:- ark:- | gzip -c >./lat.gz"

生成文件

 [root@localhost wav_dir_8k]# ls
040_20201230194105_1199367613_1.wav  cmvn.ark  feat.ark   feat.scp  wav.scp applycmvn.ark  cmvn.scp  feats.ark  lat.gz

结果

 LOG (nnet3-latgen-faster[5.5.958~2-57f8d]:CheckAndFixConfigs():nnet-am-decodable-simple.cc:294) Increasing --frames-per-chunk from 50 to 51 to make it a multiple of --frame-subsampling-factor=3
    040_20201230194105_1199367613_1 唉 李 工 你好 信友电厂 二号 机组 刚 跳 了 一 台 磨 煤机 导致 AGC 退出 了 现在 我 正在 处理 估计 十分钟 之后 就 可以 处理 好 了 我 就 可以 投 上了 
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。