void MlHMM::mapAdapt( const char *input_fname, const char *output_fname, XFile *measurer_file ) { if ( (n_new > 0) && !init_shmm ) error("The new symbols have not been initialized\n" ); DataSet* data; if (disk) data = (DataSet*)new(allocator) DiskHTKDataSet( input_fnames, target_fnames, n_inputs, true, max_load, lex_output, is_symbol); else data = (DataSet*)new(allocator) HTKDataSet( input_fnames, target_fnames, n_inputs, true, max_load, lex_output, is_symbol); real* thresh = (real*)allocator->alloc(data->n_inputs*sizeof(real)); initializeThreshold(data,thresh,threshold); HMM** input = readHTK( input_fname, lex_input, thresh ); int n_models = lex_output->phone_info->n_phones; int i_new = 0; int i_input = 0; HMM** output = (HMM**)allocator->alloc(sizeof(HMM*)*n_models); // EMTrainer** hmm_trainer = (EMTrainer **)allocator->alloc(sizeof(EMTrainer*)*n_models); // MAPDiagonalGMM*** gmms = (MAPDiagonalGMM ***)allocator->alloc(sizeof(MAPDiagonalGMM**)*n_models); DiagonalGMM** priors = NULL; for (int i=0; i < n_models; i++) { bool new_model = false; if ( (i_new < n_new) && (i == new_in_output[i_new]) ) { // this is a new model output[i] = init_shmm->models[new_in_data[i_new]]; #ifdef __AXDEBUG__ printf("New internal symbol %s\n", lex_data->phone_info->getPhone(new_in_data[i_new]) ) ; #endif i_new++; new_model = true; } else { output[i] = input[i_input]; i_input++; } int states = output[i]->n_states; priors = (DiagonalGMM**)output[i]->states; gmms[i] = (MAPDiagonalGMM**)allocator->alloc(sizeof(MAPDiagonalGMM*)*states); for (int j=1;j<states-1;j++) { MAPDiagonalGMM* gmm = new(allocator)MAPDiagonalGMM(priors[j]); // set the training options if (thresh) gmm->setVarThreshold(thresh); if (prior>0) gmm->setROption("prior weights",prior); gmm->setROption("weight on prior",map_factor); gmm->setBOption("learn means",!no_learn_means); gmm->setBOption("learn variances",learn_var); gmm->setBOption("learn weights",learn_weights); if ( new_model ) { //gmm->setROption("weight on prior",0); //gmm->setBOption("learn variances",true); //gmm->setBOption("learn weights",true); } gmms[i][j] = gmm; } gmms[i][0] = NULL; gmms[i][states-1] = NULL; // MAP on new models only when not separate training ! if ( !new_model || !adapt_separate ) output[i]->states = (Distribution**)gmms[i]; if ( /* !new_model && */ adapt_separate ) { hmm_trainer[i] = new(allocator)EMTrainer(output[i]); hmm_trainer[i]->setIOption("max iter", max_iter * 1); hmm_trainer[i]->setROption("end accuracy", accuracy * 1.0); } else hmm_trainer[i] = NULL; } SpeechHMM* shmm = new(allocator) SpeechHMM( n_models , output , lex_output, hmm_trainer ); shmm->setBOption("targets are phonemes",!is_symbol); if ( adapt_separate ) { ExampleFrameSelectorDataSet** sub_dataset = (ExampleFrameSelectorDataSet**)allocator->alloc(sizeof(ExampleFrameSelectorDataSet*)*n_models); for (int m=0;m<n_models;m++) { sub_dataset[m] = new(allocator) ExampleFrameSelectorDataSet(data); } shmm->splitDataSet(data , sub_dataset); for (int i = 0; i < n_models; i++) { int m = i; // the transitions and emission parameters will be set in each model if (sub_dataset[m]->n_examples==0 || sub_dataset[m]->inputs->n_frames <= 0) { if ( adapt_separate_set_data ) { message("No example (just set data)"); shmm->models[m]->setDataSet(data); } //else // message("No example (don't set data)"); } else if (shmm->model_trainer[m]) { message("HMM adaptation of model %d with own aligned data",m); shmm->model_trainer[m]->train(sub_dataset[m], shmm->initial_models_trainer_measurers); } else { //message("No trainer (don't set data)"); //shmm->models[m]->setDataSet(sub_dataset[m]); } } } else { shmm->setBOption("initialize", false); // Measurers on the training dataset MeasurerList measurers; NLLMeasurer nll_meas(shmm->log_probabilities, data, measurer_file ); measurers.addNode(&nll_meas); // The Gradient Machine Trainer EMTrainer trainer(shmm); trainer.setIOption("max iter", max_iter); trainer.setROption("end accuracy", accuracy); if (viterbi) trainer.setBOption("viterbi", true); trainer.train(data, &measurers); } writeHTK( output_fname, shmm, lex_output->phone_info->phone_names ); }
int GMM(char *datafile, float means[N_GAUSS][3], float var[N_GAUSS][3], float logw[N_GAUSS]) { real accuracy = 0.001; //end accuracy real threshold = 0.001; //variance threshold int max_iter_kmeans = 50; //max number of iterations of KMeans int max_iter_gmm = 50; //max number of iterations of GMM int n_gaussians = N_GAUSS; //number of Gaussians real prior = 0.001; //prior on the weights int max_load = -1; //max number of examples to load for train int the_seed = -1; //the random seed bool norm = false; //normalize the datas char *save_model_file = "model.txt"; //the model file int k_fold = -1; //number of folds, if you want to do cross-validation bool binary_mode = true; //binary mode for files Allocator *allocator = new Allocator; //==================================================================== //=================== Create the DataSet ... ========================= //==================================================================== MatDataSet data(datafile, -1, 0, true, max_load, binary_mode); MeanVarNorm* mv_norm = NULL; if(norm) mv_norm = new(allocator)MeanVarNorm (&data); //==================================================================== //=================== Training Mode ================================= //==================================================================== if(the_seed == -1) Random::seed(); else Random::manualSeed((long)the_seed); if(norm) data.preProcess(mv_norm); //=================== Create the GMM... ========================= // create a KMeans object to initialize the GMM KMeans kmeans(data.n_inputs, n_gaussians); kmeans.setROption("prior weights",prior); // the kmeans trainer EMTrainer kmeans_trainer(&kmeans); kmeans_trainer.setROption("end accuracy", accuracy); kmeans_trainer.setIOption("max iter", max_iter_kmeans); // the kmeans measurer MeasurerList kmeans_measurers; DiskXFile *filektv = new(allocator) DiskXFile("kmeans_train_val", "w"); NLLMeasurer nll_kmeans_measurer(kmeans.log_probabilities,&data,filektv); kmeans_measurers.addNode(&nll_kmeans_measurer); // create the GMM DiagonalGMM gmm(data.n_inputs,n_gaussians,&kmeans_trainer); // set the training options real* thresh = (real*)allocator->alloc(data.n_inputs*sizeof(real)); initializeThreshold(&data,thresh,threshold); gmm.setVarThreshold(thresh); gmm.setROption("prior weights",prior); gmm.setOOption("initial kmeans trainer measurers", &kmeans_measurers); //=================== Measurers and Trainer =============================== // Measurers on the training dataset MeasurerList measurers; DiskXFile *filegtv = new(allocator) DiskXFile("gmm_train_val", "w"); NLLMeasurer nll_meas(gmm.log_probabilities, &data, filegtv); measurers.addNode(&nll_meas); // The Gradient Machine Trainer EMTrainer trainer(&gmm); trainer.setIOption("max iter", max_iter_gmm); trainer.setROption("end accuracy", accuracy); //trainer.setBOption("viterbi", true); //=================== Let's go... =============================== if(k_fold <= 0) { trainer.train(&data, &measurers); if(strcmp(save_model_file, "")) { DiskXFile model_(save_model_file, "w"); //cmd.saveXFile(&model_); if(norm) mv_norm->saveXFile(&model_); model_.taggedWrite(&n_gaussians, sizeof(int), 1, "n_gaussians"); model_.taggedWrite(&data.n_inputs, sizeof(int), 1, "n_inputs"); gmm.saveXFile(&model_); for (int i = 0; i < N_GAUSS; i++) { logw[i] = gmm.log_weights[i]; for (int j = 0; j < 3; j++) { means[i][j] = gmm.means[i][j]; var[i][j] = gmm.var[i][j]; } } } } else { KFold k(&trainer, k_fold); k.crossValidate(&data, NULL, &measurers); } delete allocator; return(0); }