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



    版权声明:本文为博主原创文章,遵循 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
    • 2
    • 3
    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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 准备需要的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
    # 看到这里 恭喜您已经完成了本次实验。
    ```
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    java面向对象(三)
    【python与数据分析】NumPy数值计算基础1——numpy数组及其运算
    LeetCode Cookbook 树(4)
    ParagonNTFS15.9.314新版Mac强大的读写工具
    LeetCode每日一题(898. Bitwise ORs of Subarrays)
    javascript--async和defer的区别
    SpringCache_概述、Cacheable、更新缓存、删除缓存、从0搭建缓存项目
    常见的8个JMeter压测问题
    聚类分析 | MATLAB实现基于SOM自组织特征映射聚类可视化
    Java-web全解
  • 原文地址:https://blog.csdn.net/junxing2018_wu/article/details/126334989