使用HTK中HRsults评价word spotting准确率(FOM)
毕设中涉及到使用the Figure of Merit(FOM)来测评音频word spotting的结果,但HTKbook对这个功能的叙述比较少,网上的内容也不多,所以看了下源码,基本上知道如何操作了,在这里记录下~
一、FOM理解
对于语音关键词检出任务中的FOM,具体可以看NIST的定义,是对word spotting结果的上界估计(upper-bound estimate),计算每个小时出现1~10个错误警报FA(false alarm)的正确检出(true hits)平均,公式如下:
Ρi代表在发生第¡次false alarm之前检测到的FA百分比,N为大于10T-0.5的第一个整数,a=10T-N用来保证每小时出现10次FA.
二、如何使用HTK工具中HResults工具来测评word spotting的FOM
HTKBook中只给出了HResults工具用来评价语音识别结果的方法为:
HResults [options] hmmList recFiles ...
虽然实质上测评FOM和语音识别结果都是将测试抄本(test transcription)和参考抄本(reference transcription)进行比对,但在命令执行上还是不太一样的。
翻开HRsult.c文件我们发现在word spot recording模式下将测试抄本和参考抄本比对的方法如下:
1 void MatchSpotFiles(void) 2 { 3 int i,j,nr,nt; 4 Label t,*l; 5 HTime t1,t2; 6 7 test=GetLabelList(ans,1); 8 NormaliseName(test,tlev); 9 if (test->head->succ == test->tail) { 10 HError(-3330,"MatchSpotFile: Test Output File %s is Empty",recfn); 11 return; 12 } 13 14 /* increment total duration - note that this assumes that the 15 end of the last ref label or test label whichever is greater, 16 marks the end of the file */ 17 t1 = t2 = 0.0; 18 if (ref->tail->pred!=ref->head) 19 t1=ref->tail->pred->end; 20 if (test->tail->pred!=test->head) 21 t2=test->tail->pred->end; 22 23 if (t1<0.0 || t2<0.0) { 24 HError(-3333,"MatchSpotFiles: Final times missing from label files"); 25 return; 26 } 27 28 totalDur += (t1>t2)?t1:t2; 29 30 /* increment key occ counts */ 31 nr=CountAuxLabs(ref,rlev); 32 for (i=1; i<=nr; i++) { 33 l = GetAuxLabN(ref,i,rlev); 34 j=Index((rlev==0)?l->labid:l->auxLab[rlev]); 35 if (j!=0) ++keyOccs[j]; 36 } 37 /* record key spots */ 38 nt=CountAuxLabs(test,tlev); 39 for (i=1; i<=nt; i++) { 40 l = GetAuxLabN(test,i,tlev); 41 t = *l; 42 t.end = AuxLabEndTime(l,tlev); 43 AddSpot(l->labid,IsHit(&t),l->score); 44 } 45 }
MatchSpotFiles方法从参考抄本中依次检测LabelList中每个Label关键词,从而累加对应的keyOccs[j]数组,也就是keyword真实出现的次数;同时从测试抄本中检测各个Label所含的关键词,同时累加关键词被检出的次数,并将每次关键词的出现记录在spotRec的列表中。有了关键词真实出现的次数和被检测的记录,就可以按照FOM的定义计算各个关键词的FOM值,这里不多说,具体可以看HResults中的CalcKeyFOM和CalcGlobal方法。
但是到这里我们还是不知道命令行下的具体命令和如何组织测试抄本和参看抄本,通过查看HResults.c中的main函数我们知道先读入的是options选项和测试抄本的.mlf文件,之后有如下方法:
Initialise(GetStrArg());
再看看Initialise的定义:
1 void Initialise(char * listfn) 2 { 3 CreateHeap(&tempHeap, "tempHeap", MSTAK, 1, 1.0, 8000, 40000); 4 5 nulClass = GetLabId(nulName,TRUE); 6 ReadHMMList(listfn); 7 if (stripContexts) LTriStrip(TRUE); 8 if (outPStats) 9 InitConMat(); 10 if (wSpot) 11 InitSpotLists(); 12 if (fullResults && !wSpot && !nistFormat) 13 PrintBar(0,htkWidth,'-',"Sentence Scores"); 14 if (!nistFormat && spkrMask!=NULL) htkWidth += 11; 15 }
在做语音识别测评的时候需要由ReadHMMList方法读入HMMList,但在keyword spotting任务下却不是这样,所以这里应该替换为关键词的list。源代码的分析就是这样,接下来实践一下:
在命令行下输入:
HResults.exe -w -I test.mlf wlist ref.mlf
得到测评结果:
当然这是我自己手工整理的测试和参考抄本,索引得到的数据略假。。。这里只是给大家一个展示~
以上只是我个人看过源码之后的一点见解,错误的地方很多,希望能在今后进一步深入!