Kaldi 说话人识别以及xvector和PLDA介绍

原理部分

主要来自Dan 2017年在interspeech上的论文
Deep Neural Network Embeddings for Text-Independent Speaker Verification 以及 CSDN上monsieurliaxiamen对它的解读,plda部分来自论文Probabilistic Linear Discriminant Analysis,具体见文末Reference部分

lda
linear discriminant analysis。监督学习,降维,分类,kaldi说话人识别中主要用来降维。
模型目标:内间距离越大,内内距离越小。
plda
Probabilistic Linear Discriminant Analysis,可以用于类推理、分类、假设检验以及聚类。kaldi中说话人识别主要用于Inference。
PCA
principal component Analysis,主成分分析,非监督学习,可以用于降维、数据预处理。
目标:数据之间方差最大化。因为越有区分性的特征,在这个特征上数据应该越分散,也就说方差会越大。

实践部分

脚本来自kaldi/egs/sre16/v2/run.sh
忽略其中的augment以及各种数据combined部分,剩下部分主要有以下几大块:

流程介绍

数据准备

data preparation

提取特征

steps/make_mfcc.sh

训练提取xvector

local/nnet3/xvector/prepare_feats_for_egs.sh
local/nnet3/xvector/run_xvector.sh
sid/nnet3/xvector/extract_xvectors.sh

lda和plda生成

ivector-mean
ivector-compute-lda
ivector-compute-plda

plda 打分

ivector-plda-scoring

plda 文件概览(三部分分别是mean_ 、transform_、psi_)

<Plda>  [ 0.1910353 0.1038426 0.007481088 0.002701155 -0.001868085 -0.002852982 -0.004794177 0.0003118274 0.001357874 -0.0003702804 -0.007818467 -0.006480816 -0.01073896 -0.007529463 -0.0004633793 0.005444924 0.00405669 0.004729587 0.006050912 -0.00173621 -0.01375775 0.0002508409 0.0009469036 0.0003214211 0.005703435 -0.009714458 0.007051155 0.009829545 -0.01356905 0.006318203 ]
 [
  1.005321 -0.07987567 0.004292751 0.01341255 -0.00775885 -0.006687849 -0.02105686 -0.01885685 -0.01961054 0.00874298 0.01298537 0.02908863 -0.02184164 -0.02787862 0.008261035 0.02874176 0.008588934 0.006092427 0.02091952 0.01834754 -0.02541942 -0.007677392 0.004872064 -0.0001613838 0.01633646 -0.03131115 0.005954142 0.03456053 -0.05974155 0.004061513
  0.05136413 1.005225 0.004460757 -0.01348865 0.003562312 0.0003487898 0.01290073 -0.01474868 0.01212416 0.00889867 -0.003501936 0.0007597982 -0.02017156 0.02082325 -0.02117081 0.008176986 -0.0002946498 0.004753779 -0.01417886 0.004547984 -0.02952497 -0.001326409 -0.003239684 0.0207567 -6.161483e-05 -0.01402215 0.0004445125 0.00183783 -0.001046173 0.0235291
...
  -0.009447127 -0.003009784 -0.2182507 -0.3392377 0.2602997 -0.005991881 0.1182683 0.1908596 -0.07981741 -0.0311276 -0.06683343 -0.0693347 -0.1725913 0.2734958 0.1326121 -0.06617561 -0.1493326 0.1054356 0.09206729 0.1523166 0.02825381 0.2420946 0.09938067 0.1702297 0.1592616 0.1837506 0.06555345 0.2809799 0.4906489 -0.03724701
  0.001444527 -0.00968504 0.1732248 -0.1366071 0.09926528 0.1737767 -0.09885036 0.008107004 -0.00198012 0.1945651 -0.04585695 0.01186848 0.1706801 -0.07791475 0.0221427 0.3386421 0.341729 -0.1832474 0.1837578 0.1290585 0.350675 0.1412214 -0.1184681 -0.4228691 -0.1344547 0.1760014 0.0703044 0.1712077 0.1165621 -0.08851321 ]
 [ 2.307668 0.143411 1.863693e-05 1.86066e-05 1.857748e-05 1.856671e-05 1.85515e-05 1.854624e-05 1.852481e-05 1.850243e-05 1.849062e-05 1.848249e-05 1.845776e-05 1.844569e-05 1.844352e-05 1.8426e-05 1.842294e-05 1.840143e-05 1.838444e-05 1.837731e-05 1.835936e-05 1.835559e-05 1.833895e-05 1.832552e-05 1.830681e-05 1.830368e-05 1.829919e-05 1.829096e-05 1.827391e-05 1.819192e-05 ]

内部细节

从后往前开始介绍,重点介绍最后一个命令。
[备注:以终为始是我们快速掌握一项技能或者看懂一篇文章的很重要的一个方法,与带着问题去学习有异曲同工之妙。论文或者教科书教我们的都是线性思维,总是一步一步,先把所有该准备的都准备好,然后biu的一声,结果出来了。我们经常疑惑的是:我们前期做了那么多的准备,是为了什么,特别是在流程比较复杂又或者人心浮躁无法深入完整的看下去的时候,以终为始能够很好的解决这个问题,它能让你很快的熟悉整个流程,也能让你知道中间的那些弯弯绕绕到底是为了什么?]

ivector-plda-scoring 参数以及命令介绍

比如实际项目中,我们已经拿到了训练集训练得到的plda,然后来了一个音频,希望得到该音频对应的类别(说话人或者音频质量什么的),怎么做呢? 也就是最后一步的ivector-plda-scoring。摘抄命令如下:

ivector-plda-scoring --num-utts=ark:exp/train/num_utts.ark 
plda \
ark:exp/train/spk_ivectors.ark \
ark:exp/test/ivectors.ark \
trials \
scores

对应的脚本截图如下:


ivector-plda-scoring

命令对照着截图来看[冒号前面是实际参数,冒号后面是截图中通过命令生成的参数]:
plda : ivector-copy-plda --smoothing=0.0 exp/xvectors_sre_combined/plda - |
ark:exp/train/spk_ivectors.ark : 对应每个类别对应的向量,比如下面就是三个说话人对应的spk_ivectors.ark,lda dim = 30

person1  [ -5.47368 -0.1970172 1.849248e-05 2.117038e-06 -4.931857e-05 -5.998876e-05 3.921373e-05 -2.858735e-05 -4.138478e-05 -2.632396e-05 5.241184e-06 3.867019e-05 1.214699e-05 -1.425252e-05 4.71196e-06 2.844079e-05 -3.951063e-06 -2.383433e-05 -2.382615e-05 6.957247e-07 4.588171e-06 3.023096e-06 -2.04503e-05 -1.585875e-05 -5.949017e-06 1.971544e-05 -2.424583e-05 1.140037e-05 -4.874436e-06 4.220028e-06 ]
person2  [ 3.89035 3.855538 -4.72949e-05 3.440788e-05 -0.0002225023 6.697718e-05 8.30239e-05 2.754744e-05 7.262208e-05 7.248818e-05 -0.0001983043 -8.678074e-05 0.000176367 -7.130462e-05 0.000122591 0.0001917566 7.880914e-06 -7.411545e-05 1.220619e-05 3.442607e-05 -1.725737e-06 1.023686e-05 -9.930105e-06 0.0001110308 1.779477e-05 3.857107e-05 0.0001238374 7.73169e-05 3.754893e-05 5.792317e-05 ]
person3  [ 4.146533 -3.578586 7.919347e-05 5.045559e-05 2.321615e-05 -3.699426e-05 4.365425e-05 6.24825e-05 -2.209483e-05 5.753889e-05 5.039277e-05 0.0001499025 -4.521562e-05 6.874517e-05 9.509942e-05 2.72809e-05 -3.908812e-05 -3.199685e-05 3.785522e-05 -1.839882e-05 1.846353e-05 1.505007e-05 6.653779e-05 -7.26548e-05 -5.498202e-06 2.419258e-05 6.142457e-05 5.799062e-05 2.95341e-05 -5.933775e-06 ]

ark:exp/test/ivectors.ark : "ark:ivector-subtract-global-mean exp/xvectors_sre16_major/mean.vec scp:exp/xvectors_sre16_eval_test/xvector.scp ark:- | transform-vec exp/xvectors_sre_combined/transform.mat ark:- ark:- | ivector-normalize-length ark:- ark:- |"
实际上就是test中的音频经过提特征、过神经网络得到xvector,然后和训练集一样经过去均值[ivector-subtract-global-mean],lda转换[transform-vec]、正则化[ivector-normalize-length]

trials [输入音频列表]

class1 test_001.wav
class2 test_001.wav
...

scores[各个类别得分文件,也是我们需要的结果]

class1 test_001.wav prob1
class2 test_001.wav prob2
...

音频属于各个类别的"概率"

注意上面的mean.vec 和 spk_ivectors.ark 的区别,直接从生成的命令就可以看出。

ivector-mean scp:exp/xvectors_train/xvector.scp exp/xvectors_train/mean.vec
ivector-mean ark:data/train/spk2utt scp:exp/xvectors_train/xvector.scp ark:- | ivector-subtract-global-mean exp/xvectors_train/mean.vec ark:- ark:- | transform-vec exp/xvectors_train/transform.mat ark:- ark:- | ivector-normalize-length ark:- ark:spk_ivectors.ark

ivector-plda-scoring 计算公式

plda.cc score comment

ivectorbin/ivector-plda-scoring.cc → ivector/plda.cc

上面代码的公式补充

注意倒数第二行公式(I+Ψ)少了个逆,另外,M_LOG_2PI * dim 在loglike_given_class 以及loglike_without_class 都有,所以消掉了

Reference

https://blog.csdn.net/monsieurliaxiamen/article/details/79638227
https://danielpovey.com/files/2017_interspeech_embeddings.pdf
https://blog.csdn.net/xmu_jupiter/article/details/47281211
Probabilistic Linear Discriminant Analysis
https://blog.csdn.net/liusongxiang666/article/details/83024845

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容