예제 #1
0
파일: mlhmm.cpp 프로젝트: DDMAL/aruspix
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 );

}
예제 #2
0
파일: gmm.cpp 프로젝트: kobeyuan/PCM
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);
}