最近一直有个疑惑,plda是怎么训练的?就是plda是怎么计算得分的? 又是怎么根据得分进行判断说话人的? EER跟准确率之间又是什么关系?
时间很紧,论文还没写,需要静一静,好好弄明白这个来清醒一下。
提取完i-vector之后,计算出每一句话的ivector特征,然后计算了sre
ivector-mean scp:exp/ivectors_sre/ivector.scp exp/ivectors_sre/mean.vec
下面看ivector-mean.cc里边进行了什么操作:
就是把sre中所有的i-vector全都加起来并且总的utt number. 然后得到一个sre集合的均值向量,训练PLDA模型公式中中u.
// If 2 arguments are given, computes the mean of all input files and writes out the mean vector.
if (po.NumArgs() == 2) {
// Compute the mean of the input vectors and write it out.
std::string ivector_rspecifier = po.GetArg(1),
mean_wxfilename = po.GetArg(2);
int32 num_done = 0;
SequentialBaseFloatVectorReader ivector_reader(ivector_rspecifier);
Vector<double> sum;
for (; !ivector_reader.Done(); ivector_reader.Next()) {
if (sum.Dim() == 0) sum.Resize(ivector_reader.Value().Dim());
sum.AddVec(1.0, ivector_reader.Value());
num_done++;
}
if (num_done == 0) {
KALDI_ERR << "No iVectors read";
} else {
sum.Scale(1.0 / num_done);
WriteKaldiObject(sum, mean_wxfilename, binary_write);
return 0;
}
}
下面就是plda-scoring.sh的脚本,输入了8个参数,最后得到的得分文件 plda_scores.
local/plda_scoring.sh $tandem_feats_dir/sre $tandem_feats_dir/train $tandem_feats_dir/test \
exp/ivectors_sre exp/ivectors_train exp/ivectors_test $trials exp/scores_gmm_512_ind_pooled
vim local/plda_scoring.sh
#各个参数看上面的脚本,8个参数
plda_data_dir=$1
enroll_data_dir=$2
test_data_dir=$3
plda_ivec_dir=$4
enroll_ivec_dir=$5
test_ivec_dir=$6
trials=$7
scores_dir=$8
#由i-vector特征来训练一个plda模型,plda模型也是由sre集合训练的,所以这里传的参数都是sre的。
ivector-compute-plda ark:$plda_data_dir/spk2utt \
"ark:ivector-normalize-length scp:${plda_ivec_dir}/ivector.scp ark:- |" \
$plda_ivec_dir/plda 2>$plda_ivec_dir/log/plda.log
mkdir -p $scores_dir
ivector-plda-scoring --num-utts=ark:${enroll_ivec_dir}/num_utts.ark \
"ivector-copy-plda --smoothing=0.0 ${plda_ivec_dir}/plda - |"
"ark:ivector-subtract-global-mean ${plda_ivec_dir}/mean.vec \
scp:${enroll_ivec_dir}/spk_ivector.scp ark:- |" \
"ark:ivector-subtract-global-mean ${plda_ivec_dir}/mean.vec \
scp:${test_ivec_dir}/ivector.scp ark:- |" \
"cat '$trials' | awk '{print \$1, \$2}' |" $scores_dir/plda_scores
先看一下训练PLDA的源码:ivector-compute-plda.cc 只把关键代码拿出来,否则看起来很乱
int main(int argc, char *argv[]) {
try {
const char *usage =
"Computes a Plda object (