56 static void load_vocab(
const EST_String &vfile);
60 static void load_wstream(
const EST_String &filename,
65 static void load_given(
const EST_String &filename,
66 const int ngram_order);
68 static double find_gram_prob(
EST_VTPath *p,
int *state);
71 static double find_extra_gram_prob(
EST_VTPath *p,
int *state,
int time);
76 static int max_history=0;
81 static float lm_scale = 1.0;
82 static float ob_scale = 1.0;
83 static float ob_scale2 = 1.0;
87 static float ob_beam=-1;
88 static int n_beam = -1;
90 static bool trace_on =
FALSE;
110 int main(
int argc,
char **argv)
118 EST_String(
"[observations file] -o [output file]\n")+
119 "Summary: find the most likely path through a sequence of\n"+
120 " observations, constrained by a language model.\n"+
121 "-ngram <string> Grammar file, required\n"+
122 "-given <string> ngram left contexts, per frame\n"+
123 "-vocab <string> File with names of vocabulary, this\n"+
124 " must be same number as width of observations, required\n"+
125 "-ob_type <string> Observation type : likelihood .... and change doc\"probs\" or \"logs\" (default is \"logs\")\n"+
126 "\nFloor values and scaling (scaling is applied after floor value)\n"+
127 "-lm_floor <float> LM floor probability\n"+
128 "-lm_scale <float> LM scale factor factor (applied to log prob)\n"+
129 "-ob_floor <float> Observations floor probability\n"+
130 "-ob_scale <float> Observation scale factor (applied to prob or log prob, depending on -ob_type)\n\n"+
131 "-prev_tag <string>\n"+
132 " tag before sentence start\n"+
133 "-prev_prev_tag <string>\n"+
134 " all words before 'prev_tag'\n"+
135 "-last_tag <string>\n"+
136 " after sentence end\n"+
141 "-observes2 <string> second observations (overlays first, ob_type must be same)\n"+
142 "-ob_floor2 <float> \n"+
143 "-ob_scale2 <float> \n\n"+
144 "-ob_prune <float> observation pruning beam width (log) probability\n"+
145 "-n_prune <int> top-n pruning of observations\n"+
146 "-prune <float> pruning beam width (log) probability\n"+
147 "-trace show details of search as it proceeds\n",
155 cerr <<
": you must give exactly one observations file on the command line";
157 cerr <<
"(use -observes2 for optional second observations)" << endl;
167 cerr << argv[0] <<
": no ngram specified" << endl;
173 cerr <<
"You must provide a vocabulary file !" << endl;
177 load_wstream(files.
first(),al.
val(
"-vocab"),wstream,observations);
180 load_wstream(al.
val(
"-observes2"),al.
val(
"-vocab"),wstream,observations2);
186 load_given(al.
val(
"-given"),ngram.
order());
191 lm_scale = al.
fval(
"-lm_scale");
196 ob_scale = al.
fval(
"-ob_scale");
201 ob_scale2 = al.
fval(
"-ob_scale2");
206 pstring = al.
val(
"-prev_tag");
207 if (al.
present(
"-prev_prev_tag"))
208 ppstring = al.
val(
"-prev_prev_tag");
212 beam = al.
fval(
"-prune");
217 ob_beam = al.
fval(
"-ob_prune");
223 n_beam = al.
ival(
"-n_prune");
226 cerr <<
"WARNING : " << n_beam;
227 cerr <<
" is not a reasonable value for -n_prune !" << endl;
241 floor = al.
fval(
"-lm_floor");
244 cerr <<
"Error : LM floor probability is negative !" << endl;
249 cerr <<
"Error : LM floor probability > 1 " << endl;
252 lm_log_prob_floor =
safe_log(floor);
258 floor = al.
fval(
"-ob_floor");
261 cerr <<
"Error : Observation floor probability is negative !" << endl;
266 cerr <<
"Error : Observation floor probability > 1 " << endl;
269 ob_log_prob_floor =
safe_log(floor);
274 floor = al.
fval(
"-ob_floor2");
277 cerr <<
"Error : Observation2 floor probability is negative !" << endl;
282 cerr <<
"Error : Observation2 floor probability > 1 " << endl;
285 ob_log_prob_floor2 =
safe_log(floor);
291 if(al.
val(
"-ob_type") ==
"logs")
293 else if(al.
val(
"-ob_type") ==
"probs")
297 cerr <<
"\"" << al.
val(
"-ob_type")
298 <<
"\" is not a valid ob_type : try \"logs\" or \"probs\"" << endl;
303 if(do_search(wstream))
306 cerr <<
"No path could be found." << endl;
320 else if ((fd = fopen(out_file,
"wb")) ==
NULL)
322 cerr <<
"can't open \"" << out_file <<
"\" for output" << endl;
326 for (s=wstream.
head(); s != 0 ; s=s->
next())
328 predict = s->
f(
"best").
string();
329 pscore = s->
f(
"best_score");
330 fprintf(fd,
"%s %f\n",(
const char *)predict,pscore);
348 if((beam > 0) || (ob_beam > 0))
354 cerr <<
"Starting Viterbi search..." << endl;
363 static void load_wstream(
const EST_String &filename,
375 if (obs.
load(filename,0.10) != 0)
377 cerr <<
"can't find observations file \"" << filename <<
"\"" << endl;
383 cerr <<
"Number in vocab (" << vocab.
length() <<
384 ") not equal to observation's width (" <<
395 static void load_given(
const EST_String &filename,
396 const int ngram_order)
405 cerr <<
"can't load given file \"" << filename <<
"\"" << endl;
410 for (p = given.
head(); p; p = p->
next())
412 for(i=0;i<given(p).
length();i++)
413 if( is_a_special( given(p)(i), j) && (-j > max_history))
420 static void load_vocab(
const EST_String &vfile)
425 if (ts.
open(vfile) == -1)
427 cerr <<
"can't find vocab file \"" << vfile <<
"\"" << endl;
443 item->
set(
"pos",pos);
449 double prob=1.0,prob2=1.0;
457 observe = s->
f(
"pos");
462 prob = observations.
a(observe,i);
464 prob2 = observations2.
a(observe,i);
469 if (prob < ob_log_prob_floor)
470 prob = ob_log_prob_floor;
475 if (prob2 < ob_log_prob_floor2)
476 prob2 = ob_log_prob_floor2;
481 if (prob < ob_log_prob_floor)
482 prob = ob_log_prob_floor;
483 if ((
num_obs == 2) && (prob2 < ob_log_prob_floor2))
484 prob2 = ob_log_prob_floor2;
491 c->
score = prob + prob2;
503 top_n_candidates(all_c);
526 prob = find_extra_gram_prob(np,&np->
state,c->
s->
f(
"pos"));
528 prob = find_gram_prob(np,&np->
state);
531 if (lprob < lm_log_prob_floor)
532 lprob = lm_log_prob_floor;
545 static double find_gram_prob(
EST_VTPath *p,
int *state)
549 double prob=0.0,nprob;
554 for (pp=p->
from,i=ngram.
order()-2; i >= 0; i--)
562 window[i] = ppstring;
576 for (i=0; i < ngram.
order()-1; i++)
577 window[i] = window(i+1);
578 ngram.
predict(window,&nprob,state);
584 static double find_extra_gram_prob(
EST_VTPath *p,
int *state,
int time)
588 double prob=0.0,nprob;
592 get_history(history,p);
594 fill_window(window,history,p,time);
612 for(i=history.length()-1;i>0;i--)
613 history[i] = history(i-1);
617 fill_window(window,history,p,time+1);
618 ngram.
predict(window,&nprob,state);
631 for (pp=p->
from,i=0; i < history.
length(); i++)
640 history[i] = ppstring;
643 history[i] = pstring;
659 if( time >= given.
length() )
675 for(i=0;i<ngram.
order()-1;i++)
678 if( is_a_special( (*this_g)(i), j))
679 window[i] = history(-1-j);
681 window[i] = (*this_g)(i);
718 for(i=0;i<n_beam;i++)
727 for(p=all_c;p!=
NULL;q=p,p=p->next)
730 if(p->score > this_best->score)
737 if(this_best ==
NULL)
741 if(prev_to_best ==
NULL)
743 all_c = this_best->
next;
746 prev_to_best->
next = this_best->
next;
748 this_best->
next = top_c;
EST_TokenStream & get(EST_Token &t)
get next token in stream
int contains(const char *s, ssize_t pos=-1) const
Does it contain this substring?
EST_read_status load(const EST_String &filename)
EST_read_status load_TList_of_StrVector(EST_TList< EST_StrVector > &w, const EST_String &filename, const int vec_len)
double safe_log(const double x)
double samples(void) const
Total number of example found.
#define SENTENCE_END_MARKER
void set(const EST_String &name, ssize_t ival)
int ival(const EST_String &rkey, int m=1) const
int num_channels() const
return number of channels in track
void close(void)
Close stream.
const EST_String & predict(const EST_StrVector &words, double *prob, int *state) const
EST_String itoString(int n)
Make a EST_String object from an integer.
bool result(const EST_String &n)
float fval(const EST_String &rkey, int m=1) const
void set(const EST_String &name, int ival)
T & nth(int n)
return the Nth value
void print_results(EST_Relation &ref, EST_Relation &test, EST_FMatrix &m, int tot, int del, int ins, int v)
double probability(const EST_String &s) const
int num_states(void) const
double safe_log10(const double x)
int main(int argc, char **argv)
int open(const EST_String &filename)
open a EST_TokenStream for a file.
const EST_Val f(const EST_String &name) const
const EST_DiscreteProbDistribution & prob_dist(const EST_StrVector &words) const
EST_read_status load(const EST_String name, float ishift=0.0, float startt=0.0)
void set_name(const EST_String &name) const
float & a(ssize_t i, int c=0)
void search(void)
Do the the actual search.
void set_pruning_parameters(float beam, float ob_beam)
set beam widths for pruning
INLINE ssize_t length() const
number of items in vector.
void initialise(EST_Relation *r)
Build the initial table from a EST_Relation.
float time(const EST_Item &item)
const T & first() const
return const reference to first item in list
ssize_t num_frames() const
return number of frames in track
EST_Token & peek(void)
peek at next token
const EST_String & string(void) const
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
void append(const T &item)
add item onto end of list
A class that offers a generalised Viterbi decoder.
int present(const K &rkey) const
Returns true if key is present.
EST_Item * append(EST_Item *si)
EST_String after(int pos, int len=1) const
Part after pos+len.
EST_String before(int pos, int len=0) const
Part before position.
#define SENTENCE_START_MARKER
int parse_command_line(int argc, char *argv[], const EST_String &usage, EST_StrList &files, EST_Option &al, int make_stdio=1)