我正在尝试使用mfcc功能和隐藏的马尔可夫模型开发java中的音频分类系统。我正在关注这篇研究论文:http://acccn.net/cr569/Rstuff/keys/bathSoundMonitoring.pdf。
它描述了算法如下:
处理了与声音事件样本相对应的每个声音文件 由具有重叠的汉明窗口(25毫秒)预加重和加窗的帧 50%。由13阶MFCC组成的特征向量 帧。我们使用从左到右的六态连续密度对每个声音进行建模 HMM没有状态跳过。每个HMM状态由两个高斯混合组成 组件。完成模型初始化阶段后,所有HMM模型 在三个迭代周期中训练。
我已经完成了第一部分工作,即从样本声音中提取特征。结果我得到了一个2d的双精度数组,每行包含13列(每行代表一个声音的帧)。 现在我的问题是如何使用这些数据训练嗯。
我正在使用jahmm库。到目前为止,我已经开发了一些示例代码,以便大致了解库的工作原理。
/**Some sample data to act as the mfcc data. Here each line terminated by a new space
* is one observation. I don't know whether each line should be one row from the mfcc values
* (representing one frame) or each line should be representing a set of features from one audio file.
*/
String realSequences = "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n"
+ "1.1;2.2;3.3;4.4;5.5;6.6;7.7;8.8;9.9;10.0;11.1;12.2;13.3;\n";
/**
* This is the reader class that reads the data and puts then in a relevant collection format
*
*/
Reader reader = new StringReader(realSequences);
List<? extends List<ObservationReal>> sequences =
ObservationSequencesReader.readSequences(new ObservationRealReader(), reader);
reader.close();
/**
* As the description states that each state is composed of two Gaussian mixture components.
*/
OpdfGaussianMixtureFactory gMixtureFactory = new OpdfGaussianMixtureFactory(2);
/**
* The manual for jahmm says that KMeans learner is a good way to initialize the hmm. It has 6 states
* and uses the two gaussian mixture models created above.
*/
KMeansLearner<ObservationReal> kml = new KMeansLearner<ObservationReal>(6, gMixtureFactory, sequences);
Hmm<ObservationReal> initHmm = kml.iterate();
/*
* As the papers states the hmm is trained in 3 iterative cycles.
*/
BaumWelchLearner bwl = new BaumWelchLearner();
Hmm<ObservationReal> learntHmm = null;
for (int i = 0; i < 3; i++) {
learntHmm = bwl.iterate(initHmm, sequences);
}
我的问题是:
Q1:mfcc数据应采用何种格式传递以训练嗯? (参见realSeuqences专栏的评论)
Q2:在语音识别中,有时我们需要通过重复相同的单词来训练系统10次。这是否意味着用这10个样品训练一个嗯?如果是,那么如何使用相同声音的不同样本训练一个hmm。或者它是10个单独训练的嗯,但标有该词?
问题3:如何在声音识别方面比较两个hmm模型。使用维特比或Kullback Leibler距离更好吗?
答案 0 :(得分:2)
Q1:mfcc数据应采用何种格式传递以训练嗯? (参见realSeuqences专栏的评论)
MFCC数据必须表示为:
List<? extends List<ObservationVector>> sequences
这是一个数据序列列表。每个序列对应于单词样本并且是向量列表,每个向量表示一个帧并包含13个MFCC值。
Q2:在语音识别中,有时我们需要训练系统 重复相同的单词可以说10次。这是否意味着训练一个 嗯那10个样品?
输入数据是每个单词的序列列表。此列表将一起处理。
如果是,那么如何训练一个嗯 同一声音的不同样本。或者它是单独训练的10 嗯,但标有这个词?
这是一个HMM。 hmm训练算法适用于每个单词的几个样本。它实际上需要很多样本,超过10个。
问题3:如何在声音识别方面比较两个hmm模型。是吗 更好地使用维特比或Kullback Leibler距离?
目前还不太清楚“比较”是什么意思。您是否希望一个HMM的状态低于另一个或什么。您想用什么属性进行比较。答案取决于那个。
并且,重要的是要注意语音识别HMM训练具有一些特定的(如何选择状态数,使用哪些特征,如何初始化HMM)。出于这个原因,为了获得最佳性能,最好使用CMUSphinx(http://cmusphinx.sourceforge.net)等专用工具包,而不是通用工具包。