kaldi中改写sre10/v1用timit dataset做说话人识别总结

首先非常感谢david-ryan-snyder 提供的帮助,非常耐心的给出问题的解答。
经过一个周的调试修改,终于在timit数据集上跑通了sre10中的v1 demo, 特来总结一下,重新理顺一下思路,把其中的各个步骤的算法大体的捋一遍。
最重要的还是数据准备阶段,由于没有原始的数据,整个过程进行的比较困难,花了差不多一个周的时间来各种改,之前第一次跑wsj那个demo的时候才花了不到一个周,现在对kaldi还算比较熟悉,对数据处理的脚本也都写出来了,只需要稍微改一下就好,总之还是对说话人识别的技术不太了解. 回归正题,我们看到sre10/v1的run.sh中有四个data set: sre train sre10_train sre10_test. 根据后边的的script我们可以得知这四个集合的数据集有哪些以及分别的作用是什么:
一、 SRE:
SRE2004 LDC2006S44
SRE2005 Train LDC2011S01
SRE2005 Test LDC2011S04
SRE2006 Train LDC2011S09
SRE2006 Test 1 LDC2011S10
SRE2006 Test 2 LDC2012S01
SRE2008 Train LDC2011S05
SRE2008 Test LDC2011S08
1. prepare sre data: local/make_sre.sh data
2. make mfcc features: steps/make_mfcc.sh –mfcc-config conf/mfcc.conf –nj 40 –cmd “ traincmd"data/sreexp/makemfcc  mfccdir
3. computer VAD sid/compute_vad_decision.sh –nj 40 –cmd “ traincmd"data/sreexp/makevad vaddir
4. extract_ivectors sid/extract_ivectors.sh –cmd “$train_cmd -l mem_free=6G,ram_free=6G” –nj 50 exp/extractor data/sre \ exp/ivectors_sre
5. train PLDA modle local/plda_scoring.sh data/sre data/sre10_train data/sre10_test \
exp/ivectors_sre exp/ivectors_sre10_train exp/ivectors_sre10_test $trials local/scores_gmm_2048_ind_pooled
上面是SRE set经过的计算,我们可以看到前四步都是跟其他的几个set是一样的,所以我们的SRE库主要是用来训练PLDA模型的。 关于PLDA模型的简单理解请看: 还没写
关于VAD的源码以及计算请看:http://blog.csdn.net/zjm750617105/article/details/52336403
二、 Train
SWBD2 Phase 2 LDC99S79
SWBD2 Phase 3 LDC2002S06
SWBD Cellular 1 LDC2001S13
SWBD Ceullar 2 LDC2004S07
SRE2004 LDC2006S44
SRE2005 Train LDC2011S01
SRE2005 Test LDC2011S04
SRE2006 Train LDC2011S09
SRE2006 Test 1 LDC2011S10
SRE2006 Test 2 LDC2012S01
SRE2008 Train LDC2011S05
SRE2008 Test LDC2011S08
1. prepare sre data: utils/combine_data.sh data/train \
data/swbd_cellular1_train data/swbd_cellular2_train \
data/swbd2_phase2_train data/swbd2_phase3_train data/sre
可见train set是包括sre set的
2. make mfcc features
3. computer VAD
4. train diag UBM sid/train_diag_ubm.sh –nj 40 –cmd “ traincmdlmemfree=20G,ramfree=20G data/train16k num_components \
exp/diag_ubm_$num_components
5. train full UBM “sid/train_full_ubm.sh –nj 40 –remove-low-count-gaussians false \
–cmd train_cmd  data/train_32k  exp/diag_ubm_{num_components} exp/full_ubm_ numcomponents6.sid/trainivectorextractor.shcmd train_cmd -l mem_free=35G,ram_free=35G” \
–ivector-dim 600 \
–num-iters 5 exp/full_ubm_$num_components/final.ubm data/train exp/extractor
训练ivector的特征提取器
可见 Train 这个训练集主要是用来训练UBM 和 ivector的提取器extractor的
三、 sre10_train and sre10_test
enroll(sre10_train) and test(sre10_test) share speakers, they should not contain utterances from the same recordings.
也就是说/export/corpora5/SRE/SRE2010/eval/ 这个集合中每一个人的一部分语音作为sre10_train , 另一部分作为sre10_test
这两个集合的作用主要是最后的evaluation阶段。
上面是原始的脚本,但是现在我们没有那么多的数据,我们只有timit的数据集,630spks * 10utts/spk = 6300utts那我们应该怎么划分呢?
由上面每个集合的作用可以看出,我们可以把sre和train集合用一个用sre来表示就可以,我们取330个说话人的语料作为sre,其中sre来训练PLDA模型,sre_1600 来训练diag_ubm,sre_3200来训练full_ubm , 用sre来训练 ivector 的extractor.
剩余的300spks作为evaluation(sre10_train and sre10_test) , 这样的话基本OK,注意sre和evaluation集合中男女比例都要适中

但是这里边有一个非常重要的问题,也是困扰了好几天的问题,就是有一个trials文件, 这个文件的问题具体可以看我在github问的一个问题: https://github.com/kaldi-asr/kaldi/issues/1014
这里我再简单的捋一下:首先在原始脚本里边这个文件是从
local/make_sre_2010_test.pl /export/corpora5/SRE/SRE2010/eval/ data/
产生的, 而这个脚本里边trials文件是从一个叫 coreext-coreext.trialkey.csv文件中读出来的,然而这个文件是在原始的sre10数据库里边的,但是我们没有这个数据库,所以我们得想办法自己根据格式以及数据的分布自己写一个脚本去生成一个,具体的脚本就不分享了,说一下具体思路,自己写的话也很快就能写出来。
首先根据local/make_sre_2010_test.pl: print OUT_TRIALS ;
我们可以确定trials文件的格式:
format: “speakerId uttId target/nontarget”
spkA spkA-utt1 target(target 或者是 nontarget)
spkA spkA-utt2 istarget
spkA spkB-utt2 nontarget
前两列我们可以根据spk2utts文件得到,但是第三列的值我们不知道(在 coreext-coreext.trialkey.csv中有值,直接读出来就好,具体看make_sre_2010_test.pl脚本), 如果我们这个地方全部默认是target的话,我们会发现在最后compute-eer的时候会报一个错误,说没有nontarget,所以在设计的时候必须有target和nontarget. 这个怎么设计我们下面会说, 我们先看一下nontarget的话是什么格式:
nontarget
nontarget
nontarget
注意看就是说话人和utt不匹配的情况,这个需要我们有全部的target,然后生成一定比例的nontarget , 然后合起来作为一个t rials文件。 下面是david-ryan-snyder(kaldi维护者之一)建议:
What I suggest is that you look at the spk2utt file, and write a script that generates a trials file for you. For each speaker, you can take the speaker id and all the utterances that belong to it and pair them up to create the “target” trials. For example:

target
target
To create the nontarget trials, you can randomly pair a speaker with utterances belonging to another speaker. For example:

nontarget
nontarget
nontarget
Since you’ll need to write a script to do this, you can create an option that controls the probability of forming nontarget trials, and you can generate several trials files with a different percent of nontargets and see how the results vary between them. Since the scripts evaluate on the equal error-rate (EER), most likely it won’t make a big difference. E.g., if your EER is 10% with 50% nontarget trials, it will likely continue to be 10% with 80% nontarget trials.

读懂了上面的所有内容和注意要点,应该两三天就可以搞出来,其中还有很多的实现的细节,那就需要有一定的语音识别的基础、一定的代码能力和debug能力。
下面是我按照200spks作为sre的结果:
GMM-1024 EER
ind female: 9.524
ind male: 17.77
ind pooled: 11.83
dep female: 28.57
dep male: 12.89
dep pooled: 28.17
有明显错误,性别相关的结果不如性别无关的好
300spk 80%nontrarget sre的结果:
GMM-1024 EER
ind female: 7.576
ind male: 7.639
ind pooled: 6.349
dep female: 7.576
dep male: 7.176
dep pooled: 7.778
仅供参考。
文中还有一下算法的原理是没整理出来的,有时间再来整理或者给出一些比较好的博客或者论文。

你可能感兴趣的:(sre)