39 Token *start_tok =
new Token(0.0, 0.0, NULL, NULL);
69 bool use_final_probs)
const {
70 fst::VectorFst<LatticeArc>
fst;
72 ShortestPath(fst, ofst);
73 return (ofst->NumStates() > 0);
79 bool use_final_probs)
const {
89 KALDI_ERR <<
"You cannot call FinalizeDecoding() and then call " 90 <<
"GetRawLattice() with use_final_probs == false";
92 unordered_map<Token*, BaseFloat> final_costs_local;
94 const unordered_map<Token*, BaseFloat> &final_costs =
100 ofst->DeleteStates();
104 unordered_map<Token*, StateId> tok_map(bucket_count);
106 for (
int32 f = 0; f <= num_frames; f++) {
108 KALDI_WARN <<
"GetRawLattice: no tokens active on frame " << f
109 <<
": not producing lattice.\n";
113 tok_map[tok] = ofst->AddState();
118 if (f == 0 && ofst->NumStates() > 0)
119 ofst->SetStart(ofst->NumStates()-1);
121 StateId cur_state = 0;
123 for (
int32 f = 0; f <= num_frames; f++) {
129 unordered_map<Token*, StateId>::const_iterator iter =
130 tok_map.find(l->next_tok);
131 StateId nextstate = iter->second;
133 Arc arc(l->ilabel, l->olabel,
134 Weight(l->graph_cost, l->acoustic_cost),
136 ofst->AddArc(cur_state, arc);
138 if (f == num_frames) {
139 if (use_final_probs && !final_costs.empty()) {
140 unordered_map<Token*, BaseFloat>::const_iterator iter =
141 final_costs.find(tok);
142 if (iter != final_costs.end())
151 return (cur_state != 0);
160 bool use_final_probs)
const {
164 if (!TopSort(&raw_fst))
165 KALDI_WARN <<
"Topological sorting of state-level lattice failed " 166 "(probably your lexicon has empty words or your LM has epsilon cycles; this " 169 fst::ILabelCompare<LatticeArc> ilabel_comp;
170 ArcSort(&raw_fst, ilabel_comp);
177 raw_fst.DeleteStates();
182 return (ofst->NumStates() != 0);
196 bool emitting,
bool *changed) {
200 unordered_map<StateId, Token*>::iterator find_iter =
cur_toks_.find(state);
207 Token *new_tok =
new Token (tot_cost, extra_cost, NULL, toks);
211 if (changed) *changed =
true;
214 Token *tok = find_iter->second;
217 if (changed) *changed =
true;
219 if (changed) *changed =
false;
229 int32 frame,
bool *extra_costs_changed,
234 *extra_costs_changed =
false;
235 *links_pruned =
false;
240 KALDI_WARN <<
"No tokens alive [doing pruning].. warning first " 241 "time only for each utterance\n";
252 BaseFloat tok_extra_cost = std::numeric_limits<BaseFloat>::infinity();
253 for (link = tok->links; link != NULL; ) {
262 if (prev_link != NULL) prev_link->
next = next_link;
263 else tok->links = next_link;
266 *links_pruned =
true;
268 if (link_extra_cost < 0.0) {
269 if (link_extra_cost < -0.01)
270 KALDI_WARN <<
"Negative extra_cost: " << link_extra_cost;
271 link_extra_cost = 0.0;
273 if (link_extra_cost < tok_extra_cost)
274 tok_extra_cost = link_extra_cost;
279 if (fabs(tok_extra_cost - tok->extra_cost) > delta)
281 tok->extra_cost = tok_extra_cost;
283 if (changed) *extra_costs_changed =
true;
293 unordered_map<Token*, BaseFloat> *final_costs,
297 if (final_costs != NULL)
298 final_costs->clear();
300 BaseFloat infinity = std::numeric_limits<BaseFloat>::infinity();
302 best_cost_with_final = infinity;
304 for (unordered_map<StateId, Token*>::const_iterator iter =
cur_toks_.begin();
307 Token *tok = iter->second;
310 cost_with_final = cost + final_cost;
311 best_cost = std::min(cost, best_cost);
312 best_cost_with_final = std::min(cost_with_final, best_cost_with_final);
313 if (final_costs != NULL && final_cost != infinity)
314 (*final_costs)[tok] = final_cost;
316 if (final_relative_cost != NULL) {
317 if (best_cost == infinity && best_cost_with_final == infinity) {
320 *final_relative_cost = infinity;
322 *final_relative_cost = best_cost_with_final - best_cost;
325 if (final_best_cost != NULL) {
326 if (best_cost_with_final != infinity) {
327 *final_best_cost = best_cost_with_final;
329 *final_best_cost = best_cost;
343 KALDI_WARN <<
"No tokens alive at end of file\n";
345 typedef unordered_map<Token*, BaseFloat>::const_iterator IterType;
361 tok != NULL; tok = tok->next) {
374 final_cost = iter->second;
376 final_cost = std::numeric_limits<BaseFloat>::infinity();
382 for (link = tok->links; link != NULL; ) {
390 if (prev_link != NULL) prev_link->
next = next_link;
391 else tok->links = next_link;
395 if (link_extra_cost < 0.0) {
396 if (link_extra_cost < -0.01)
397 KALDI_WARN <<
"Negative extra_cost: " << link_extra_cost;
398 link_extra_cost = 0.0;
400 if (link_extra_cost < tok_extra_cost)
401 tok_extra_cost = link_extra_cost;
411 tok_extra_cost = std::numeric_limits<BaseFloat>::infinity();
414 if (!
ApproxEqual(tok->extra_cost, tok_extra_cost, delta))
416 tok->extra_cost = tok_extra_cost;
425 return relative_cost;
440 KALDI_WARN <<
"No tokens alive [doing pruning]";
441 Token *tok, *next_tok, *prev_tok = NULL;
442 for (tok = toks; tok != NULL; tok = next_tok) {
443 next_tok = tok->
next;
444 if (tok->
extra_cost == std::numeric_limits<BaseFloat>::infinity()) {
447 if (prev_tok != NULL) prev_tok->
next = tok->
next;
448 else toks = tok->
next;
467 for (
int32 f = cur_frame_plus_one - 1; f >= 0; f--) {
473 bool extra_costs_changed =
false, links_pruned =
false;
475 if (extra_costs_changed && f > 0)
481 if (f+1 < cur_frame_plus_one &&
487 KALDI_VLOG(3) <<
"PruneActiveTokens: pruned tokens from " << num_toks_begin
499 for (
int32 f = final_frame_plus_one - 1; f >= 0; f--) {
506 KALDI_VLOG(3) <<
"pruned tokens from " << num_toks_begin
520 BaseFloat cutoff = std::numeric_limits<BaseFloat>::infinity();
521 for (unordered_map<StateId, Token*>::iterator iter =
prev_toks_.begin();
525 Token *tok = iter->second;
526 for (fst::ArcIterator<fst::Fst<Arc> > aiter(
fst_, state);
529 const Arc &arc = aiter.Value();
530 if (arc.ilabel != 0) {
532 graph_cost = arc.weight.Value(),
534 tot_cost = cur_cost + ac_cost + graph_cost;
535 if (tot_cost >= cutoff)
continue;
544 graph_cost, ac_cost, tok->
links);
562 std::vector<StateId> queue;
563 BaseFloat best_cost = std::numeric_limits<BaseFloat>::infinity();
564 for (unordered_map<StateId, Token*>::iterator iter =
cur_toks_.begin();
568 if (
fst_.NumInputEpsilons(state) != 0)
569 queue.push_back(state);
570 best_cost = std::min(best_cost, iter->second->tot_cost);
574 KALDI_ERR <<
"Error in ProcessEmitting: no surviving tokens: frame is " 581 while (!queue.empty()) {
591 for (fst::ArcIterator<fst::Fst<Arc> > aiter(
fst_, state);
594 const Arc &arc = aiter.Value();
595 if (arc.ilabel == 0) {
596 BaseFloat graph_cost = arc.weight.Value(),
598 tot_cost = cur_cost + graph_cost;
599 if (tot_cost < cutoff) {
605 graph_cost, 0, tok->
links);
609 if (changed &&
fst_.NumInputEpsilons(arc.nextstate) != 0)
610 queue.push_back(arc.nextstate);
622 tok->DeleteForwardLinks();
642 for (unordered_map<StateId, Token*>::iterator iter = toks->begin();
643 iter != toks->end(); ++iter) {
646 static_cast<BaseFloat>(iter->second->tot_cost));
648 std::vector<StateId> retained;
650 for (unordered_map<StateId, Token*>::iterator iter = toks->begin();
651 iter != toks->end(); ++iter) {
652 if (iter->second->tot_cost < cutoff)
653 retained.push_back(iter->first);
655 unordered_map<StateId, Token*> tmp;
656 for (
size_t i = 0;
i < retained.size();
i++) {
657 tmp[retained[
i]] = (*toks)[retained[
i]];
659 KALDI_VLOG(2) <<
"Pruned to "<<(retained.size())<<
" toks.\n";
fst::StdArc::StateId StateId
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
fst::ArcTpl< LatticeWeight > LatticeArc
std::vector< TokenList > active_toks_
void InitDecoding()
InitDecoding initializes the decoding, and should only be used if you intend to call AdvanceDecoding(...
LatticeSimpleDecoderConfig config_
DecodableInterface provides a link between the (acoustic-modeling and feature-processing) code and th...
int32 NumFramesDecoded() const
BaseFloat final_relative_cost_
static const LatticeWeightTpl One()
bool DeterminizeLatticePruned(const ExpandedFst< ArcTpl< Weight > > &ifst, double beam, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePrunedOptions opts)
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
BaseFloat final_best_cost_
bool GetLattice(CompactLattice *clat, bool use_final_probs=true) const
bool Decode(DecodableInterface *decodable)
virtual bool IsLastFrame(int32 frame) const =0
Returns true if this is the last frame.
bool decoding_finalized_
decoding_finalized_ is true if someone called FinalizeDecoding().
unordered_map< Token *, BaseFloat > final_costs_
For the meaning of the next 3 variables, see the comment for decoding_finalized_ above., and ComputeFinalCosts().
void FinalizeDecoding()
This function may be optionally called after AdvanceDecoding(), when you do not plan to decode any fu...
void PruneCurrentTokens(BaseFloat beam, unordered_map< StateId, Token *> *toks)
BaseFloat FinalRelativeCost() const
FinalRelativeCost() serves the same purpose as ReachedFinal(), but gives more information.
bool GetRawLattice(Lattice *lat, bool use_final_probs=true) const
void PruneActiveTokens(BaseFloat delta)
void ComputeFinalCosts(unordered_map< Token *, BaseFloat > *final_costs, BaseFloat *final_relative_cost, BaseFloat *final_best_cost) const
void DeleteForwardLinks()
void PruneForwardLinks(int32 frame, bool *extra_costs_changed, bool *links_pruned, BaseFloat delta)
Token * FindOrAddToken(StateId state, int32 frame_plus_one, BaseFloat tot_cost, bool emitting, bool *changed)
unordered_map< StateId, Token * > prev_toks_
void ProcessNonemitting()
const fst::Fst< fst::StdArc > & fst_
fst::VectorFst< LatticeArc > Lattice
void PruneForwardLinksFinal()
fst::VectorFst< CompactLatticeArc > CompactLattice
void ProcessEmitting(DecodableInterface *decodable)
fst::StdArc::Weight Weight
#define KALDI_ASSERT(cond)
bool GetBestPath(Lattice *lat, bool use_final_probs=true) const
unordered_map< StateId, Token * > cur_toks_
fst::DeterminizeLatticePhonePrunedOptions det_opts
virtual BaseFloat LogLikelihood(int32 frame, int32 index)=0
Returns the log likelihood, which will be negated in the decoder.
static bool ApproxEqual(float a, float b, float relative_tolerance=0.001)
return abs(a - b) <= relative_tolerance * (abs(a)+abs(b)).
void PruneTokensForFrame(int32 frame)