📄 hmm_10.cc
字号:
// file: $isip/class/pr/HiddenMarkovModel/hmm_10.cc// version: $Id: hmm_10.cc,v 1.1 2003/01/11 15:20:59 jelinek Exp $//// isip include files//#include "HiddenMarkovModel.h"// method: adapt//// arguments:// Vector<StatisticalModel>& stat_models: (input/output) models to adapt//// return: a boolean value indicating status//// this method adapts the models using their accumulated statistics//// it implements MLLR adaptation according to// Chris J. Leggetter, Improved Acoustic Modeling for HMMs Using// Linear Transformations, February 1995, PhD thesis//boolean HiddenMarkovModel::adapt(Vector<StatisticalModel>& stat_models_a) { // the line below hard-codes that first three statistical models are // no speech models, thus they will be excluded from adaptation // long num_no_speech_states = 3; // get the number of features // long num_feat = 0; // if the model to adapt is Gaussian model, get feature dimension // if (stat_models_a(0).getType() == StatisticalModel::GAUSSIAN_MODEL) { VectorFloat mean; stat_models_a(0).getGaussianModel().getMean(mean); num_feat = mean.length(); } // if the model to adapt is mixture model, get feature dimension of // the first mixture component // else if (stat_models_a(0).getType() == StatisticalModel::MIXTURE_MODEL) { VectorFloat mean; StatisticalModel* sm = stat_models_a(0).getMixtureModel() .getModels().getFirst(); sm->getMean(mean); num_feat = mean.length(); } else { return Error::handle(name(), L"adapt", HiddenMarkovModel::ERR_ADAPT_NO_GAUSSIAN, __FILE__, __LINE__); } // define Z matrix // MatrixFloat z_glob(num_feat, num_feat + 1); // define G matrix // Vector<MatrixDouble> g_glob(num_feat); for (long i = 0; i < num_feat; i++) { g_glob(i).setDimensions(num_feat + 1, num_feat + 1); } // loop over all statistical models, but not silence model and // compute their contributions to the global adaptation // for (int i = num_no_speech_states; i < stat_models_a.length(); i++) { // if the model to adapt is a single Gaussian model, compute its // contribution to the global adaptation // if (stat_models_a(i).getType() == StatisticalModel::GAUSSIAN_MODEL) { GaussianModel& gm = stat_models_a(i).getGaussianModel(); // compute the contribution of this Gaussian model to the global // adaptation // adaptPart(g_glob, z_glob, gm); } // if the model to adapt is a mixture of Gaussian models, compute // the contribution of each mixture component to the global // adaptation // else if (stat_models_a(i).getType() == StatisticalModel::MIXTURE_MODEL) { // get the linked list of mixture components // SingleLinkedList<StatisticalModel>& models = const_cast<StatisticalModel&>(stat_models_a(i)).getMixtureModel(). getModels(); // check whether each mixture component is Gaussian model and // compute its contribution to the global adaptation // boolean more = models.gotoFirst(); while (more) { // get the current mixture component // StatisticalModel* model = models.getCurr(); // check whether it is Gaussian // if (model->getType() == StatisticalModel::GAUSSIAN_MODEL) { GaussianModel& gm = model->getGaussianModel(); // compute the contribution of this Gaussian model to the // global adaptation // adaptPart(g_glob, z_glob, gm); } else { return Error::handle(name(), L"adapt", HiddenMarkovModel::ERR_ADAPT_NO_GAUSSIAN, __FILE__, __LINE__); } // move to the next mixture component // more = models.gotoNext(); } // end of loop over all mixtures } // end of else if mixture model // it is neither single Gaussian, nor mixture model // else { return Error::handle(name(), L"adapt", HiddenMarkovModel::ERR_ADAPT_NO_GAUSSIAN, __FILE__, __LINE__); } // end of else unsupported model } // end of loop over all statistical models // define transformation matrix W (one row for each Gaussian // dimension) // Vector<VectorFloat> w(num_feat); for (long i = 0; i < num_feat; i++) { // since transformation is applied to the extended mean // w(i).setLength(num_feat + 1); } // compute the inverse of G // Vector<MatrixDouble> g_inv(num_feat); for (long i = 0; i < num_feat; i++) { double det = g_glob(i).determinant(); Double Det = det; // if in debug mode, print the determinant of G // if (debug_level_d >= Integral::ALL) { String out; out.concat(i); out.concat(L". det:"); out.concat(Det); Console::put(out); } // compute the threshold for a singularity of G matrix // double threshold = Integral::pow(0.1, num_feat); // if the matrix is singular with a given threshold, compute // inverse using SVD // if (g_glob(i).isSingular(threshold)) { MatrixDouble uu; MatrixDouble ww; MatrixDouble vv; g_glob(i).decompositionSVD(uu, ww, vv); // compute the inverse of ww // for (long j = 0; j < num_feat; j++) { Double diag_element = ww(j, j); // replace diagonal elements that are close to zero by zero // if (diag_element.almostEqual(0)) { ww.setValue(j, j, 0); } // otherwise compute inverted value // else { ww.setValue(j, j, 1 / ww(j, j)); } } // finally compute the inverse of G // g_inv(i).mult(vv, ww); uu.transpose(); g_inv(i).mult(uu); } // if matrix is not singular with a given threshold, compute // inverse by a standard method // else { g_inv(i).inverse(g_glob(i)); } } // compute the rows of Z matrix // Vector<VectorFloat> z_r(num_feat); for (long i = 0; i < num_feat; i++) { z_glob.getRow(z_r(i), i); } // convert G_inv matrices to float by looping over all elements // Vector<MatrixFloat> g_inv_f(num_feat); for (long i = 0; i < num_feat; i++) { g_inv_f(i).setDimensions(num_feat + 1, num_feat + 1); for (long j = 0; j < num_feat + 1; j++) { for (long k = 0; k < num_feat + 1; k++) { g_inv_f(i).setValue(j, k, g_inv(i)(j, k)); } } } // compute rows of the transformation matrix W // for (long i = 0; i < num_feat; i++) { g_inv_f(i).multv(w(i), z_r(i)); // if in debug mode, print the rows of the transformation matrix W // if (debug_level_d >= Integral::ALL) { String comment(L"w(i), i: "); comment.concat(i); w(i).debug(comment); } } // loop over all statistical models and adapt their parameters // for (int i = num_no_speech_states; i < stat_models_a.length(); i++) { // if the model to adapt is a single Gaussian model, adapt its // parameters using the transformation matrix W // if (stat_models_a(i).getType() == StatisticalModel::GAUSSIAN_MODEL) { stat_models_a(i).getGaussianModel().adapt(w); } // if the model to adapt is a Gaussian mixture model, loop over // all mixture components and adapt their parameters // else if (stat_models_a(i).getType() == StatisticalModel::MIXTURE_MODEL) { // get the linked list of mixtures // SingleLinkedList<StatisticalModel>& models = const_cast<StatisticalModel&>(stat_models_a(i)).getMixtureModel() .getModels(); // loop over the linked list of mixtures // boolean more = models.gotoFirst(); while (more) { // get the current mixture component // StatisticalModel* model = models.getCurr(); // since it was checked to be Gaussian already, it can be adapted // model->getGaussianModel().adapt(w); // move to the next mixture component // more = models.gotoNext(); } // end of loop over all mixtures } // end of else if mixture model } // end of loop over all statistical models // exit gracefully // return true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -