All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages

#include <transition-model.h>

Collaboration diagram for TransitionModel:

Classes

struct  Tuple
 

Public Member Functions

 TransitionModel (const ContextDependencyInterface &ctx_dep, const HmmTopology &hmm_topo)
 Initialize the object [e.g. More...
 
 TransitionModel ()
 Constructor that takes no arguments: typically used prior to calling Read. More...
 
void Read (std::istream &is, bool binary)
 
void Write (std::ostream &os, bool binary) const
 
const HmmTopologyGetTopo () const
 return reference to HMM-topology object. More...
 
bool IsFinal (int32 trans_id) const
 
bool IsSelfLoop (int32 trans_id) const
 
int32 NumTransitionIds () const
 Returns the total number of transition-ids (note, these are one-based). More...
 
int32 NumTransitionIndices (int32 trans_state) const
 Returns the number of transition-indices for a particular transition-state. More...
 
int32 NumTransitionStates () const
 Returns the total number of transition-states (note, these are one-based). More...
 
int32 NumPdfs () const
 
int32 NumPhones () const
 
const std::vector< int32 > & GetPhones () const
 Returns a sorted, unique list of phones. More...
 
BaseFloat GetTransitionProb (int32 trans_id) const
 
BaseFloat GetTransitionLogProb (int32 trans_id) const
 
BaseFloat GetTransitionLogProbIgnoringSelfLoops (int32 trans_id) const
 Returns the log-probability of a particular non-self-loop transition after subtracting the probability mass of the self-loop and renormalizing; will crash if called on a self-loop. More...
 
BaseFloat GetNonSelfLoopLogProb (int32 trans_state) const
 Returns the log-prob of the non-self-loop probability mass for this transition state. More...
 
void MleUpdate (const Vector< double > &stats, const MleTransitionUpdateConfig &cfg, BaseFloat *objf_impr_out, BaseFloat *count_out)
 Does Maximum Likelihood estimation. More...
 
void MapUpdate (const Vector< double > &stats, const MapTransitionUpdateConfig &cfg, BaseFloat *objf_impr_out, BaseFloat *count_out)
 Does Maximum A Posteriori (MAP) estimation. More...
 
void Print (std::ostream &os, const std::vector< std::string > &phone_names, const Vector< double > *occs=NULL)
 Print will print the transition model in a human-readable way, for purposes of human inspection. More...
 
void InitStats (Vector< double > *stats) const
 
void Accumulate (BaseFloat prob, int32 trans_id, Vector< double > *stats) const
 
bool Compatible (const TransitionModel &other) const
 returns true if all the integer class members are identical (but does not compare the transition probabilities. More...
 
Integer mapping functions
int32 TupleToTransitionState (int32 phone, int32 hmm_state, int32 pdf, int32 self_loop_pdf) const
 
int32 PairToTransitionId (int32 trans_state, int32 trans_index) const
 
int32 TransitionIdToTransitionState (int32 trans_id) const
 
int32 TransitionIdToTransitionIndex (int32 trans_id) const
 
int32 TransitionStateToPhone (int32 trans_state) const
 
int32 TransitionStateToHmmState (int32 trans_state) const
 
int32 TransitionStateToForwardPdfClass (int32 trans_state) const
 
int32 TransitionStateToSelfLoopPdfClass (int32 trans_state) const
 
int32 TransitionStateToForwardPdf (int32 trans_state) const
 
int32 TransitionStateToSelfLoopPdf (int32 trans_state) const
 
int32 SelfLoopOf (int32 trans_state) const
 
int32 TransitionIdToPdf (int32 trans_id) const
 
int32 TransitionIdToPhone (int32 trans_id) const
 
int32 TransitionIdToPdfClass (int32 trans_id) const
 
int32 TransitionIdToHmmState (int32 trans_id) const
 

Private Member Functions

void MleUpdateShared (const Vector< double > &stats, const MleTransitionUpdateConfig &cfg, BaseFloat *objf_impr_out, BaseFloat *count_out)
 This version of the Update() function is for if the user specifies –share-for-pdfs=true. More...
 
void MapUpdateShared (const Vector< double > &stats, const MapTransitionUpdateConfig &cfg, BaseFloat *objf_impr_out, BaseFloat *count_out)
 This version of the MapUpdate() function is for if the user specifies –share-for-pdfs=true. More...
 
void ComputeTuples (const ContextDependencyInterface &ctx_dep)
 
void ComputeTuplesIsHmm (const ContextDependencyInterface &ctx_dep)
 
void ComputeTuplesNotHmm (const ContextDependencyInterface &ctx_dep)
 
void ComputeDerived ()
 
void ComputeDerivedOfProbs ()
 
void InitializeProbs ()
 
void Check () const
 
bool IsHmm () const
 
 DISALLOW_COPY_AND_ASSIGN (TransitionModel)
 

Private Attributes

HmmTopology topo_
 
std::vector< Tupletuples_
 Triples indexed by transition state minus one; the triples are in sorted order which allows us to do the reverse mapping from triple to transition state. More...
 
std::vector< int32 > state2id_
 Gives the first transition_id of each transition-state; indexed by the transition-state. More...
 
std::vector< int32 > id2state_
 For each transition-id, the corresponding transition state (indexed by transition-id). More...
 
std::vector< int32 > id2pdf_id_
 
Vector< BaseFloatlog_probs_
 For each transition-id, the corresponding log-prob. Indexed by transition-id. More...
 
Vector< BaseFloatnon_self_loop_log_probs_
 For each transition-state, the log of (1 - self-loop-prob). More...
 
int32 num_pdfs_
 This is actually one plus the highest-numbered pdf we ever got back from the tree (but the tree numbers pdfs contiguously from zero so this is the number of pdfs). More...
 

Detailed Description

Definition at line 122 of file transition-model.h.

Constructor & Destructor Documentation

TransitionModel ( const ContextDependencyInterface ctx_dep,
const HmmTopology hmm_topo 
)

Initialize the object [e.g.

at the start of training]. The class keeps a copy of the HmmTopology object, but not the ContextDependency object.

Definition at line 234 of file transition-model.cc.

References TransitionModel::Check(), TransitionModel::ComputeDerived(), TransitionModel::ComputeTuples(), and TransitionModel::InitializeProbs().

235  : topo_(hmm_topo) {
236  // First thing is to get all possible tuples.
237  ComputeTuples(ctx_dep);
238  ComputeDerived();
239  InitializeProbs();
240  Check();
241 }
void ComputeTuples(const ContextDependencyInterface &ctx_dep)
TransitionModel ( )
inline

Constructor that takes no arguments: typically used prior to calling Read.

Definition at line 133 of file transition-model.h.

133 { }

Member Function Documentation

void Accumulate ( BaseFloat  prob,
int32  trans_id,
Vector< double > *  stats 
) const
inline

Definition at line 238 of file transition-model.h.

References KALDI_ASSERT, and TransitionModel::NumTransitionIds().

Referenced by main().

238  {
239  KALDI_ASSERT(trans_id <= NumTransitionIds());
240  (*stats)(trans_id) += prob;
241  // This is trivial and doesn't require class members, but leaves us more open
242  // to design changes than doing it manually.
243  }
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void Check ( ) const
private

Definition at line 198 of file transition-model.cc.

References KALDI_ASSERT, TransitionModel::log_probs_, TransitionModel::NumTransitionIds(), TransitionModel::NumTransitionIndices(), TransitionModel::NumTransitionStates(), TransitionModel::PairToTransitionId(), TransitionModel::TransitionIdToTransitionIndex(), TransitionModel::TransitionIdToTransitionState(), TransitionModel::TransitionStateToForwardPdf(), TransitionModel::TransitionStateToHmmState(), TransitionModel::TransitionStateToPhone(), TransitionModel::TransitionStateToSelfLoopPdf(), and TransitionModel::TupleToTransitionState().

Referenced by TransitionModel::Read(), and TransitionModel::TransitionModel().

198  {
200  {
201  int32 sum = 0;
202  for (int32 ts = 1; ts <= NumTransitionStates(); ts++) sum += NumTransitionIndices(ts);
203  KALDI_ASSERT(sum == NumTransitionIds());
204  }
205  for (int32 tid = 1; tid <= NumTransitionIds(); tid++) {
206  int32 tstate = TransitionIdToTransitionState(tid),
207  index = TransitionIdToTransitionIndex(tid);
208  KALDI_ASSERT(tstate > 0 && tstate <=NumTransitionStates() && index >= 0);
209  KALDI_ASSERT(tid == PairToTransitionId(tstate, index));
210  int32 phone = TransitionStateToPhone(tstate),
211  hmm_state = TransitionStateToHmmState(tstate),
212  forward_pdf = TransitionStateToForwardPdf(tstate),
213  self_loop_pdf = TransitionStateToSelfLoopPdf(tstate);
214  KALDI_ASSERT(tstate == TupleToTransitionState(phone, hmm_state, forward_pdf, self_loop_pdf));
215  KALDI_ASSERT(log_probs_(tid) <= 0.0 && log_probs_(tid) - log_probs_(tid) == 0.0);
216  // checking finite and non-positive (and not out-of-bounds).
217  }
218 }
int32 TransitionStateToPhone(int32 trans_state) const
int32 TupleToTransitionState(int32 phone, int32 hmm_state, int32 pdf, int32 self_loop_pdf) const
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
int32 TransitionStateToHmmState(int32 trans_state) const
int32 TransitionIdToTransitionIndex(int32 trans_id) const
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
int32 TransitionStateToForwardPdf(int32 trans_state) const
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToSelfLoopPdf(int32 trans_state) const
int32 TransitionIdToTransitionState(int32 trans_id) const
bool Compatible ( const TransitionModel other) const

returns true if all the integer class members are identical (but does not compare the transition probabilities.

Definition at line 895 of file transition-model.cc.

References TransitionModel::id2state_, TransitionModel::num_pdfs_, TransitionModel::state2id_, TransitionModel::topo_, and TransitionModel::tuples_.

Referenced by kaldi::TestTransitionModel().

895  {
896  return (topo_ == other.topo_ && tuples_ == other.tuples_ &&
897  state2id_ == other.state2id_ && id2state_ == other.id2state_
898  && num_pdfs_ == other.num_pdfs_);
899 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
int32 num_pdfs_
This is actually one plus the highest-numbered pdf we ever got back from the tree (but the tree numbe...
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
void ComputeDerived ( )
private

Definition at line 144 of file transition-model.cc.

References TransitionModel::id2pdf_id_, TransitionModel::id2state_, TransitionModel::IsSelfLoop(), TransitionModel::num_pdfs_, TransitionModel::state2id_, TransitionModel::topo_, HmmTopology::TopologyForPhone(), HmmTopology::HmmState::transitions, and TransitionModel::tuples_.

Referenced by TransitionModel::Read(), and TransitionModel::TransitionModel().

144  {
145  state2id_.resize(tuples_.size()+2); // indexed by transition-state, which
146  // is one based, but also an entry for one past end of list.
147 
148  int32 cur_transition_id = 1;
149  num_pdfs_ = 0;
150  for (int32 tstate = 1;
151  tstate <= static_cast<int32>(tuples_.size()+1); // not a typo.
152  tstate++) {
153  state2id_[tstate] = cur_transition_id;
154  if (static_cast<size_t>(tstate) <= tuples_.size()) {
155  int32 phone = tuples_[tstate-1].phone,
156  hmm_state = tuples_[tstate-1].hmm_state,
157  forward_pdf = tuples_[tstate-1].forward_pdf,
158  self_loop_pdf = tuples_[tstate-1].self_loop_pdf;
159  num_pdfs_ = std::max(num_pdfs_, 1 + forward_pdf);
160  num_pdfs_ = std::max(num_pdfs_, 1 + self_loop_pdf);
161  const HmmTopology::HmmState &state = topo_.TopologyForPhone(phone)[hmm_state];
162  int32 my_num_ids = static_cast<int32>(state.transitions.size());
163  cur_transition_id += my_num_ids; // # trans out of this state.
164  }
165  }
166 
167  id2state_.resize(cur_transition_id); // cur_transition_id is #transition-ids+1.
168  id2pdf_id_.resize(cur_transition_id);
169  for (int32 tstate = 1; tstate <= static_cast<int32>(tuples_.size()); tstate++)
170  for (int32 tid = state2id_[tstate]; tid < state2id_[tstate+1]; tid++) {
171  id2state_[tid] = tstate;
172  if (IsSelfLoop(tid))
173  id2pdf_id_[tid] = tuples_[tstate-1].self_loop_pdf;
174  else
175  id2pdf_id_[tid] = tuples_[tstate-1].forward_pdf;
176  }
177 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
std::vector< int32 > id2pdf_id_
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
int32 num_pdfs_
This is actually one plus the highest-numbered pdf we ever got back from the tree (but the tree numbe...
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
bool IsSelfLoop(int32 trans_id) const
void ComputeDerivedOfProbs ( )
private

Definition at line 364 of file transition-model.cc.

References kaldi::Exp(), TransitionModel::GetTransitionLogProb(), KALDI_WARN, kaldi::Log(), TransitionModel::non_self_loop_log_probs_, TransitionModel::NumTransitionStates(), Vector< Real >::Resize(), and TransitionModel::SelfLoopOf().

Referenced by TransitionModel::InitializeProbs(), TransitionModel::MapUpdate(), TransitionModel::MapUpdateShared(), TransitionModel::MleUpdate(), TransitionModel::MleUpdateShared(), and TransitionModel::Read().

364  {
365  non_self_loop_log_probs_.Resize(NumTransitionStates()+1); // this array indexed
366  // by transition-state with nothing in zeroth element.
367  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
368  int32 tid = SelfLoopOf(tstate);
369  if (tid == 0) { // no self-loop
370  non_self_loop_log_probs_(tstate) = 0.0; // log(1.0)
371  } else {
372  BaseFloat self_loop_prob = Exp(GetTransitionLogProb(tid)),
373  non_self_loop_prob = 1.0 - self_loop_prob;
374  if (non_self_loop_prob <= 0.0) {
375  KALDI_WARN << "ComputeDerivedOfProbs(): non-self-loop prob is " << non_self_loop_prob;
376  non_self_loop_prob = 1.0e-10; // just so we can continue...
377  }
378  non_self_loop_log_probs_(tstate) = Log(non_self_loop_prob); // will be negative.
379  }
380  }
381 }
double Exp(double x)
Definition: kaldi-math.h:83
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
#define KALDI_WARN
Definition: kaldi-error.h:130
BaseFloat GetTransitionLogProb(int32 trans_id) const
int32 SelfLoopOf(int32 trans_state) const
Vector< BaseFloat > non_self_loop_log_probs_
For each transition-state, the log of (1 - self-loop-prob).
void ComputeTuples ( const ContextDependencyInterface ctx_dep)
private

Definition at line 27 of file transition-model.cc.

References TransitionModel::ComputeTuplesIsHmm(), TransitionModel::ComputeTuplesNotHmm(), TransitionModel::IsHmm(), and TransitionModel::tuples_.

Referenced by TransitionModel::TransitionModel().

27  {
28  if (IsHmm())
29  ComputeTuplesIsHmm(ctx_dep);
30  else
31  ComputeTuplesNotHmm(ctx_dep);
32 
33  // now tuples_ is populated with all possible tuples of (phone, hmm_state, pdf, self_loop_pdf).
34  std::sort(tuples_.begin(), tuples_.end()); // sort to enable reverse lookup.
35  // this sorting defines the transition-ids.
36 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
void ComputeTuplesNotHmm(const ContextDependencyInterface &ctx_dep)
void ComputeTuplesIsHmm(const ContextDependencyInterface &ctx_dep)
void ComputeTuplesIsHmm ( const ContextDependencyInterface ctx_dep)
private

Definition at line 38 of file transition-model.cc.

References ContextDependencyInterface::GetPdfInfo(), HmmTopology::GetPhones(), rnnlm::i, rnnlm::j, KALDI_ASSERT, kaldi::kNoPdf, HmmTopology::NumPdfClasses(), TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by TransitionModel::ComputeTuples().

38  {
39  const std::vector<int32> &phones = topo_.GetPhones();
40  KALDI_ASSERT(!phones.empty());
41 
42  // this is the case for normal models. but not fot chain models
43  std::vector<std::vector<std::pair<int32, int32> > > pdf_info;
44  std::vector<int32> num_pdf_classes( 1 + *std::max_element(phones.begin(), phones.end()), -1);
45  for (size_t i = 0; i < phones.size(); i++)
46  num_pdf_classes[phones[i]] = topo_.NumPdfClasses(phones[i]);
47  ctx_dep.GetPdfInfo(phones, num_pdf_classes, &pdf_info);
48  // pdf_info is list indexed by pdf of which (phone, pdf_class) it
49  // can correspond to.
50 
51  std::map<std::pair<int32, int32>, std::vector<int32> > to_hmm_state_list;
52  // to_hmm_state_list is a map from (phone, pdf_class) to the list
53  // of hmm-states in the HMM for that phone that that (phone, pdf-class)
54  // can correspond to.
55  for (size_t i = 0; i < phones.size(); i++) { // setting up to_hmm_state_list.
56  int32 phone = phones[i];
58  for (int32 j = 0; j < static_cast<int32>(entry.size()); j++) { // for each state...
59  int32 pdf_class = entry[j].forward_pdf_class;
60  if (pdf_class != kNoPdf) {
61  to_hmm_state_list[std::make_pair(phone, pdf_class)].push_back(j);
62  }
63  }
64  }
65 
66  for (int32 pdf = 0; pdf < static_cast<int32>(pdf_info.size()); pdf++) {
67  for (size_t j = 0; j < pdf_info[pdf].size(); j++) {
68  int32 phone = pdf_info[pdf][j].first,
69  pdf_class = pdf_info[pdf][j].second;
70  const std::vector<int32> &state_vec = to_hmm_state_list[std::make_pair(phone, pdf_class)];
71  KALDI_ASSERT(!state_vec.empty());
72  // state_vec is a list of the possible HMM-states that emit this
73  // pdf_class.
74  for (size_t k = 0; k < state_vec.size(); k++) {
75  int32 hmm_state = state_vec[k];
76  tuples_.push_back(Tuple(phone, hmm_state, pdf, pdf));
77  }
78  }
79  }
80 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
static const int32 kNoPdf
A constant used in the HmmTopology class as the pdf-class kNoPdf, which is used when a HMM-state is n...
Definition: hmm-topology.h:87
int32 NumPdfClasses(int32 phone) const
Returns the number of pdf-classes for this phone; throws exception if phone not covered by this topol...
const std::vector< int32 > & GetPhones() const
Returns a reference to a sorted, unique list of phones covered by the topology (these phones will be ...
Definition: hmm-topology.h:164
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeTuplesNotHmm ( const ContextDependencyInterface ctx_dep)
private

Definition at line 82 of file transition-model.cc.

References ContextDependencyInterface::GetPdfInfo(), HmmTopology::GetPhones(), rnnlm::i, rnnlm::j, KALDI_ASSERT, kaldi::kNoPdf, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by TransitionModel::ComputeTuples().

82  {
83  const std::vector<int32> &phones = topo_.GetPhones();
84  KALDI_ASSERT(!phones.empty());
85 
86  // pdf_info is a set of lists indexed by phone. Each list is indexed by
87  // (pdf-class, self-loop pdf-class) of each state of that phone, and the element
88  // is a list of possible (pdf, self-loop pdf) pairs that that (pdf-class, self-loop pdf-class)
89  // pair generates.
90  std::vector<std::vector<std::vector<std::pair<int32, int32> > > > pdf_info;
91  // pdf_class_pairs is a set of lists indexed by phone. Each list stores
92  // (pdf-class, self-loop pdf-class) of each state of that phone.
93  std::vector<std::vector<std::pair<int32, int32> > > pdf_class_pairs;
94  pdf_class_pairs.resize(1 + *std::max_element(phones.begin(), phones.end()));
95  for (size_t i = 0; i < phones.size(); i++) {
96  int32 phone = phones[i];
98  for (int32 j = 0; j < static_cast<int32>(entry.size()); j++) { // for each state...
99  int32 forward_pdf_class = entry[j].forward_pdf_class, self_loop_pdf_class = entry[j].self_loop_pdf_class;
100  if (forward_pdf_class != kNoPdf)
101  pdf_class_pairs[phone].push_back(std::make_pair(forward_pdf_class, self_loop_pdf_class));
102  }
103  }
104  ctx_dep.GetPdfInfo(phones, pdf_class_pairs, &pdf_info);
105 
106  std::vector<std::map<std::pair<int32, int32>, std::vector<int32> > > to_hmm_state_list;
107  to_hmm_state_list.resize(1 + *std::max_element(phones.begin(), phones.end()));
108  // to_hmm_state_list is a phone-indexed set of maps from (pdf-class, self-loop pdf_class) to the list
109  // of hmm-states in the HMM for that phone that that (pdf-class, self-loop pdf-class)
110  // can correspond to.
111  for (size_t i = 0; i < phones.size(); i++) { // setting up to_hmm_state_list.
112  int32 phone = phones[i];
113  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
114  std::map<std::pair<int32, int32>, std::vector<int32> > phone_to_hmm_state_list;
115  for (int32 j = 0; j < static_cast<int32>(entry.size()); j++) { // for each state...
116  int32 forward_pdf_class = entry[j].forward_pdf_class, self_loop_pdf_class = entry[j].self_loop_pdf_class;
117  if (forward_pdf_class != kNoPdf) {
118  phone_to_hmm_state_list[std::make_pair(forward_pdf_class, self_loop_pdf_class)].push_back(j);
119  }
120  }
121  to_hmm_state_list[phone] = phone_to_hmm_state_list;
122  }
123 
124  for (int32 i = 0; i < phones.size(); i++) {
125  int32 phone = phones[i];
126  for (int32 j = 0; j < static_cast<int32>(pdf_info[phone].size()); j++) {
127  int32 pdf_class = pdf_class_pairs[phone][j].first,
128  self_loop_pdf_class = pdf_class_pairs[phone][j].second;
129  const std::vector<int32> &state_vec =
130  to_hmm_state_list[phone][std::make_pair(pdf_class, self_loop_pdf_class)];
131  KALDI_ASSERT(!state_vec.empty());
132  for (size_t k = 0; k < state_vec.size(); k++) {
133  int32 hmm_state = state_vec[k];
134  for (size_t m = 0; m < pdf_info[phone][j].size(); m++) {
135  int32 pdf = pdf_info[phone][j][m].first,
136  self_loop_pdf = pdf_info[phone][j][m].second;
137  tuples_.push_back(Tuple(phone, hmm_state, pdf, self_loop_pdf));
138  }
139  }
140  }
141  }
142 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
static const int32 kNoPdf
A constant used in the HmmTopology class as the pdf-class kNoPdf, which is used when a HMM-state is n...
Definition: hmm-topology.h:87
const std::vector< int32 > & GetPhones() const
Returns a reference to a sorted, unique list of phones covered by the topology (these phones will be ...
Definition: hmm-topology.h:164
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
DISALLOW_COPY_AND_ASSIGN ( TransitionModel  )
private
BaseFloat GetNonSelfLoopLogProb ( int32  trans_state) const

Returns the log-prob of the non-self-loop probability mass for this transition state.

(you can get the self-loop prob, if a self-loop exists, by calling GetTransitionLogProb(SelfLoopOf(trans_state)).

Definition at line 452 of file transition-model.cc.

References KALDI_ASSERT, and TransitionModel::non_self_loop_log_probs_.

Referenced by kaldi::AddSelfLoopsAfter(), kaldi::AddSelfLoopsBefore(), kaldi::GetScaledTransitionLogProb(), and TransitionModel::GetTransitionLogProbIgnoringSelfLoops().

452  {
453  KALDI_ASSERT(trans_state != 0);
454  return non_self_loop_log_probs_(trans_state);
455 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
Vector< BaseFloat > non_self_loop_log_probs_
For each transition-state, the log of (1 - self-loop-prob).
const std::vector<int32>& GetPhones ( ) const
inline

Returns a sorted, unique list of phones.

Definition at line 194 of file transition-model.h.

References HmmTopology::GetPhones(), and TransitionModel::topo_.

Referenced by TrainingGraphCompiler::CompileGraph(), TrainingGraphCompiler::CompileGraphs(), kaldi::GetHTransducer(), main(), kaldi::TestSplitToPhones(), kaldi::TestWordAlignLatticeLexicon(), and TrainingGraphCompiler::TrainingGraphCompiler().

194 { return topo_.GetPhones(); }
const std::vector< int32 > & GetPhones() const
Returns a reference to a sorted, unique list of phones covered by the topology (these phones will be ...
Definition: hmm-topology.h:164
BaseFloat GetTransitionLogProb ( int32  trans_id) const

Definition at line 448 of file transition-model.cc.

References TransitionModel::log_probs_.

Referenced by kaldi::AddSelfLoopsAfter(), kaldi::AddSelfLoopsBefore(), TransitionModel::ComputeDerivedOfProbs(), kaldi::GetHmmAsFstSimple(), and kaldi::GetScaledTransitionLogProb().

448  {
449  return log_probs_(trans_id);
450 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
BaseFloat GetTransitionLogProbIgnoringSelfLoops ( int32  trans_id) const

Returns the log-probability of a particular non-self-loop transition after subtracting the probability mass of the self-loop and renormalizing; will crash if called on a self-loop.

Specifically: for non-self-loops it returns the log of (that prob divided by (1 minus self-loop-prob-for-that-state)).

Definition at line 457 of file transition-model.cc.

References TransitionModel::GetNonSelfLoopLogProb(), TransitionModel::IsSelfLoop(), KALDI_ASSERT, KALDI_PARANOID_ASSERT, TransitionModel::log_probs_, and TransitionModel::TransitionIdToTransitionState().

Referenced by kaldi::GetHmmAsFst(), and kaldi::GetScaledTransitionLogProb().

457  {
458  KALDI_ASSERT(trans_id != 0);
459  KALDI_PARANOID_ASSERT(!IsSelfLoop(trans_id));
460  return log_probs_(trans_id) - GetNonSelfLoopLogProb(TransitionIdToTransitionState(trans_id));
461 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
#define KALDI_PARANOID_ASSERT(cond)
Definition: kaldi-error.h:182
bool IsSelfLoop(int32 trans_id) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionIdToTransitionState(int32 trans_id) const
BaseFloat GetNonSelfLoopLogProb(int32 trans_state) const
Returns the log-prob of the non-self-loop probability mass for this transition state.
BaseFloat GetTransitionProb ( int32  trans_id) const

Definition at line 444 of file transition-model.cc.

References kaldi::Exp(), and TransitionModel::log_probs_.

Referenced by TransitionModel::MapUpdate(), TransitionModel::MapUpdateShared(), TransitionModel::MleUpdate(), TransitionModel::MleUpdateShared(), and TransitionModel::Print().

444  {
445  return Exp(log_probs_(trans_id));
446 }
double Exp(double x)
Definition: kaldi-math.h:83
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
void InitializeProbs ( )
private

Definition at line 179 of file transition-model.cc.

References TransitionModel::ComputeDerivedOfProbs(), TransitionModel::Tuple::hmm_state, TransitionModel::id2state_, KALDI_ASSERT, KALDI_ERR, KALDI_WARN, kaldi::Log(), TransitionModel::log_probs_, TransitionModel::NumTransitionIds(), TransitionModel::Tuple::phone, Vector< Real >::Resize(), TransitionModel::state2id_, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by TransitionModel::TransitionModel().

179  {
180  log_probs_.Resize(NumTransitionIds()+1); // one-based array, zeroth element empty.
181  for (int32 trans_id = 1; trans_id <= NumTransitionIds(); trans_id++) {
182  int32 trans_state = id2state_[trans_id];
183  int32 trans_index = trans_id - state2id_[trans_state];
184  const Tuple &tuple = tuples_[trans_state-1];
185  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(tuple.phone);
186  KALDI_ASSERT(static_cast<size_t>(tuple.hmm_state) < entry.size());
187  BaseFloat prob = entry[tuple.hmm_state].transitions[trans_index].second;
188  if (prob <= 0.0)
189  KALDI_ERR << "TransitionModel::InitializeProbs, zero "
190  "probability [should remove that entry in the topology]";
191  if (prob > 1.0)
192  KALDI_WARN << "TransitionModel::InitializeProbs, prob greater than one.";
193  log_probs_(trans_id) = Log(prob);
194  }
196 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_WARN
Definition: kaldi-error.h:130
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void InitStats ( Vector< double > *  stats) const
inline

Definition at line 236 of file transition-model.h.

References TransitionModel::NumTransitionIds(), and Vector< Real >::Resize().

Referenced by main().

236 { stats->Resize(NumTransitionIds()+1); }
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
bool IsFinal ( int32  trans_id) const

Definition at line 331 of file transition-model.cc.

References TransitionModel::Tuple::hmm_state, TransitionModel::id2state_, KALDI_ASSERT, TransitionModel::Tuple::phone, TransitionModel::state2id_, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by kaldi::ConvertCompactLatticeToPhones(), kaldi::IsPlausibleWord(), LatticePhoneAligner::ComputationState::OutputArcForce(), LatticeWordAligner::ComputationState::OutputArcForce(), LatticeWordAligner::ComputationState::OutputNormalWordArc(), LatticeWordAligner::ComputationState::OutputOnePhoneWordArc(), LatticePhoneAligner::ComputationState::OutputPhoneArc(), ArcPosteriorComputer::OutputPosteriors(), LatticeWordAligner::ComputationState::OutputSilenceArc(), kaldi::SplitToPhonesInternal(), WordAlignedLatticeTester::TestArcNormalWord(), WordAlignedLatticeTester::TestArcOnePhoneWord(), and WordAlignedLatticeTester::TestArcSilence().

331  {
332  KALDI_ASSERT(static_cast<size_t>(trans_id) < id2state_.size());
333  int32 trans_state = id2state_[trans_id];
334  int32 trans_index = trans_id - state2id_[trans_state];
335  const Tuple &tuple = tuples_[trans_state-1];
336  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(tuple.phone);
337  KALDI_ASSERT(static_cast<size_t>(tuple.hmm_state) < entry.size());
338  KALDI_ASSERT(static_cast<size_t>(tuple.hmm_state) < entry.size());
339  KALDI_ASSERT(static_cast<size_t>(trans_index) <
340  entry[tuple.hmm_state].transitions.size());
341  // return true if the transition goes to the final state of the
342  // topology entry.
343  return (entry[tuple.hmm_state].transitions[trans_index].first + 1 ==
344  static_cast<int32>(entry.size()));
345 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool IsHmm ( ) const
private

Definition at line 220 of file transition-model.cc.

References HmmTopology::GetPhones(), rnnlm::i, rnnlm::j, KALDI_ASSERT, TransitionModel::topo_, and HmmTopology::TopologyForPhone().

Referenced by TransitionModel::ComputeTuples(), TransitionModel::MapUpdateShared(), TransitionModel::MleUpdateShared(), TransitionModel::Print(), and TransitionModel::Write().

220  {
221  const std::vector<int32> &phones = topo_.GetPhones();
222  KALDI_ASSERT(!phones.empty());
223  for (size_t i = 0; i < phones.size(); i++) {
224  int32 phone = phones[i];
225  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
226  for (int32 j = 0; j < static_cast<int32>(entry.size()); j++) { // for each state...
227  if (entry[j].forward_pdf_class != entry[j].self_loop_pdf_class)
228  return false;
229  }
230  }
231  return true;
232 }
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
const std::vector< int32 > & GetPhones() const
Returns a reference to a sorted, unique list of phones covered by the topology (these phones will be ...
Definition: hmm-topology.h:164
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool IsSelfLoop ( int32  trans_id) const

Definition at line 901 of file transition-model.cc.

References TransitionModel::Tuple::hmm_state, TransitionModel::id2state_, KALDI_ASSERT, TransitionModel::Tuple::phone, TransitionModel::state2id_, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by kaldi::ChangeReorderingOfAlignment(), TransitionModel::ComputeDerived(), kaldi::ConvertLatticeToPhones(), fst::DeterminizeLatticeInsertPhones(), kaldi::GetScaledTransitionLogProb(), TransitionModel::GetTransitionLogProbIgnoringSelfLoops(), kaldi::IsPlausibleWord(), kaldi::IsReordered(), TidToTstateMapper::operator()(), LatticeWordAligner::ComputationState::OutputArcForce(), LatticeWordAligner::ComputationState::OutputNormalWordArc(), LatticeWordAligner::ComputationState::OutputOnePhoneWordArc(), LatticePhoneAligner::ComputationState::OutputPhoneArc(), LatticeWordAligner::ComputationState::OutputSilenceArc(), TransitionModel::Print(), kaldi::SplitToPhonesInternal(), WordAlignedLatticeTester::TestArcNormalWord(), and TransitionModel::TransitionIdToPdfClass().

901  {
902  KALDI_ASSERT(static_cast<size_t>(trans_id) < id2state_.size());
903  int32 trans_state = id2state_[trans_id];
904  int32 trans_index = trans_id - state2id_[trans_state];
905  const Tuple &tuple = tuples_[trans_state-1];
906  int32 phone = tuple.phone, hmm_state = tuple.hmm_state;
907  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
908  KALDI_ASSERT(static_cast<size_t>(hmm_state) < entry.size());
909  return (static_cast<size_t>(trans_index) < entry[hmm_state].transitions.size()
910  && entry[hmm_state].transitions[trans_index].first == hmm_state);
911 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void MapUpdate ( const Vector< double > &  stats,
const MapTransitionUpdateConfig cfg,
BaseFloat objf_impr_out,
BaseFloat count_out 
)

Does Maximum A Posteriori (MAP) estimation.

The stats are counts/weights, indexed by transition-id.

Definition at line 530 of file transition-model.cc.

References TransitionModel::ComputeDerivedOfProbs(), VectorBase< Real >::Dim(), TransitionModel::GetTransitionProb(), KALDI_ASSERT, KALDI_ERR, KALDI_LOG, kaldi::Log(), TransitionModel::log_probs_, TransitionModel::MapUpdateShared(), rnnlm::n, TransitionModel::NumTransitionIds(), TransitionModel::NumTransitionIndices(), TransitionModel::NumTransitionStates(), TransitionModel::PairToTransitionId(), MapTransitionUpdateConfig::share_for_pdfs, VectorBase< Real >::Sum(), and MapTransitionUpdateConfig::tau.

Referenced by main().

533  {
534  KALDI_ASSERT(cfg.tau > 0.0);
535  if (cfg.share_for_pdfs) {
536  MapUpdateShared(stats, cfg, objf_impr_out, count_out);
537  return;
538  }
539  BaseFloat count_sum = 0.0, objf_impr_sum = 0.0;
540  KALDI_ASSERT(stats.Dim() == NumTransitionIds()+1);
541  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
542  int32 n = NumTransitionIndices(tstate);
543  KALDI_ASSERT(n>=1);
544  if (n > 1) { // no point updating if only one transition...
545  Vector<double> counts(n);
546  for (int32 tidx = 0; tidx < n; tidx++) {
547  int32 tid = PairToTransitionId(tstate, tidx);
548  counts(tidx) = stats(tid);
549  }
550  double tstate_tot = counts.Sum();
551  count_sum += tstate_tot;
552  Vector<BaseFloat> old_probs(n), new_probs(n);
553  for (int32 tidx = 0; tidx < n; tidx++) {
554  int32 tid = PairToTransitionId(tstate, tidx);
555  old_probs(tidx) = new_probs(tidx) = GetTransitionProb(tid);
556  }
557  for (int32 tidx = 0; tidx < n; tidx++)
558  new_probs(tidx) = (counts(tidx) + cfg.tau * old_probs(tidx)) /
559  (cfg.tau + tstate_tot);
560  // Compute objf change
561  for (int32 tidx = 0; tidx < n; tidx++) {
562  double objf_change = counts(tidx) * (Log(new_probs(tidx))
563  - Log(old_probs(tidx)));
564  objf_impr_sum += objf_change;
565  }
566  // Commit updated values.
567  for (int32 tidx = 0; tidx < n; tidx++) {
568  int32 tid = PairToTransitionId(tstate, tidx);
569  log_probs_(tid) = Log(new_probs(tidx));
570  if (log_probs_(tid) - log_probs_(tid) != 0.0)
571  KALDI_ERR << "Log probs is inf or NaN: error in update or bad stats?";
572  }
573  }
574  }
575  KALDI_LOG << "Objf change is " << (objf_impr_sum / count_sum)
576  << " per frame over " << count_sum
577  << " frames.";
578  if (objf_impr_out) *objf_impr_out = objf_impr_sum;
579  if (count_out) *count_out = count_sum;
581 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
BaseFloat GetTransitionProb(int32 trans_id) const
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
struct rnnlm::@11::@12 n
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
#define KALDI_ERR
Definition: kaldi-error.h:127
void MapUpdateShared(const Vector< double > &stats, const MapTransitionUpdateConfig &cfg, BaseFloat *objf_impr_out, BaseFloat *count_out)
This version of the MapUpdate() function is for if the user specifies –share-for-pdfs=true.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
#define KALDI_LOG
Definition: kaldi-error.h:133
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
void MapUpdateShared ( const Vector< double > &  stats,
const MapTransitionUpdateConfig cfg,
BaseFloat objf_impr_out,
BaseFloat count_out 
)
private

This version of the MapUpdate() function is for if the user specifies –share-for-pdfs=true.

We share the transitions for all states that share the same pdf.

Definition at line 687 of file transition-model.cc.

References TransitionModel::ComputeDerivedOfProbs(), VectorBase< Real >::Dim(), TransitionModel::GetTransitionProb(), TransitionModel::IsHmm(), KALDI_ASSERT, KALDI_ERR, KALDI_LOG, kaldi::Log(), TransitionModel::log_probs_, rnnlm::n, TransitionModel::NumTransitionIds(), TransitionModel::NumTransitionIndices(), TransitionModel::NumTransitionStates(), TransitionModel::PairToTransitionId(), MapTransitionUpdateConfig::share_for_pdfs, VectorBase< Real >::Sum(), MapTransitionUpdateConfig::tau, TransitionModel::TransitionStateToForwardPdf(), and TransitionModel::TransitionStateToSelfLoopPdf().

Referenced by TransitionModel::MapUpdate().

690  {
691  KALDI_ASSERT(cfg.share_for_pdfs);
692 
693  BaseFloat count_sum = 0.0, objf_impr_sum = 0.0;
694  KALDI_ASSERT(stats.Dim() == NumTransitionIds()+1);
695  std::map<int32, std::set<int32> > pdf_to_tstate;
696 
697  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
698  int32 pdf = TransitionStateToForwardPdf(tstate);
699  pdf_to_tstate[pdf].insert(tstate);
700  if (!IsHmm()) {
701  pdf = TransitionStateToSelfLoopPdf(tstate);
702  pdf_to_tstate[pdf].insert(tstate);
703  }
704  }
705  std::map<int32, std::set<int32> >::iterator map_iter;
706  for (map_iter = pdf_to_tstate.begin();
707  map_iter != pdf_to_tstate.end();
708  ++map_iter) {
709  // map_iter->first is pdf-id... not needed.
710  const std::set<int32> &tstates = map_iter->second;
711  KALDI_ASSERT(!tstates.empty());
712  int32 one_tstate = *(tstates.begin());
713  int32 n = NumTransitionIndices(one_tstate);
714  KALDI_ASSERT(n >= 1);
715  if (n > 1) { // Only update if >1 transition...
716  Vector<double> counts(n);
717  for (std::set<int32>::const_iterator iter = tstates.begin();
718  iter != tstates.end();
719  ++iter) {
720  int32 tstate = *iter;
721  if (NumTransitionIndices(tstate) != n)
722  KALDI_ERR << "Mismatch in #transition indices: you cannot "
723  "use the --share-for-pdfs option with this topology "
724  "and sharing scheme.";
725  for (int32 tidx = 0; tidx < n; tidx++) {
726  int32 tid = PairToTransitionId(tstate, tidx);
727  counts(tidx) += stats(tid);
728  }
729  }
730  double pdf_tot = counts.Sum();
731  count_sum += pdf_tot;
732 
733  // Note: when calculating objf improvement, we
734  // assume we previously had the same tying scheme so
735  // we can get the params from one_tstate and they're valid
736  // for all.
737  Vector<BaseFloat> old_probs(n), new_probs(n);
738  for (int32 tidx = 0; tidx < n; tidx++) {
739  int32 tid = PairToTransitionId(one_tstate, tidx);
740  old_probs(tidx) = new_probs(tidx) = GetTransitionProb(tid);
741  }
742  for (int32 tidx = 0; tidx < n; tidx++)
743  new_probs(tidx) = (counts(tidx) + old_probs(tidx) * cfg.tau) /
744  (pdf_tot + cfg.tau);
745  // Compute objf change
746  for (int32 tidx = 0; tidx < n; tidx++) {
747  double objf_change = counts(tidx) * (Log(new_probs(tidx))
748  - Log(old_probs(tidx)));
749  objf_impr_sum += objf_change;
750  }
751  // Commit updated values.
752  for (std::set<int32>::const_iterator iter = tstates.begin();
753  iter != tstates.end();
754  ++iter) {
755  int32 tstate = *iter;
756  for (int32 tidx = 0; tidx < n; tidx++) {
757  int32 tid = PairToTransitionId(tstate, tidx);
758  log_probs_(tid) = Log(new_probs(tidx));
759  if (log_probs_(tid) - log_probs_(tid) != 0.0)
760  KALDI_ERR << "Log probs is inf or NaN: error in update or bad stats?";
761  }
762  }
763  }
764  }
765  KALDI_LOG << "Objf change is " << (objf_impr_sum / count_sum)
766  << " per frame over " << count_sum
767  << " frames.";
768  if (objf_impr_out) *objf_impr_out = objf_impr_sum;
769  if (count_out) *count_out = count_sum;
771 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
BaseFloat GetTransitionProb(int32 trans_id) const
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
int32 TransitionStateToForwardPdf(int32 trans_state) const
struct rnnlm::@11::@12 n
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToSelfLoopPdf(int32 trans_state) const
#define KALDI_LOG
Definition: kaldi-error.h:133
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
void MleUpdate ( const Vector< double > &  stats,
const MleTransitionUpdateConfig cfg,
BaseFloat objf_impr_out,
BaseFloat count_out 
)

Does Maximum Likelihood estimation.

The stats are counts/weights, indexed by transition-id. This was previously called Update().

Definition at line 464 of file transition-model.cc.

References TransitionModel::ComputeDerivedOfProbs(), VectorBase< Real >::Dim(), MleTransitionUpdateConfig::floor, TransitionModel::GetTransitionProb(), rnnlm::i, KALDI_ASSERT, KALDI_ERR, KALDI_LOG, kaldi::Log(), TransitionModel::log_probs_, MleTransitionUpdateConfig::mincount, TransitionModel::MleUpdateShared(), rnnlm::n, TransitionModel::NumTransitionIds(), TransitionModel::NumTransitionIndices(), TransitionModel::NumTransitionStates(), TransitionModel::PairToTransitionId(), VectorBase< Real >::Scale(), MleTransitionUpdateConfig::share_for_pdfs, and VectorBase< Real >::Sum().

Referenced by main().

467  {
468  if (cfg.share_for_pdfs) {
469  MleUpdateShared(stats, cfg, objf_impr_out, count_out);
470  return;
471  }
472  BaseFloat count_sum = 0.0, objf_impr_sum = 0.0;
473  int32 num_skipped = 0, num_floored = 0;
474  KALDI_ASSERT(stats.Dim() == NumTransitionIds()+1);
475  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
476  int32 n = NumTransitionIndices(tstate);
477  KALDI_ASSERT(n>=1);
478  if (n > 1) { // no point updating if only one transition...
479  Vector<double> counts(n);
480  for (int32 tidx = 0; tidx < n; tidx++) {
481  int32 tid = PairToTransitionId(tstate, tidx);
482  counts(tidx) = stats(tid);
483  }
484  double tstate_tot = counts.Sum();
485  count_sum += tstate_tot;
486  if (tstate_tot < cfg.mincount) { num_skipped++; }
487  else {
488  Vector<BaseFloat> old_probs(n), new_probs(n);
489  for (int32 tidx = 0; tidx < n; tidx++) {
490  int32 tid = PairToTransitionId(tstate, tidx);
491  old_probs(tidx) = new_probs(tidx) = GetTransitionProb(tid);
492  }
493  for (int32 tidx = 0; tidx < n; tidx++)
494  new_probs(tidx) = counts(tidx) / tstate_tot;
495  for (int32 i = 0; i < 3; i++) { // keep flooring+renormalizing for 3 times..
496  new_probs.Scale(1.0 / new_probs.Sum());
497  for (int32 tidx = 0; tidx < n; tidx++)
498  new_probs(tidx) = std::max(new_probs(tidx), cfg.floor);
499  }
500  // Compute objf change
501  for (int32 tidx = 0; tidx < n; tidx++) {
502  if (new_probs(tidx) == cfg.floor) num_floored++;
503  double objf_change = counts(tidx) * (Log(new_probs(tidx))
504  - Log(old_probs(tidx)));
505  objf_impr_sum += objf_change;
506  }
507  // Commit updated values.
508  for (int32 tidx = 0; tidx < n; tidx++) {
509  int32 tid = PairToTransitionId(tstate, tidx);
510  log_probs_(tid) = Log(new_probs(tidx));
511  if (log_probs_(tid) - log_probs_(tid) != 0.0)
512  KALDI_ERR << "Log probs is inf or NaN: error in update or bad stats?";
513  }
514  }
515  }
516  }
517  KALDI_LOG << "TransitionModel::Update, objf change is "
518  << (objf_impr_sum / count_sum) << " per frame over " << count_sum
519  << " frames. ";
520  KALDI_LOG << num_floored << " probabilities floored, " << num_skipped
521  << " out of " << NumTransitionStates() << " transition-states "
522  "skipped due to insuffient data (it is normal to have some skipped.)";
523  if (objf_impr_out) *objf_impr_out = objf_impr_sum;
524  if (count_out) *count_out = count_sum;
526 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
BaseFloat GetTransitionProb(int32 trans_id) const
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
struct rnnlm::@11::@12 n
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
#define KALDI_LOG
Definition: kaldi-error.h:133
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
void MleUpdateShared(const Vector< double > &stats, const MleTransitionUpdateConfig &cfg, BaseFloat *objf_impr_out, BaseFloat *count_out)
This version of the Update() function is for if the user specifies –share-for-pdfs=true.
void MleUpdateShared ( const Vector< double > &  stats,
const MleTransitionUpdateConfig cfg,
BaseFloat objf_impr_out,
BaseFloat count_out 
)
private

This version of the Update() function is for if the user specifies –share-for-pdfs=true.

We share the transitions for all states that share the same pdf.

Definition at line 588 of file transition-model.cc.

References TransitionModel::ComputeDerivedOfProbs(), VectorBase< Real >::Dim(), MleTransitionUpdateConfig::floor, TransitionModel::GetTransitionProb(), rnnlm::i, TransitionModel::IsHmm(), KALDI_ASSERT, KALDI_ERR, KALDI_LOG, kaldi::Log(), TransitionModel::log_probs_, MleTransitionUpdateConfig::mincount, rnnlm::n, TransitionModel::NumTransitionIds(), TransitionModel::NumTransitionIndices(), TransitionModel::NumTransitionStates(), TransitionModel::PairToTransitionId(), VectorBase< Real >::Scale(), MleTransitionUpdateConfig::share_for_pdfs, VectorBase< Real >::Sum(), TransitionModel::TransitionStateToForwardPdf(), and TransitionModel::TransitionStateToSelfLoopPdf().

Referenced by TransitionModel::MleUpdate().

591  {
592  KALDI_ASSERT(cfg.share_for_pdfs);
593 
594  BaseFloat count_sum = 0.0, objf_impr_sum = 0.0;
595  int32 num_skipped = 0, num_floored = 0;
596  KALDI_ASSERT(stats.Dim() == NumTransitionIds()+1);
597  std::map<int32, std::set<int32> > pdf_to_tstate;
598 
599  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
600  int32 pdf = TransitionStateToForwardPdf(tstate);
601  pdf_to_tstate[pdf].insert(tstate);
602  if (!IsHmm()) {
603  pdf = TransitionStateToSelfLoopPdf(tstate);
604  pdf_to_tstate[pdf].insert(tstate);
605  }
606  }
607  std::map<int32, std::set<int32> >::iterator map_iter;
608  for (map_iter = pdf_to_tstate.begin();
609  map_iter != pdf_to_tstate.end();
610  ++map_iter) {
611  // map_iter->first is pdf-id... not needed.
612  const std::set<int32> &tstates = map_iter->second;
613  KALDI_ASSERT(!tstates.empty());
614  int32 one_tstate = *(tstates.begin());
615  int32 n = NumTransitionIndices(one_tstate);
616  KALDI_ASSERT(n >= 1);
617  if (n > 1) { // Only update if >1 transition...
618  Vector<double> counts(n);
619  for (std::set<int32>::const_iterator iter = tstates.begin();
620  iter != tstates.end();
621  ++iter) {
622  int32 tstate = *iter;
623  if (NumTransitionIndices(tstate) != n)
624  KALDI_ERR << "Mismatch in #transition indices: you cannot "
625  "use the --share-for-pdfs option with this topology "
626  "and sharing scheme.";
627  for (int32 tidx = 0; tidx < n; tidx++) {
628  int32 tid = PairToTransitionId(tstate, tidx);
629  counts(tidx) += stats(tid);
630  }
631  }
632  double pdf_tot = counts.Sum();
633  count_sum += pdf_tot;
634  if (pdf_tot < cfg.mincount) { num_skipped++; }
635  else {
636  // Note: when calculating objf improvement, we
637  // assume we previously had the same tying scheme so
638  // we can get the params from one_tstate and they're valid
639  // for all.
640  Vector<BaseFloat> old_probs(n), new_probs(n);
641  for (int32 tidx = 0; tidx < n; tidx++) {
642  int32 tid = PairToTransitionId(one_tstate, tidx);
643  old_probs(tidx) = new_probs(tidx) = GetTransitionProb(tid);
644  }
645  for (int32 tidx = 0; tidx < n; tidx++)
646  new_probs(tidx) = counts(tidx) / pdf_tot;
647  for (int32 i = 0; i < 3; i++) { // keep flooring+renormalizing for 3 times..
648  new_probs.Scale(1.0 / new_probs.Sum());
649  for (int32 tidx = 0; tidx < n; tidx++)
650  new_probs(tidx) = std::max(new_probs(tidx), cfg.floor);
651  }
652  // Compute objf change
653  for (int32 tidx = 0; tidx < n; tidx++) {
654  if (new_probs(tidx) == cfg.floor) num_floored++;
655  double objf_change = counts(tidx) * (Log(new_probs(tidx))
656  - Log(old_probs(tidx)));
657  objf_impr_sum += objf_change;
658  }
659  // Commit updated values.
660  for (std::set<int32>::const_iterator iter = tstates.begin();
661  iter != tstates.end();
662  ++iter) {
663  int32 tstate = *iter;
664  for (int32 tidx = 0; tidx < n; tidx++) {
665  int32 tid = PairToTransitionId(tstate, tidx);
666  log_probs_(tid) = Log(new_probs(tidx));
667  if (log_probs_(tid) - log_probs_(tid) != 0.0)
668  KALDI_ERR << "Log probs is inf or NaN: error in update or bad stats?";
669  }
670  }
671  }
672  }
673  }
674  KALDI_LOG << "Objf change is " << (objf_impr_sum / count_sum)
675  << " per frame over " << count_sum << " frames; "
676  << num_floored << " probabilities floored, "
677  << num_skipped << " pdf-ids skipped due to insuffient data.";
678  if (objf_impr_out) *objf_impr_out = objf_impr_sum;
679  if (count_out) *count_out = count_sum;
681 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
BaseFloat GetTransitionProb(int32 trans_id) const
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
int32 TransitionStateToForwardPdf(int32 trans_state) const
struct rnnlm::@11::@12 n
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToSelfLoopPdf(int32 trans_state) const
#define KALDI_LOG
Definition: kaldi-error.h:133
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
int32 NumPhones ( ) const

Definition at line 320 of file transition-model.cc.

References rnnlm::i, and TransitionModel::tuples_.

320  {
321  int32 num_trans_state = tuples_.size();
322  int32 max_phone_id = 0;
323  for (int32 i = 0; i < num_trans_state; ++i) {
324  if (tuples_[i].phone > max_phone_id)
325  max_phone_id = tuples_[i].phone;
326  }
327  return max_phone_id;
328 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
int32 NumTransitionIndices ( int32  trans_state) const

Returns the number of transition-indices for a particular transition-state.

Note: "Indices" is the plural of "index". Index is not the same as "id", here. A transition-index is a zero-based offset into the transitions out of a particular transition state.

Definition at line 259 of file transition-model.cc.

References KALDI_ASSERT, TransitionModel::state2id_, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), main(), TransitionModel::MapUpdate(), TransitionModel::MapUpdateShared(), TransitionModel::MleUpdate(), TransitionModel::MleUpdateShared(), and TransitionModel::Print().

259  {
260  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
261  return static_cast<int32>(state2id_[trans_state+1]-state2id_[trans_state]);
262 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 NumTransitionStates ( ) const
inline

Returns the total number of transition-states (note, these are one-based).

Definition at line 179 of file transition-model.h.

References TransitionModel::tuples_.

Referenced by TransitionModel::Check(), TransitionModel::ComputeDerivedOfProbs(), kaldi::GetPdfsForPhones(), kaldi::GetPhonesForPdfs(), main(), TransitionModel::MapUpdate(), TransitionModel::MapUpdateShared(), TransitionModel::MleUpdate(), TransitionModel::MleUpdateShared(), and TransitionModel::Print().

179 { return tuples_.size(); }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
int32 PairToTransitionId ( int32  trans_state,
int32  trans_index 
) const

Definition at line 314 of file transition-model.cc.

References KALDI_ASSERT, TransitionModel::state2id_, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), kaldi::ConvertAlignmentForPhone(), kaldi::GenerateRandomAlignment(), kaldi::GetHmmAsFst(), kaldi::GetHmmAsFstSimple(), TransitionModel::MapUpdate(), TransitionModel::MapUpdateShared(), TransitionModel::MleUpdate(), TransitionModel::MleUpdateShared(), TransitionModel::Print(), and TransitionModel::SelfLoopOf().

314  {
315  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
316  KALDI_ASSERT(trans_index < state2id_[trans_state+1] - state2id_[trans_state]);
317  return state2id_[trans_state] + trans_index;
318 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void Print ( std::ostream &  os,
const std::vector< std::string > &  phone_names,
const Vector< double > *  occs = NULL 
)

Print will print the transition model in a human-readable way, for purposes of human inspection.

The "occs" are optional (they are indexed by pdf-id).

Definition at line 801 of file transition-model.cc.

References VectorBase< Real >::Dim(), TransitionModel::Tuple::forward_pdf, TransitionModel::GetTransitionProb(), TransitionModel::Tuple::hmm_state, TransitionModel::IsHmm(), TransitionModel::IsSelfLoop(), KALDI_ASSERT, TransitionModel::NumPdfs(), TransitionModel::NumTransitionIndices(), TransitionModel::NumTransitionStates(), TransitionModel::PairToTransitionId(), TransitionModel::Tuple::phone, TransitionModel::Tuple::self_loop_pdf, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by main().

803  {
804  if (occs != NULL)
805  KALDI_ASSERT(occs->Dim() == NumPdfs());
806  bool is_hmm = IsHmm();
807  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
808  const Tuple &tuple = tuples_[tstate-1];
809  KALDI_ASSERT(static_cast<size_t>(tuple.phone) < phone_names.size());
810  std::string phone_name = phone_names[tuple.phone];
811 
812  os << "Transition-state " << tstate << ": phone = " << phone_name
813  << " hmm-state = " << tuple.hmm_state;
814  if (is_hmm)
815  os << " pdf = " << tuple.forward_pdf << '\n';
816  else
817  os << " forward-pdf = " << tuple.forward_pdf << " self-loop-pdf = "
818  << tuple.self_loop_pdf << '\n';
819  for (int32 tidx = 0; tidx < NumTransitionIndices(tstate); tidx++) {
820  int32 tid = PairToTransitionId(tstate, tidx);
821  BaseFloat p = GetTransitionProb(tid);
822  os << " Transition-id = " << tid << " p = " << p;
823  if (occs != NULL) {
824  if (IsSelfLoop(tid))
825  os << " count of pdf = " << (*occs)(tuple.self_loop_pdf);
826  else
827  os << " count of pdf = " << (*occs)(tuple.forward_pdf);
828  }
829  // now describe what it's a transition to.
830  if (IsSelfLoop(tid)) os << " [self-loop]\n";
831  else {
832  int32 hmm_state = tuple.hmm_state;
833  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(tuple.phone);
834  KALDI_ASSERT(static_cast<size_t>(hmm_state) < entry.size());
835  int32 next_hmm_state = entry[hmm_state].transitions[tidx].first;
836  KALDI_ASSERT(next_hmm_state != hmm_state);
837  os << " [" << hmm_state << " -> " << next_hmm_state << "]\n";
838  }
839  }
840  }
841 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
BaseFloat GetTransitionProb(int32 trans_id) const
float BaseFloat
Definition: kaldi-types.h:29
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
bool IsSelfLoop(int32 trans_id) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
void Read ( std::istream &  is,
bool  binary 
)

Definition at line 383 of file transition-model.cc.

References TransitionModel::Check(), TransitionModel::ComputeDerived(), TransitionModel::ComputeDerivedOfProbs(), kaldi::ExpectToken(), rnnlm::i, KALDI_ASSERT, TransitionModel::log_probs_, HmmTopology::Read(), Vector< Real >::Read(), kaldi::ReadBasicType(), kaldi::ReadToken(), TransitionModel::topo_, and TransitionModel::tuples_.

Referenced by kaldi::InitAmGmmFromOld(), main(), and kaldi::TestTransitionModel().

383  {
384  ExpectToken(is, binary, "<TransitionModel>");
385  topo_.Read(is, binary);
386  std::string token;
387  ReadToken(is, binary, &token);
388  int32 size;
389  ReadBasicType(is, binary, &size);
390  tuples_.resize(size);
391  for (int32 i = 0; i < size; i++) {
392  ReadBasicType(is, binary, &(tuples_[i].phone));
393  ReadBasicType(is, binary, &(tuples_[i].hmm_state));
394  ReadBasicType(is, binary, &(tuples_[i].forward_pdf));
395  if (token == "<Tuples>")
396  ReadBasicType(is, binary, &(tuples_[i].self_loop_pdf));
397  else if (token == "<Triples>")
398  tuples_[i].self_loop_pdf = tuples_[i].forward_pdf;
399  }
400  ReadToken(is, binary, &token);
401  KALDI_ASSERT(token == "</Triples>" || token == "</Tuples>");
402  ComputeDerived();
403  ExpectToken(is, binary, "<LogProbs>");
404  log_probs_.Read(is, binary);
405  ExpectToken(is, binary, "</LogProbs>");
406  ExpectToken(is, binary, "</TransitionModel>");
408  Check();
409 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
void ReadBasicType(std::istream &is, bool binary, T *t)
ReadBasicType is the name of the read function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:55
void ReadToken(std::istream &is, bool binary, std::string *str)
ReadToken gets the next token and puts it in str (exception on failure).
Definition: io-funcs.cc:154
void Read(std::istream &is, bool binary)
Definition: hmm-topology.cc:39
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
void ExpectToken(std::istream &is, bool binary, const char *token)
ExpectToken tries to read in the given token, and throws an exception on failure. ...
Definition: io-funcs.cc:188
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void Read(std::istream &in, bool binary, bool add=false)
Read function using C++ streams.
int32 SelfLoopOf ( int32  trans_state) const

Definition at line 349 of file transition-model.cc.

References KALDI_ASSERT, TransitionModel::PairToTransitionId(), TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by kaldi::AddSelfLoopsAfter(), kaldi::AddSelfLoopsBefore(), and TransitionModel::ComputeDerivedOfProbs().

349  { // returns the self-loop transition-id,
350  KALDI_ASSERT(static_cast<size_t>(trans_state-1) < tuples_.size());
351  const Tuple &tuple = tuples_[trans_state-1];
352  // or zero if does not exist.
353  int32 phone = tuple.phone, hmm_state = tuple.hmm_state;
354  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
355  KALDI_ASSERT(static_cast<size_t>(hmm_state) < entry.size());
356  for (int32 trans_index = 0;
357  trans_index < static_cast<int32>(entry[hmm_state].transitions.size());
358  trans_index++)
359  if (entry[hmm_state].transitions[trans_index].first == hmm_state)
360  return PairToTransitionId(trans_state, trans_index);
361  return 0; // invalid transition id.
362 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionIdToHmmState ( int32  trans_id) const

Definition at line 794 of file transition-model.cc.

References TransitionModel::Tuple::hmm_state, TransitionModel::id2state_, KALDI_ASSERT, and TransitionModel::tuples_.

Referenced by kaldi::ConvertAlignmentForPhone(), kaldi::ConvertLatticeToPhones(), and fst::DeterminizeLatticeInsertPhones().

794  {
795  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
796  int32 trans_state = id2state_[trans_id];
797  const Tuple &t = tuples_[trans_state-1];
798  return t.hmm_state;
799 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionIdToPdfClass ( int32  trans_id) const

Definition at line 780 of file transition-model.cc.

References TransitionModel::Tuple::hmm_state, TransitionModel::id2state_, TransitionModel::IsSelfLoop(), KALDI_ASSERT, TransitionModel::Tuple::phone, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by kaldi::AccumulateTreeStats().

780  {
781  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
782  int32 trans_state = id2state_[trans_id];
783 
784  const Tuple &t = tuples_[trans_state-1];
785  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(t.phone);
786  KALDI_ASSERT(static_cast<size_t>(t.hmm_state) < entry.size());
787  if (IsSelfLoop(trans_id))
788  return entry[t.hmm_state].self_loop_pdf_class;
789  else
790  return entry[t.hmm_state].forward_pdf_class;
791 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
bool IsSelfLoop(int32 trans_id) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionIdToPhone ( int32  trans_id) const

Definition at line 774 of file transition-model.cc.

References TransitionModel::id2state_, KALDI_ASSERT, and TransitionModel::tuples_.

Referenced by kaldi::AccumulateTreeStats(), LatticeLexiconWordAligner::ComputationState::Advance(), kaldi::CompactLatticeToWordProns(), kaldi::ConvertAlignment(), kaldi::ConvertAlignmentForPhone(), kaldi::ConvertCompactLatticeToPhones(), kaldi::ConvertLatticeToPhones(), kaldi::ConvertPosteriorToPhones(), fst::DeterminizeLatticeInsertPhones(), kaldi::IsPlausibleWord(), kaldi::LatticeActivePhones(), kaldi::LatticeBoost(), kaldi::LatticeForwardBackwardMpeVariants(), main(), LatticePhoneAligner::ComputationState::OutputArcForce(), LatticeWordAligner::ComputationState::OutputArcForce(), LatticeWordAligner::ComputationState::OutputNormalWordArc(), LatticeWordAligner::ComputationState::OutputOnePhoneWordArc(), LatticePhoneAligner::ComputationState::OutputPhoneArc(), ArcPosteriorComputer::OutputPosteriors(), LatticeWordAligner::ComputationState::OutputSilenceArc(), WordAlignedLatticeTester::TestArcNormalWord(), WordAlignedLatticeTester::TestArcOnePhoneWord(), WordAlignedLatticeTester::TestArcSilence(), kaldi::TestConvertAlignment(), kaldi::TestSplitToPhones(), kaldi::WeightSilencePost(), and kaldi::WeightSilencePostDistributed().

774  {
775  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
776  int32 trans_state = id2state_[trans_id];
777  return tuples_[trans_state-1].phone;
778 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionIdToTransitionIndex ( int32  trans_id) const

Definition at line 269 of file transition-model.cc.

References TransitionModel::id2state_, KALDI_ASSERT, and TransitionModel::state2id_.

Referenced by TransitionModel::Check(), and kaldi::ConvertAlignmentForPhone().

269  {
270  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
271  return trans_id - state2id_[id2state_[trans_id]];
272 }
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionIdToTransitionState ( int32  trans_id) const
int32 TransitionStateToForwardPdf ( int32  trans_state) const

Definition at line 279 of file transition-model.cc.

References KALDI_ASSERT, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), kaldi::GetPdfsForPhones(), kaldi::GetPhonesForPdfs(), TransitionModel::MapUpdateShared(), and TransitionModel::MleUpdateShared().

279  {
280  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
281  return tuples_[trans_state-1].forward_pdf;
282 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToForwardPdfClass ( int32  trans_state) const

Definition at line 284 of file transition-model.cc.

References KALDI_ASSERT, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by kaldi::ConvertAlignmentForPhone().

285  {
286  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
287  const Tuple &t = tuples_[trans_state-1];
288  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(t.phone);
289  KALDI_ASSERT(static_cast<size_t>(t.hmm_state) < entry.size());
290  return entry[t.hmm_state].forward_pdf_class;
291 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToHmmState ( int32  trans_state) const

Definition at line 309 of file transition-model.cc.

References KALDI_ASSERT, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), and kaldi::SplitToPhonesInternal().

309  {
310  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
311  return tuples_[trans_state-1].hmm_state;
312 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToPhone ( int32  trans_state) const

Definition at line 274 of file transition-model.cc.

References KALDI_ASSERT, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), kaldi::GetPdfsForPhones(), kaldi::GetPhonesForPdfs(), main(), and kaldi::SplitToPhonesInternal().

274  {
275  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
276  return tuples_[trans_state-1].phone;
277 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToSelfLoopPdf ( int32  trans_state) const

Definition at line 304 of file transition-model.cc.

References KALDI_ASSERT, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), kaldi::GetPdfsForPhones(), kaldi::GetPhonesForPdfs(), TransitionModel::MapUpdateShared(), and TransitionModel::MleUpdateShared().

304  {
305  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
306  return tuples_[trans_state-1].self_loop_pdf;
307 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TransitionStateToSelfLoopPdfClass ( int32  trans_state) const

Definition at line 294 of file transition-model.cc.

References KALDI_ASSERT, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by kaldi::ConvertAlignmentForPhone().

295  {
296  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
297  const Tuple &t = tuples_[trans_state-1];
298  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(t.phone);
299  KALDI_ASSERT(static_cast<size_t>(t.hmm_state) < entry.size());
300  return entry[t.hmm_state].self_loop_pdf_class;
301 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:134
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 TupleToTransitionState ( int32  phone,
int32  hmm_state,
int32  pdf,
int32  self_loop_pdf 
) const

Definition at line 243 of file transition-model.cc.

References KALDI_ERR, and TransitionModel::tuples_.

Referenced by TransitionModel::Check(), kaldi::ConvertAlignmentForPhone(), kaldi::GenerateRandomAlignment(), kaldi::GetHmmAsFst(), and kaldi::GetHmmAsFstSimple().

243  {
244  Tuple tuple(phone, hmm_state, pdf, self_loop_pdf);
245  // Note: if this ever gets too expensive, which is unlikely, we can refactor
246  // this code to sort first on pdf, and then index on pdf, so those
247  // that have the same pdf are in a contiguous range.
248  std::vector<Tuple>::const_iterator iter =
249  std::lower_bound(tuples_.begin(), tuples_.end(), tuple);
250  if (iter == tuples_.end() || !(*iter == tuple)) {
251  KALDI_ERR << "TransitionModel::TupleToTransitionState, tuple not found."
252  << " (incompatible tree and model?)";
253  }
254  // tuples_ is indexed by transition_state-1, so add one.
255  return static_cast<int32>((iter - tuples_.begin())) + 1;
256 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
#define KALDI_ERR
Definition: kaldi-error.h:127
void Write ( std::ostream &  os,
bool  binary 
) const

Definition at line 411 of file transition-model.cc.

References rnnlm::i, TransitionModel::IsHmm(), TransitionModel::log_probs_, TransitionModel::topo_, TransitionModel::tuples_, HmmTopology::Write(), VectorBase< Real >::Write(), kaldi::WriteBasicType(), and kaldi::WriteToken().

Referenced by main(), and kaldi::TestTransitionModel().

411  {
412  bool is_hmm = IsHmm();
413  WriteToken(os, binary, "<TransitionModel>");
414  if (!binary) os << "\n";
415  topo_.Write(os, binary);
416  if (is_hmm)
417  WriteToken(os, binary, "<Triples>");
418  else
419  WriteToken(os, binary, "<Tuples>");
420  WriteBasicType(os, binary, static_cast<int32>(tuples_.size()));
421  if (!binary) os << "\n";
422  for (int32 i = 0; i < static_cast<int32> (tuples_.size()); i++) {
423  WriteBasicType(os, binary, tuples_[i].phone);
424  WriteBasicType(os, binary, tuples_[i].hmm_state);
425  WriteBasicType(os, binary, tuples_[i].forward_pdf);
426  if (!is_hmm)
427  WriteBasicType(os, binary, tuples_[i].self_loop_pdf);
428  if (!binary) os << "\n";
429  }
430  if (is_hmm)
431  WriteToken(os, binary, "</Triples>");
432  else
433  WriteToken(os, binary, "</Tuples>");
434  if (!binary) os << "\n";
435  WriteToken(os, binary, "<LogProbs>");
436  if (!binary) os << "\n";
437  log_probs_.Write(os, binary);
438  WriteToken(os, binary, "</LogProbs>");
439  if (!binary) os << "\n";
440  WriteToken(os, binary, "</TransitionModel>");
441  if (!binary) os << "\n";
442 }
std::vector< Tuple > tuples_
Triples indexed by transition state minus one; the triples are in sorted order which allows us to do ...
void Write(std::ostream &Out, bool binary) const
Writes to C++ stream (option to write in binary).
void Write(std::ostream &os, bool binary) const
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
void WriteToken(std::ostream &os, bool binary, const char *token)
The WriteToken functions are for writing nonempty sequences of non-space characters.
Definition: io-funcs.cc:134
void WriteBasicType(std::ostream &os, bool binary, T t)
WriteBasicType is the name of the write function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:34

Member Data Documentation

std::vector<int32> id2pdf_id_
private
Vector<BaseFloat> non_self_loop_log_probs_
private

For each transition-state, the log of (1 - self-loop-prob).

Indexed by transition-state.

Definition at line 312 of file transition-model.h.

Referenced by TransitionModel::ComputeDerivedOfProbs(), and TransitionModel::GetNonSelfLoopLogProb().

int32 num_pdfs_
private

This is actually one plus the highest-numbered pdf we ever got back from the tree (but the tree numbers pdfs contiguously from zero so this is the number of pdfs).

Definition at line 317 of file transition-model.h.

Referenced by TransitionModel::Compatible(), TransitionModel::ComputeDerived(), and TransitionModel::NumPdfs().

std::vector<int32> state2id_
private

Gives the first transition_id of each transition-state; indexed by the transition-state.

Array indexed 1..num-transition-states+1 (the last one is needed so we can know the num-transitions of the last transition-state.

Definition at line 299 of file transition-model.h.

Referenced by TransitionModel::Compatible(), TransitionModel::ComputeDerived(), TransitionModel::InitializeProbs(), TransitionModel::IsFinal(), TransitionModel::IsSelfLoop(), TransitionModel::NumTransitionIndices(), TransitionModel::PairToTransitionId(), and TransitionModel::TransitionIdToTransitionIndex().


The documentation for this class was generated from the following files: