Document hmm_train executable entirely, and change some outputs from printf to fastlib standards where necessary
This commit is contained in:
@@ -11,12 +11,13 @@
|
||||
* See the usage() function for complete option list
|
||||
*/
|
||||
|
||||
#include "fastlib/fastlib.h"
|
||||
#include <fastlib/fastlib.h>
|
||||
#include "support.h"
|
||||
#include "discreteHMM.h"
|
||||
#include "gaussianHMM.h"
|
||||
#include "mixgaussHMM.h"
|
||||
#include "mixtureDST.h"
|
||||
#include "hmm_documentation.h"
|
||||
|
||||
using namespace hmm_support;
|
||||
|
||||
@@ -25,67 +26,67 @@ success_t train_viterbi();
|
||||
void usage();
|
||||
|
||||
const fx_entry_doc hmm_train_main_entries[] = {
|
||||
{"input_file", FX_REQUIRED, FX_STR, NULL,
|
||||
"Input file containing data sequences to train on.\n"},
|
||||
{"guess_file", FX_PARAM, FX_STR, NULL,
|
||||
"File containing guess of HMM model profile (.hmm)\n"},
|
||||
{"output_file", FX_PARAM, FX_STR, NULL,
|
||||
"Output file containing trained HMM profile (default output.<type>.hmm)\n"},
|
||||
{"type", FX_REQUIRED, FX_STR, NULL,
|
||||
" HMM type : discrete | gaussian | mixture.\n"},
|
||||
"HMM type: discrete | gaussian | mixture\n"},
|
||||
{"algorithm", FX_PARAM, FX_STR, NULL,
|
||||
" Training algoritm: baumwelch | viterbi.\n"},
|
||||
{"seqfile", FX_REQUIRED, FX_STR, NULL,
|
||||
" Output file for the data sequences.\n"},
|
||||
{"guess", FX_PARAM, FX_STR, NULL,
|
||||
" File containing guessing HMM model profile.\n"},
|
||||
{"numstate", FX_PARAM, FX_INT, NULL,
|
||||
" If no guessing profile specified, at least provide the number of states.\n"},
|
||||
{"profile", FX_REQUIRED, FX_STR, NULL,
|
||||
" Output file containing trained HMM profile.\n"},
|
||||
{"maxiter", FX_PARAM, FX_INT, NULL,
|
||||
" Maximum number of iterations, default = 500.\n"},
|
||||
"Training algorithm: baumwelch | viterbi (default baumwelch)\n"},
|
||||
{"num_states", FX_PARAM, FX_INT, NULL,
|
||||
"If no guess profile is specified, at least provide the number of states\n"},
|
||||
{"max_iter", FX_PARAM, FX_INT, NULL,
|
||||
"Maximum number of iterations (default 500)\n"},
|
||||
{"tolerance", FX_PARAM, FX_DOUBLE, NULL,
|
||||
" Error tolerance on log-likelihood as a stopping criteria.\n"},
|
||||
"Error tolerance on log-likelihood as a stopping criteria (default 0.001)\n"},
|
||||
FX_ENTRY_DOC_DONE
|
||||
};
|
||||
|
||||
const fx_submodule_doc hmm_train_main_submodules[] = {
|
||||
const fx_submodule_doc hmm_train_submod_entries[] = {
|
||||
{"formats", &hmm_format_doc,
|
||||
"Documentation for file formats used by this program and other MLPACK HMM tools\n"},
|
||||
FX_SUBMODULE_DOC_DONE
|
||||
};
|
||||
|
||||
const fx_module_doc hmm_train_main_doc = {
|
||||
hmm_train_main_entries, hmm_train_main_submodules,
|
||||
"This is a program training HMM models from data sequences. \n"
|
||||
hmm_train_main_entries, hmm_train_submod_entries,
|
||||
"The hmm_train utility is for training HMMs from data sequences. Given an\n"
|
||||
"input file of data sequences, and optionally a file containing a guess of\n"
|
||||
"the HMM profile (or a parameter specifying the number of states), the program\n"
|
||||
"will use the specified training algorithm (Viterbi or Baum-Welch, default\n"
|
||||
"Baum-Welch) to train the HMM until the log-likelihood error reaches the given\n"
|
||||
"value (default 0.001).\n"
|
||||
"\n"
|
||||
"It is important to note that if the guess file is not specified, the number\n"
|
||||
"of states must be specified. Additionally, a guess file must be specified\n"
|
||||
"if the HMM type is 'mixture'.\n"
|
||||
"\n"
|
||||
"See the documentation in the 'formats' submodule (--help=formats) for more\n"
|
||||
"information on the file formats that this program uses.\n"
|
||||
};
|
||||
|
||||
void usage() {
|
||||
printf("\nUsage:\n"
|
||||
" train --type=={discrete|gaussian|mixture} OPTION\n"
|
||||
"[OPTIONS]\n"
|
||||
" --algorithm={baumwelch|viterbi} : algorithm used for training, default Baum-Welch\n"
|
||||
" --seqfile=file : file contains input sequences\n"
|
||||
" --guess=file : file contains guess HMM profile\n"
|
||||
" --numstate=NUM : if no guess profile is specified, at least specify the number of state\n"
|
||||
" --profile=file : output file for estimated HMM profile\n"
|
||||
" --maxiter=NUM : maximum number of iteration, default=500\n"
|
||||
" --tolerance=NUM : error tolerance on log-likelihood, default=1e-3\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
fx_init(argc, argv, &hmm_train_main_doc);
|
||||
success_t s = SUCCESS_PASS;
|
||||
if (fx_param_exists(NULL,"type")) {
|
||||
if (fx_param_exists(NULL, "type")) {
|
||||
const char* algorithm = fx_param_str(NULL, "algorithm", "baumwelch");
|
||||
if (strcmp(algorithm,"baumwelch")==0)
|
||||
if (strcmp(algorithm, "baumwelch") == 0)
|
||||
s = train_baumwelch();
|
||||
else if (strcmp(algorithm,"viterbi")==0)
|
||||
else if (strcmp(algorithm, "viterbi") == 0)
|
||||
s = train_viterbi();
|
||||
else {
|
||||
printf("Unrecognized algorithm: must be baumwelch or viterbi !!!\n");
|
||||
FATAL("Unrecognized training algorithm: must be 'baumwelch' or 'viterbi'.\n");
|
||||
s = SUCCESS_FAIL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Unrecognized type: must be: discrete | gaussian | mixture !!!\n");
|
||||
FATAL("Unrecognized HMM type; must be 'discrete', 'gaussian', or 'mixture'.\n");
|
||||
s = SUCCESS_FAIL;
|
||||
}
|
||||
if (!PASSED(s)) usage();
|
||||
|
||||
fx_done(NULL);
|
||||
}
|
||||
|
||||
@@ -101,10 +102,8 @@ success_t train_baumwelch() {
|
||||
return train_baumwelch_gaussian();
|
||||
else if (strcmp(type, "mixture")==0)
|
||||
return train_baumwelch_mixture();
|
||||
else {
|
||||
printf("Unrecognized type: must be: discrete | gaussian | mixture !!!\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
success_t train_viterbi_discrete();
|
||||
@@ -119,40 +118,34 @@ success_t train_viterbi() {
|
||||
return train_viterbi_gaussian();
|
||||
else if (strcmp(type, "mixture")==0)
|
||||
return train_viterbi_mixture();
|
||||
else {
|
||||
printf("Unrecognized type: must be: discrete | gaussian | mixture !!!\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
success_t train_baumwelch_mixture() {
|
||||
if (!fx_param_exists(NULL, "seqfile")) {
|
||||
printf("--seqfile must be defined.\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
MixtureofGaussianHMM hmm;
|
||||
ArrayList<Matrix> seqs;
|
||||
|
||||
const char* seqin = fx_param_str_req(NULL, "seqfile");
|
||||
const char* proout = fx_param_str(NULL, "profile", "pro.mix.out");
|
||||
const char* seqin = fx_param_str_req(NULL, "input_file");
|
||||
const char* proout = fx_param_str(NULL, "output_file", "output.mix.hmm");
|
||||
|
||||
load_matrix_list(seqin, &seqs);
|
||||
|
||||
if (fx_param_exists(NULL, "guess")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess");
|
||||
printf("Load parameters from file %s\n", guess);
|
||||
if (fx_param_exists(NULL, "guess_file")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess_file");
|
||||
NOTIFY("Loading guess parameters from file %s...", guess);
|
||||
hmm.InitFromFile(guess);
|
||||
}
|
||||
else {
|
||||
hmm.Init();
|
||||
printf("Automatic initialization not supported !!!");
|
||||
FATAL("Automatic initialization not supported for mixture training.");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
int maxiter = fx_param_int(NULL, "maxiter", 500);
|
||||
int maxiter = fx_param_int(NULL, "max_iter", 500);
|
||||
double tol = fx_param_double(NULL, "tolerance", 1e-3);
|
||||
|
||||
NOTIFY("Training using Baum-Welch algorithm...");
|
||||
hmm.TrainBaumWelch(seqs, maxiter, tol);
|
||||
|
||||
hmm.SaveProfile(proout);
|
||||
@@ -161,36 +154,30 @@ success_t train_baumwelch_mixture() {
|
||||
}
|
||||
|
||||
success_t train_baumwelch_gaussian() {
|
||||
if (!fx_param_exists(NULL, "seqfile")) {
|
||||
printf("--seqfile must be defined.\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
GaussianHMM hmm;
|
||||
ArrayList<Matrix> seqs;
|
||||
|
||||
const char* seqin = fx_param_str_req(NULL, "seqfile");
|
||||
const char* proout = fx_param_str(NULL, "profile", "pro.gauss.out");
|
||||
const char* seqin = fx_param_str_req(NULL, "input_file");
|
||||
const char* proout = fx_param_str(NULL, "output_file", "output.gauss.hmm");
|
||||
|
||||
load_matrix_list(seqin, &seqs);
|
||||
|
||||
if (fx_param_exists(NULL, "guess")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess");
|
||||
printf("Load parameters from file %s\n", guess);
|
||||
if (fx_param_exists(NULL, "guess_file")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess_file");
|
||||
NOTIFY("Loading guess parameters from file %s...", guess);
|
||||
hmm.InitFromFile(guess);
|
||||
}
|
||||
else { // otherwise initialized using information from the data
|
||||
int numstate = fx_param_int_req(NULL, "numstate");
|
||||
printf("Generate HMM parameters: NUMSTATE = %d\n", numstate);
|
||||
int numstate = fx_param_int_req(NULL, "num_states");
|
||||
NOTIFY("Generating HMM parameters: %d states...", numstate);
|
||||
hmm.InitFromData(seqs, numstate);
|
||||
printf("Done.\n");
|
||||
}
|
||||
|
||||
int maxiter = fx_param_int(NULL, "maxiter", 500);
|
||||
int maxiter = fx_param_int(NULL, "max_iter", 500);
|
||||
double tol = fx_param_double(NULL, "tolerance", 1e-3);
|
||||
|
||||
printf("Training ...\n");
|
||||
NOTIFY("Training using Baum-Welch algorithm...");
|
||||
hmm.TrainBaumWelch(seqs, maxiter, tol);
|
||||
printf("Done.\n");
|
||||
|
||||
hmm.SaveProfile(proout);
|
||||
|
||||
@@ -198,33 +185,29 @@ success_t train_baumwelch_gaussian() {
|
||||
}
|
||||
|
||||
success_t train_baumwelch_discrete() {
|
||||
if (!fx_param_exists(NULL, "seqfile")) {
|
||||
printf("--seqfile must be defined.\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
const char* seqin = fx_param_str_req(NULL, "seqfile");
|
||||
const char* proout = fx_param_str(NULL, "profile", "pro.dis.out");
|
||||
const char* seqin = fx_param_str_req(NULL, "input_file");
|
||||
const char* proout = fx_param_str(NULL, "output_file", "output.dis.hmm");
|
||||
|
||||
ArrayList<Vector> seqs;
|
||||
load_vector_list(seqin, &seqs);
|
||||
|
||||
DiscreteHMM hmm;
|
||||
|
||||
if (fx_param_exists(NULL, "guess")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess");
|
||||
printf("Load HMM parameters from file %s\n", guess);
|
||||
if (fx_param_exists(NULL, "guess_file")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess_file");
|
||||
NOTIFY("Loading HMM parameters from file %s...", guess);
|
||||
hmm.InitFromFile(guess);
|
||||
}
|
||||
else { // otherwise randomly initialized using information from the data
|
||||
int numstate = fx_param_int_req(NULL, "numstate");
|
||||
printf("Randomly generate parameters: NUMSTATE = %d\n", numstate);
|
||||
int numstate = fx_param_int_req(NULL, "num_states");
|
||||
NOTIFY("Randomly generating parameters: %d states...", numstate);
|
||||
hmm.InitFromData(seqs, numstate);
|
||||
}
|
||||
|
||||
int maxiter = fx_param_int(NULL, "maxiter", 500);
|
||||
int maxiter = fx_param_int(NULL, "max_iter", 500);
|
||||
double tol = fx_param_double(NULL, "tolerance", 1e-3);
|
||||
|
||||
NOTIFY("Training using Baum-Welch algorithm...");
|
||||
hmm.TrainBaumWelch(seqs, maxiter, tol);
|
||||
|
||||
hmm.SaveProfile(proout);
|
||||
@@ -233,33 +216,29 @@ success_t train_baumwelch_discrete() {
|
||||
}
|
||||
|
||||
success_t train_viterbi_mixture() {
|
||||
if (!fx_param_exists(NULL, "seqfile")) {
|
||||
printf("--seqfile must be defined.\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
MixtureofGaussianHMM hmm;
|
||||
ArrayList<Matrix> seqs;
|
||||
|
||||
const char* seqin = fx_param_str_req(NULL, "seqfile");
|
||||
const char* proout = fx_param_str(NULL, "profile", "pro.mix.out");
|
||||
const char* seqin = fx_param_str_req(NULL, "input_file");
|
||||
const char* proout = fx_param_str(NULL, "output_file", "output.mix.hmm");
|
||||
|
||||
load_matrix_list(seqin, &seqs);
|
||||
|
||||
if (fx_param_exists(NULL, "guess")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess");
|
||||
printf("Load parameters from file %s\n", guess);
|
||||
if (fx_param_exists(NULL, "guess_file")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess_file");
|
||||
NOTIFY("Loading parameters from guess file %s...", guess);
|
||||
hmm.InitFromFile(guess);
|
||||
}
|
||||
else {
|
||||
hmm.Init();
|
||||
printf("Automatic initialization not supported !!!");
|
||||
FATAL("Automatic initialization not supported for mixture training.");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
int maxiter = fx_param_int(NULL, "maxiter", 500);
|
||||
int maxiter = fx_param_int(NULL, "max_iter", 500);
|
||||
double tol = fx_param_double(NULL, "tolerance", 1e-3);
|
||||
|
||||
NOTIFY("Training using Viterbi algorithm...");
|
||||
hmm.TrainViterbi(seqs, maxiter, tol);
|
||||
|
||||
hmm.SaveProfile(proout);
|
||||
@@ -268,33 +247,29 @@ success_t train_viterbi_mixture() {
|
||||
}
|
||||
|
||||
success_t train_viterbi_gaussian() {
|
||||
if (!fx_param_exists(NULL, "seqfile")) {
|
||||
printf("--seqfile must be defined.\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
GaussianHMM hmm;
|
||||
ArrayList<Matrix> seqs;
|
||||
|
||||
const char* seqin = fx_param_str_req(NULL, "seqfile");
|
||||
const char* proout = fx_param_str(NULL, "profile", "pro.gauss.viterbi.out");
|
||||
const char* seqin = fx_param_str_req(NULL, "input_file");
|
||||
const char* proout = fx_param_str(NULL, "output_file", "output.gauss.hmm");
|
||||
|
||||
load_matrix_list(seqin, &seqs);
|
||||
|
||||
if (fx_param_exists(NULL, "guess")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess");
|
||||
printf("Load parameters from file %s\n", guess);
|
||||
if (fx_param_exists(NULL, "guess_file")) { // guessed parameters in a file
|
||||
const char* guess = fx_param_str_req(NULL, "guess_file");
|
||||
NOTIFY("Loading parameters from file %s...", guess);
|
||||
hmm.InitFromFile(guess);
|
||||
}
|
||||
else { // otherwise initialized using information from the data
|
||||
int numstate = fx_param_int_req(NULL, "numstate");
|
||||
printf("Generate parameters: NUMSTATE = %d\n", numstate);
|
||||
int numstate = fx_param_int_req(NULL, "num_states");
|
||||
NOTIFY("Generating parameters with %d states\n", numstate);
|
||||
hmm.InitFromData(seqs, numstate);
|
||||
}
|
||||
|
||||
int maxiter = fx_param_int(NULL, "maxiter", 500);
|
||||
int maxiter = fx_param_int(NULL, "max_iter", 500);
|
||||
double tol = fx_param_double(NULL, "tolerance", 1e-3);
|
||||
|
||||
NOTIFY("Training using Viterbi algorithm...");
|
||||
hmm.TrainViterbi(seqs, maxiter, tol);
|
||||
|
||||
hmm.SaveProfile(proout);
|
||||
@@ -303,34 +278,30 @@ success_t train_viterbi_gaussian() {
|
||||
}
|
||||
|
||||
success_t train_viterbi_discrete() {
|
||||
if (!fx_param_exists(NULL, "seqfile")) {
|
||||
printf("--seqfile must be defined.\n");
|
||||
return SUCCESS_FAIL;
|
||||
}
|
||||
|
||||
DiscreteHMM hmm;
|
||||
ArrayList<Vector> seqs;
|
||||
|
||||
const char* seqin = fx_param_str_req(NULL, "seqfile");
|
||||
const char* proout = fx_param_str(NULL, "profile", "pro.dis.viterbi.out");
|
||||
const char* seqin = fx_param_str_req(NULL, "input_file");
|
||||
const char* proout = fx_param_str(NULL, "output_file", "output.dis.hmm");
|
||||
|
||||
load_vector_list(seqin, &seqs);
|
||||
|
||||
if (fx_param_exists(NULL, "guess")) { // guessed parameters in a file
|
||||
if (fx_param_exists(NULL, "guess_file")) { // guessed parameters in a file
|
||||
ArrayList<Matrix> matlst;
|
||||
const char* guess = fx_param_str_req(NULL, "guess");
|
||||
printf("Load parameters from file %s\n", guess);
|
||||
const char* guess = fx_param_str_req(NULL, "guess_file");
|
||||
NOTIFY("Loading guess parameters from file %s...", guess);
|
||||
hmm.InitFromFile(guess);
|
||||
}
|
||||
else { // otherwise randomly initialized using information from the data
|
||||
int numstate = fx_param_int_req(NULL, "numstate");
|
||||
printf("Generate parameters with NUMSTATE = %d\n", numstate);
|
||||
int numstate = fx_param_int_req(NULL, "num_states");
|
||||
NOTIFY("Generate parameters with %d states\n", numstate);
|
||||
hmm.InitFromData(seqs, numstate);
|
||||
}
|
||||
|
||||
int maxiter = fx_param_int(NULL, "maxiter", 500);
|
||||
int maxiter = fx_param_int(NULL, "max_iter", 500);
|
||||
double tol = fx_param_double(NULL, "tolerance", 1e-3);
|
||||
|
||||
NOTIFY("Training using Viterbi algorithm...");
|
||||
hmm.TrainViterbi(seqs, maxiter, tol);
|
||||
|
||||
hmm.SaveProfile(proout);
|
||||
|
||||
Reference in New Issue
Block a user