当前位置: 首页 > 工具软件 > GOP > 使用案例 >

发音测评 kaldi compute gop 保姆级实战指南

庾君博
2023-12-01


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明,违反必究。
本文链接:https://blog.csdn.net/junxing2018_wu/article/details/126334989

用 kaldi 计算gop得分

计算原理

该部分参考 kalid官方操作指南

  • GOP-GMM
    在传统的基于GMM-HMM的系统中,GOP最早是在(Witt et al., 2000)中提出的。
    它被定义为标准化后对数时段后验概率(the duration normalised log of the posterior)
    G O P ( p ) = 1 t e − t s + 1 l o g p ( p ∣ o ) GOP(p) = \frac {1} {t_e - t_s + 1} log {p(p|o)} GOP(p)=tets+11logp(po)
    这里的 o o o是输入观测值, p p p是规范发音音素, t s t_s ts t e t_e te 代表开始和结束的帧索引
    这里假设对于任意的 q i q_i qi, q j q_j qj,
    p ( q i ) ≈ p ( q j ) p(q_i) \approx p(q_j) p(qi)p(qj)
    我们有
    l o g p ( p ∣ o ) = p ( o ∣ p ) p ( p ) ∑ q ∈ Q p ( o ∣ q ) p ( q ) ≈ p ( o ∣ p ) ∑ q ∈ Q p ( o ∣ q ) log p(p|o) = \frac {p(o|p)p(p)} {\sum_{q \in Q} {p(o|q)p(q)}} \approx \frac {p(o|p)} {\sum_{q \in Q} {p(o|q)}} logp(po)=qQp(oq)p(q)p(op)p(p)qQp(oq)p(op)
    这里的 Q Q Q表示所有phone音素集合
    等式的分子是从强制对齐结果计算出来的,而分母是从具有不受约束的音素循环的维特比解码中计算出来的。

Kaldi 没有为我们实现 GOP-GMM,因为 GOP-NN 的性能比 GOP-GMM 好得多。

  • GOP-NN
    GOP-NN的定义与 GOP-GMM 有点不同。GOP-NN 定义为规范音素与得分最高的音素之间的对数音素后验比率(Hu et al., 2015)。
    首先,我们定义 Log Phone Postterior (LPP):
    L P P ( p ) = l o g p ( p ∣ o ; t s , t e ) LPP(p) = log p(p|o; t_s, t_e) LPP(p)=logp(po;ts,te)
    然后我们使用LPP定义 GOP-NN:
    G O P ( p ) = l o g L P P ( p ) m a x q ∈ Q L P P ( q ) GOP(p) = log {\frac {LPP(p)} {max_{q \in Q} LPP(q)}} GOP(p)=logmaxqQLPP(q)LPP(p)
    LPP 可以计算为:
    L P P ( p ) ≈ 1 t e − t s + 1 ∑ t = t s t e l o g p ( p ∣ o t ) LPP(p) \approx \frac {1} {t_e - t_s + 1} {\sum_{t=t_s}^{t_e} log{p(p|o_t)}} LPP(p)tets+11t=tstelogp(pot)
    p ( p ∣ o t ) = ∑ s ∈ p p ( s ∣ o t ) p(p|o_t) = \sum_{s \in p} {p(s|o_t)} p(pot)=spp(sot)

where s s s is the senone label, s ∣ s ∈ p s|s∈p ssp is the states belonging to those triphones whose current phone is p p p.

这里 s s s表示senone标记, s ∣ s ∈ p s|s∈p ssp 是当前音素是 p p p时的那些三音素的状态

  • Phone-level Feature
    通常,基于分类器的方法比基于gop的方法性能更好
    和基于gop的方法不同,需要额外的监督训练过程。监督训练的输入特征是phone级别的分段特征。
    phone级别的特征定义为:
    [ L P P ( p 1 ) , … , L P P ( p j ) , … , L P P ( p M ) , L P R ( p 1 ∣ p i ) , … , L P R ( p j ∣ p i ) , … , L P R ( p M ∣ p i ) ] [LPP(p_1), \dots, LPP(p_j), \dots, LPP(p_M), LPR(p_1|p_i), \dots, LPR(p_j|p_i), \dots, LPR(p_M|p_i)] [LPP(p1),,LPP(pj),,LPP(pM),LPR(p1pi),,LPR(pjpi),,LPR(pMpi)]
    这里 M M M 是所有phone音素集合
    其中 phone p j p_j pj 和 phone p i p_i pi 之间的对数后验概率比率(
    Log Posterior Ratio (LPR))定义为:
    L P R ( p j ∣ p i ) = l o g p ( p j ∣ o ; t s , t e ) − l o g p ( p i ∣ o ; t s , t e ) LPR(p_j|p_i) = log p(p_j|o;t_s, t_e) - log p(p_i|o;t_s, t_e) LPR(pjpi)=logp(pjo;ts,te)logp(pio;ts,te)

计算流程

  • load_wav : 加载音频(16k wav)
  • make_mfcc.sh : 提取 MFCC 特征(frame_size, 40)
  • extract_ivectors : 提取 ivector 特征(暂时不能理解为啥gop需要说话人信息)
  • compute_output.sh :
  • align_mapped.sh : 每帧映射到 transition-id (三音素ID)
  • ali-to-phones : 每帧映射到 phone-id
  • compute-gop : [纯音素-id + LPPs + LPRs]

动手实做

  • 安装kaldi
  1. 拉取最新的 kaldi 代码
  2. 根据 INSTALL 说明,进行编译,基本都能顺利成功

python 版本需要注意,默认使用python2.7,可以指定为常用的python3版本
可能系统默认gcc 版本不支持,可以通过指定gcc的版本进行编译,例如,

CXX=g++-6 extras/check_dependencies.sh
make depend CC=gcc-6 CPP=g++-6 CXX=g++-6 LD=g++-6
make CC=gcc-6 CPP=g++-6 CXX=g++-6 LD=g++-6 -j 8
  1. 验证是否安装成功,如果执行 compute-gop --help看到如下信息kaldi就安装成功啦~ Congratulations~~~
$ compute-gop --help

Compute Goodness Of Pronunciation (GOP) from a matrix of probabilities (e.g. from nnet3-compute).
Usage:  compute-gop [options] <model> <alignments-rspecifier> <prob-matrix-rspecifier> <gop-wspecifier> [<phone-feature-wspecifier>]
e.g.:
 nnet3-compute [args] | compute-gop 1.mdl ark:ali-phone.1 ark:- ark:gop.1 ark:phone-feat.1

Options:
  --log-applied               : If true, assume the input probabilities have been applied log. (bool, default = true)
  --phone-map                 : File name containing old->new phone mapping (each line is: old-integer-id new-integer-id) (string, default = "")
  --skip_phones_string        : Do not write features and gops for those phones (string, default = "0")

Standard options:
  --config                    : Configuration file to read (this option may be repeated) (string, default = "")
  --help                      : Print out usage message (bool, default = false)
  --print-args                : Print the command line arguments (to stderr) (bool, default = true)
  --verbose                   : Verbose level (higher->more logging) (int, default = 0)

  • 准备需要的python包
pip install kaldi-io==0.9.4 kaldiio==2.17.2 imblearn -i https://pypi.tuna.tsinghua.edu.cn/simple
```
- 使用开源数据 speechocean762 测试计算gop分数
```bash
# 进入到工作目录
```
$ cd $KALDI_ROOT/egs/gop_speechocean762/s5/

# 把假命令替换成真命令 
$ rm -f step
$ cp -r ../../wsj/s5/steps .
$ rm -f utils
$ cp -r ../../wsj/s5/utils .
$ rm -f local/feat_to_score_train.py
$ cp local/tuning/feat_to_score_train_1c.py local/feat_to_score_train.py
$ rm -f utils/run.pl
$ cp utils/parallel/run.pl utils/

# 执行gop计算
$ chmod 777 run.sh
$ ./run.sh
...
steps/align_mapped.sh: done aligning data.
The features are visualized and saved in exp/gop_train/feats.png
MSE: 0.70
Corr: 0.23
              precision    recall  f1-score   support

           0       0.24      0.31      0.27      1412
           1       0.05      0.78      0.09      1860
           2       0.99      0.36      0.53     44097

    accuracy                           0.37     47369
   macro avg       0.43      0.48      0.30     47369
weighted avg       0.93      0.37      0.50     47369
# 看到这里 恭喜您已经完成了本次实验。
```

 类似资料: