关键词搜索模块

本文由@冒顿翻译,后由@wbgxx333搬移到这里。

联系方式:[email protected]

介绍

本文描述了在kaldi中的关键词搜索模块。我们实现了以下功能:

  • 对网络进行索引以便快速检索关键词
  • 使用代理关键词以处理表外词(OOV)问题

在以下的文档中,我们将重点讨论为特殊目的而进行的基于词的关键词检索,但我们同样支持子词级别的关键词检索。我们的语音识别模块和关键词检索模块都使用加权有限状态转换器wfst,这个算法也支持使用符号表将词/子词映射到整数。

本文剩下的部分结构如下:在Typical Kaldi KWS system部分, 我们描述了kaldi kws 系统的基本模块;在Proxy keywords部分, 我们解释了我们如何使用代理关键词处理不在词汇表中的关键词;最后在Babel scripts部分, 我们介绍了为iarpa bable项目所做的kws相关的脚本。

Typical Kaldi KWS system

我们在文章"Quantifying the Value of Pronunciation Lexicons for Keyword Search in Low Resource Languages", G. Chen, S. Khudanpur, D. Povey, J. Trmal, D. Yarowsky and O. Yilmaz中可以看到kaldi kws 系统的例子。一般来说,一个kws系统包括两个部分:一个lvcsr 模块解码检索集合并且产生相应的网格,一个kws 模块生成网格索引并从索引中查找关键词。

我们的基础lvcsr 系统是一个sgmm+mmi 系统,我们使用标准的PLP分析器抽取13维的语音特征,然后用一个典型的最大似然估计进行语音训练,以一个平滑的上下文无关的音素HMM做初始值开始,以说话人自适应(SAT)的状态集群三音素hmm-gmm做为输出结束。在说话人变换训练集的统一背景模型(UBM)进行训练,然后得到用于训练HMM发射概率的子空间高斯混合模型(SGMM),最后,所有的训练语音使用SGMM系统进行解码,然后对sgmm的参数进行bmmi训练。更详细的细节参见egs/babel/s5b/run-1-main.sh。

我们在sgmm_mmi系统之外还创建了一些附加的系统,如:一个混合深度神经网络(DNN).详情见egs/babel/s5b/run-2a-nnet-gpu.sh,一个瓶颈特殊(BNF)系统,详情见egs/babel/s5b/run-8a-kaldi-bnf.sh 等等。所有这些系统都是对相同的检索集合进行解码并且生成网格,随后送到kws 模块进行索引和检索。我们在检索结果上而不是在网格上将这些系统组织起来。由上述lvscr 系统产生的网格,使用在文章"Lattice indexing for spoken term detection", D. Can, M. Saraclar, Audio, Speech, and Language Processing中描述的网格索引技术进行处理。所有待检索集语句中的网格都被从单一加权有限状态转换成一个单广义因数变送器结构,将每个词的开始时间,结束时间和网格后验概率这三维数据存储起来。给一个词或短语,我们创建他的简单有限状态机,可以得到这个关键词/短语并且将他与因数变送器得到关键词/短语在检索集合中所有出现过的地方,和一个语句的ID号,开始时间,结束时间,以及每个地方网格的后验概率。所有检索出来的结果以他们的后验概率进行排序,并且使用论文"Rapid and Accurate Spoken Term Detection"中的方法来对每个实例判断是或否。

Proxy keywords代理关键词

我们的代理关键词产生过程在论文 "Using Proxies for OOV Keywords in the Keyword Search Task", G. Chen, O. Yilmaz, J. Trmal, D. Povey, S. Khudanpur做了描述。我们最早使用这个方法解决词网格中的oov问题,如果关键词不在lvcsr系统的词汇表中,尽管实际上这个词在谈话中已经被提到了,但他也不会出现在检索集的网格中。这是lvcsr 为基础的关键词检索系统的一个老问题,并且已经有办法解决它,比如,创建一个子词系统。我们的办法是寻找语音中与词汇表中相似的词,并且使用这些词做为代理关键词替换那些表外词汇。这样做的好处是我们不用创建额外的子词系统。在即将到来的interspeech 的论文"Low-Resource Open Vocabulary Keyword Search Using Point Process Models", C. Liu, A. Jansen, G. Chen, K. Kintzley, J. Trmal, S. Khudanpur中我们证明这技术可以同一个建立在点处理模型上的音素检索模型相媲美。代理关键词是一种模糊检索方法,他在处理表外词的同时也可以加强IV关键词性能。 通常的代理关键词处理过程可以用以下公式产生:

这里 为原始的关键词, 是包含发音的 词汇。如果 是表外词,这个词汇可以使用G2P工具得到。 是编辑距离转换,表示音素与训练集的差异程度。 是原始词汇。 是包含多个IV词的WFST,是与原始发音 相似的发音词。我们把他当成原始词进行检索。 注意两个修正阶段是必不可少的,尤其当你的词汇表非常大的时候。我们同时实现了一个简单的组合算法,只产生必须的组合状态(比如,不产生以后会被修正的状态)。这避免了在计算 组合的时候使用内存太多。

Babel scripts

A highlevel look 概述

我们为IARPA Babel 项目建立了一个“一键”脚本。如果你在Babel 上进行实验时想用我们的脚本,你可以用以下几步建立一个SGMM+MMI的关键词检索系统(假设你的工作目录是 egs/babel/s5b/)

  • 安装F4DE 并且将他设置在你的path.sh中。
  • 修改cmd.sh以保证可以运行在你的集群 。
  • 将conf/languages中的一个文件连接到./lang.conf, 比如 "ln -s conf/languages/105-turkish-limitedLP.official.conf lang.conf"
  • 修改lang.conf中的JHU集群中的数据使它指向你的数据文件。
  • 运行run-1-main.sh ,建议lvcsr系统。
  • 运行run-2-segmentation.sh, 产生eval 数据的分割
  • 运行run-4-anydecode.sh,解码eval 数据,生成索引检索关键词。

同时,你可以建立DNN系统,BNF系统,Semi-supervised 系统等等语音识别系统。关键词检索任务在run-4-anydecode.sh中执行。我们将在下面介绍如何进行关键词检索的细节,你可以把这些方法用于其它的数据上。我们假设你已经解码了检索集合并且产生的相应的网格。

关键词检索数据准备

一般来说,我们在检索数据的目录中建立kws的数据目录。例如,如果你有一个叫做dev10h.uem的检索集。数据所在的目录为data/dev10.uem/. 我们在在这个目录下面创建kws 数据目录,如data/dev10h.uem/kws. 在创建kws目录之前,你必须有三个文件,一个包含检索信息的ecf文件,一个关键词列表kwlist文件,一个打分文件rttm. 有时你必须自已创建这些文件,例如,你可以创建一个rttm文件指定模型中的检索的参数。下面我们列出这些文件的格式:ECF文件的例子:

<ecf source_signal_duration="483.825" language="" version="Excluded noscore regions">   <excerpt audio_filename="YOUR_AUDIO_FILENAME" channel="1" tbeg="0.000" dur="483.825" source_type="splitcts"/> </ecf>

KWLIST文件的例子:

<kwlist ecf_filename="ecf.xml" language="tamil" encoding="UTF-8" compareNormalize="" version="Example keywords">   <kw kwid="KW204-00001">     <kwtext>செய்றத</kwtext>   </kw>   <kw kwid="KW204-00002">     <kwtext>சொல்லுவியா</kwtext>   </kw> </kwlist>

RTTM 文件的例子:

SPEAKER YOUR_AUDIO_FILENAME 1 5.87 0.370 <NA> <NA> spkr1 <NA> LEXEME YOUR_AUDIO_FILENAME 1 5.87 0.370 ஹலோ lex spkr1 0.5 SPEAKER YOUR_AUDIO_FILENAME 1 8.78 2.380 <NA> <NA> spkr1 <NA> LEXEME YOUR_AUDIO_FILENAME 1 8.78 0.300 உம்ம் lex spkr1 0.5 LEXEME YOUR_AUDIO_FILENAME 1 9.08 0.480 அதான் lex spkr1 0.5 LEXEME YOUR_AUDIO_FILENAME 1 9.56 0.510 சரியான lex spkr1 0.5 LEXEME YOUR_AUDIO_FILENAME 1 10.07 0.560 மெசேஜ்டா lex spkr1 0.5 LEXEME YOUR_AUDIO_FILENAME 1 10.63 0.350 சான்ஸே lex spkr1 0.5 LEXEME YOUR_AUDIO_FILENAME 1 10.98 0.180 இல்லயே lex spkr1 0.5

准备好这些文件后,你可以开始准备kws 数据目录。如果你只是想进行基本关键词检索,运行以下命令:

local/kws_setup.sh \   --case_insensitive $case_insensitive \   --rttm-file $my_rttm_file \   $my_ecf_file $my_kwlist_file data/lang $dataset_dir

如果你要对表外词汇进行模糊检索,你可以运行以下几个命令,这些命令首先收集相似音素,然后训练G2P模型,创建KWS数据目录:

#Generate the confusion matrix #NB, this has to be done only once, as it is training corpora dependent, #instead of search collection dependent if [ ! -f exp/conf_matrix/.done ] ; then   local/generate_confusion_matrix.sh --cmd "$decode_cmd" --nj $my_nj  \     exp/sgmm5/graph exp/sgmm5 exp/sgmm5_ali exp/sgmm5_denlats  exp/conf_matrix   touch exp/conf_matrix/.done fi confusion=exp/conf_matrix/confusions.txt  if [ ! -f exp/g2p/.done ] ; then   local/train_g2p.sh  data/local exp/g2p   touch exp/g2p/.done fi local/apply_g2p.sh --nj $my_nj --cmd "$decode_cmd" \   --var-counts $g2p_nbest --var-mass $g2p_mass \   $kwsdatadir/oov.txt exp/g2p $kwsdatadir/g2p L2_lex=$kwsdatadir/g2p/lexicon.lex  L1_lex=data/local/lexiconp.txt local/kws_data_prep_proxy.sh \   --cmd "$decode_cmd" --nj $my_nj \   --case-insensitive true \   --confusion-matrix $confusion \   --phone-cutoff $phone_cutoff \   --pron-probs true --beam $beam --nbest $nbest \   --phone-beam $phone_beam --phone-nbest $phone_nbest \   data/lang  $data_dir $L1_lex $L2_lex $kwsdatadir

Indexing and searching索引和检索

在这一阶段,我们假设你已经解码了检索集合并且生成了相应的网格。运行以下脚本将进行索引和检索:

local/kws_search.sh --cmd "$cmd" \   --max-states ${max_states} --min-lmwt ${min_lmwt} \   --max-lmwt ${max_lmwt} --skip-scoring $skip_scoring \   --indices-dir $decode_dir/kws_indices $lang_dir $data_dir $decode_dir

如果你的KWS数据目录有一个额外的ID号,比如 oov(当你进行不同的kws 时,这很有用,这种情况下,你的目录可以是这样的data/dev10h.uem/kws_oov),你必须使用extraid 选项:

local/kws_search.sh --cmd "$cmd" --extraid $extraid  \   --max-states ${max_states} --min-lmwt ${min_lmwt} \   --max-lmwt ${max_lmwt} --skip-scoring $skip_scoring \   --indices-dir $decode_dir/kws_indices $lang_dir $data_dir $decode_dir