#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 TransitionIdToPdfFast (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
 
 KALDI_DISALLOW_COPY_AND_ASSIGN (TransitionModel)
 

Private Attributes

HmmTopology topo_
 
std::vector< Tupletuples_
 Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do the reverse mapping from tuple to transition state. More...
 
std::vector< int32state2id_
 Gives the first transition_id of each transition-state; indexed by the transition-state. More...
 
std::vector< int32id2state_
 For each transition-id, the corresponding transition state (indexed by transition-id). More...
 
std::vector< int32id2pdf_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 123 of file transition-model.h.

Constructor & Destructor Documentation

◆ TransitionModel() [1/2]

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 245 of file transition-model.cc.

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

246  : topo_(hmm_topo) {
247  // First thing is to get all possible tuples.
248  ComputeTuples(ctx_dep);
249  ComputeDerived();
250  InitializeProbs();
251  Check();
252 }
void ComputeTuples(const ContextDependencyInterface &ctx_dep)

◆ TransitionModel() [2/2]

TransitionModel ( )
inline

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

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

134 : num_pdfs_(0) { }
int32 num_pdfs_
This is actually one plus the highest-numbered pdf we ever got back from the tree (but the tree numbe...

Member Function Documentation

◆ Accumulate()

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

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

References KALDI_ASSERT.

Referenced by main().

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

◆ Check()

void Check ( ) const
private

Definition at line 209 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().

209  {
211  {
212  int32 sum = 0;
213  for (int32 ts = 1; ts <= NumTransitionStates(); ts++) sum += NumTransitionIndices(ts);
214  KALDI_ASSERT(sum == NumTransitionIds());
215  }
216  for (int32 tid = 1; tid <= NumTransitionIds(); tid++) {
217  int32 tstate = TransitionIdToTransitionState(tid),
218  index = TransitionIdToTransitionIndex(tid);
219  KALDI_ASSERT(tstate > 0 && tstate <=NumTransitionStates() && index >= 0);
220  KALDI_ASSERT(tid == PairToTransitionId(tstate, index));
221  int32 phone = TransitionStateToPhone(tstate),
222  hmm_state = TransitionStateToHmmState(tstate),
223  forward_pdf = TransitionStateToForwardPdf(tstate),
224  self_loop_pdf = TransitionStateToSelfLoopPdf(tstate);
225  KALDI_ASSERT(tstate == TupleToTransitionState(phone, hmm_state, forward_pdf, self_loop_pdf));
226  KALDI_ASSERT(log_probs_(tid) <= 0.0 && log_probs_(tid) - log_probs_(tid) == 0.0);
227  // checking finite and non-positive (and not out-of-bounds).
228  }
229 }
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
int32 TransitionStateToForwardPdf(int32 trans_state) const
int32 TransitionStateToHmmState(int32 trans_state) const
int32 TupleToTransitionState(int32 phone, int32 hmm_state, int32 pdf, int32 self_loop_pdf) const
kaldi::int32 int32
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 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
int32 TransitionIdToTransitionState(int32 trans_id) const
int32 TransitionStateToPhone(int32 trans_state) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
int32 TransitionStateToSelfLoopPdf(int32 trans_state) const
int32 TransitionIdToTransitionIndex(int32 trans_id) const

◆ Compatible()

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 906 of file transition-model.cc.

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

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

906  {
907  return (topo_ == other.topo_ && tuples_ == other.tuples_ &&
908  state2id_ == other.state2id_ && id2state_ == other.id2state_
909  && num_pdfs_ == other.num_pdfs_);
910 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
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.

◆ ComputeDerived()

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  }
178 
179  // The following statements put copies a large number in the region of memory
180  // past the end of the id2pdf_id_ array, while leaving the array as it was
181  // before. The goal of this is to speed up decoding by disabling a check
182  // inside TransitionIdToPdf() that the transition-id was within the correct
183  // range.
184  int32 num_big_numbers = std::min<int32>(2000, cur_transition_id);
185  id2pdf_id_.resize(cur_transition_id + num_big_numbers,
186  std::numeric_limits<int32>::max());
187  id2pdf_id_.resize(cur_transition_id);
188 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
std::vector< int32 > id2pdf_id_
int32 num_pdfs_
This is actually one plus the highest-numbered pdf we ever got back from the tree (but the tree numbe...
kaldi::int32 int32
bool IsSelfLoop(int32 trans_id) const
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< int32 > state2id_
Gives the first transition_id of each transition-state; indexed by the transition-state.

◆ ComputeDerivedOfProbs()

void ComputeDerivedOfProbs ( )
private

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

References kaldi::Exp(), TransitionModel::GetTransitionLogProb(), KALDI_WARN, kaldi::Log(), TransitionModel::non_self_loop_log_probs_, TransitionModel::NumTransitionStates(), and TransitionModel::SelfLoopOf().

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

375  {
376  non_self_loop_log_probs_.Resize(NumTransitionStates()+1); // this array indexed
377  // by transition-state with nothing in zeroth element.
378  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
379  int32 tid = SelfLoopOf(tstate);
380  if (tid == 0) { // no self-loop
381  non_self_loop_log_probs_(tstate) = 0.0; // log(1.0)
382  } else {
383  BaseFloat self_loop_prob = Exp(GetTransitionLogProb(tid)),
384  non_self_loop_prob = 1.0 - self_loop_prob;
385  if (non_self_loop_prob <= 0.0) {
386  KALDI_WARN << "ComputeDerivedOfProbs(): non-self-loop prob is " << non_self_loop_prob;
387  non_self_loop_prob = 1.0e-10; // just so we can continue...
388  }
389  non_self_loop_log_probs_(tstate) = Log(non_self_loop_prob); // will be negative.
390  }
391  }
392 }
double Exp(double x)
Definition: kaldi-math.h:83
int32 SelfLoopOf(int32 trans_state) const
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
BaseFloat GetTransitionLogProb(int32 trans_id) const
#define KALDI_WARN
Definition: kaldi-error.h:150
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
Vector< BaseFloat > non_self_loop_log_probs_
For each transition-state, the log of (1 - self-loop-prob).

◆ ComputeTuples()

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_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
void ComputeTuplesNotHmm(const ContextDependencyInterface &ctx_dep)
void ComputeTuplesIsHmm(const ContextDependencyInterface &ctx_dep)

◆ ComputeTuplesIsHmm()

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 for 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_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
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:86
int32 NumPdfClasses(int32 phone) const
Returns the number of pdf-classes for this phone; throws exception if phone not covered by this topol...
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
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:163
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ ComputeTuplesNotHmm()

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 (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_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
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:86
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
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:163
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ GetNonSelfLoopLogProb()

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 463 of file transition-model.cc.

References KALDI_ASSERT, and TransitionModel::non_self_loop_log_probs_.

Referenced by kaldi::AddSelfLoopsNoReorder(), kaldi::AddSelfLoopsReorder(), kaldi::GetScaledTransitionLogProb(), and TransitionModel::GetTransitionLogProbIgnoringSelfLoops().

463  {
464  KALDI_ASSERT(trans_state != 0);
465  return non_self_loop_log_probs_(trans_state);
466 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
Vector< BaseFloat > non_self_loop_log_probs_
For each transition-state, the log of (1 - self-loop-prob).

◆ GetPhones()

const std::vector<int32>& GetPhones ( ) const
inline

Returns a sorted, unique list of phones.

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

References fst::Print().

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

199 { 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:163

◆ GetTopo()

◆ GetTransitionLogProb()

BaseFloat GetTransitionLogProb ( int32  trans_id) const

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

References TransitionModel::log_probs_.

Referenced by kaldi::AddSelfLoopsNoReorder(), kaldi::AddSelfLoopsReorder(), TransitionModel::ComputeDerivedOfProbs(), kaldi::GetHmmAsFsaSimple(), and kaldi::GetScaledTransitionLogProb().

459  {
460  return log_probs_(trans_id);
461 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.

◆ GetTransitionLogProbIgnoringSelfLoops()

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 468 of file transition-model.cc.

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

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

468  {
469  KALDI_ASSERT(trans_id != 0);
470  KALDI_PARANOID_ASSERT(!IsSelfLoop(trans_id));
471  return log_probs_(trans_id) - GetNonSelfLoopLogProb(TransitionIdToTransitionState(trans_id));
472 }
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
bool IsSelfLoop(int32 trans_id) const
int32 TransitionIdToTransitionState(int32 trans_id) const
#define KALDI_PARANOID_ASSERT(cond)
Definition: kaldi-error.h:206
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
BaseFloat GetNonSelfLoopLogProb(int32 trans_state) const
Returns the log-prob of the non-self-loop probability mass for this transition state.

◆ GetTransitionProb()

BaseFloat GetTransitionProb ( int32  trans_id) const

Definition at line 455 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().

455  {
456  return Exp(log_probs_(trans_id));
457 }
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.

◆ InitializeProbs()

void InitializeProbs ( )
private

Definition at line 190 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, TransitionModel::state2id_, TransitionModel::topo_, HmmTopology::TopologyForPhone(), and TransitionModel::tuples_.

Referenced by TransitionModel::TransitionModel().

190  {
191  log_probs_.Resize(NumTransitionIds()+1); // one-based array, zeroth element empty.
192  for (int32 trans_id = 1; trans_id <= NumTransitionIds(); trans_id++) {
193  int32 trans_state = id2state_[trans_id];
194  int32 trans_index = trans_id - state2id_[trans_state];
195  const Tuple &tuple = tuples_[trans_state-1];
196  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(tuple.phone);
197  KALDI_ASSERT(static_cast<size_t>(tuple.hmm_state) < entry.size());
198  BaseFloat prob = entry[tuple.hmm_state].transitions[trans_index].second;
199  if (prob <= 0.0)
200  KALDI_ERR << "TransitionModel::InitializeProbs, zero "
201  "probability [should remove that entry in the topology]";
202  if (prob > 1.0)
203  KALDI_WARN << "TransitionModel::InitializeProbs, prob greater than one.";
204  log_probs_(trans_id) = Log(prob);
205  }
207 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
#define KALDI_ERR
Definition: kaldi-error.h:147
#define KALDI_WARN
Definition: kaldi-error.h:150
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:185

◆ InitStats()

void InitStats ( Vector< double > *  stats) const
inline

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

References Vector< Real >::Resize().

Referenced by main().

241 { 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).

◆ IsFinal()

bool IsFinal ( int32  trans_id) const

Definition at line 342 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().

342  {
343  KALDI_ASSERT(static_cast<size_t>(trans_id) < id2state_.size());
344  int32 trans_state = id2state_[trans_id];
345  int32 trans_index = trans_id - state2id_[trans_state];
346  const Tuple &tuple = tuples_[trans_state-1];
347  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(tuple.phone);
348  KALDI_ASSERT(static_cast<size_t>(tuple.hmm_state) < entry.size());
349  KALDI_ASSERT(static_cast<size_t>(tuple.hmm_state) < entry.size());
350  KALDI_ASSERT(static_cast<size_t>(trans_index) <
351  entry[tuple.hmm_state].transitions.size());
352  // return true if the transition goes to the final state of the
353  // topology entry.
354  return (entry[tuple.hmm_state].transitions[trans_index].first + 1 ==
355  static_cast<int32>(entry.size()));
356 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
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:185

◆ IsHmm()

bool IsHmm ( ) const
private

Definition at line 231 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().

231  {
232  const std::vector<int32> &phones = topo_.GetPhones();
233  KALDI_ASSERT(!phones.empty());
234  for (size_t i = 0; i < phones.size(); i++) {
235  int32 phone = phones[i];
236  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
237  for (int32 j = 0; j < static_cast<int32>(entry.size()); j++) { // for each state...
238  if (entry[j].forward_pdf_class != entry[j].self_loop_pdf_class)
239  return false;
240  }
241  }
242  return true;
243 }
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
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:163
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ IsSelfLoop()

bool IsSelfLoop ( int32  trans_id) const

Definition at line 912 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(), LatticeWordAligner::ComputationState::OutputArcForce(), LatticeWordAligner::ComputationState::OutputNormalWordArc(), LatticeWordAligner::ComputationState::OutputOnePhoneWordArc(), LatticePhoneAligner::ComputationState::OutputPhoneArc(), LatticeWordAligner::ComputationState::OutputSilenceArc(), TransitionModel::Print(), kaldi::SplitToPhonesInternal(), WordAlignedLatticeTester::TestArcNormalWord(), and TransitionModel::TransitionIdToPdfClass().

912  {
913  KALDI_ASSERT(static_cast<size_t>(trans_id) < id2state_.size());
914  int32 trans_state = id2state_[trans_id];
915  int32 trans_index = trans_id - state2id_[trans_state];
916  const Tuple &tuple = tuples_[trans_state-1];
917  int32 phone = tuple.phone, hmm_state = tuple.hmm_state;
918  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
919  KALDI_ASSERT(static_cast<size_t>(hmm_state) < entry.size());
920  return (static_cast<size_t>(trans_index) < entry[hmm_state].transitions.size()
921  && entry[hmm_state].transitions[trans_index].first == hmm_state);
922 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
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:185

◆ KALDI_DISALLOW_COPY_AND_ASSIGN()

KALDI_DISALLOW_COPY_AND_ASSIGN ( TransitionModel  )
private

◆ MapUpdate()

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 541 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().

544  {
545  KALDI_ASSERT(cfg.tau > 0.0);
546  if (cfg.share_for_pdfs) {
547  MapUpdateShared(stats, cfg, objf_impr_out, count_out);
548  return;
549  }
550  BaseFloat count_sum = 0.0, objf_impr_sum = 0.0;
551  KALDI_ASSERT(stats.Dim() == NumTransitionIds()+1);
552  for (int32 tstate = 1; tstate <= NumTransitionStates(); tstate++) {
553  int32 n = NumTransitionIndices(tstate);
554  KALDI_ASSERT(n>=1);
555  if (n > 1) { // no point updating if only one transition...
556  Vector<double> counts(n);
557  for (int32 tidx = 0; tidx < n; tidx++) {
558  int32 tid = PairToTransitionId(tstate, tidx);
559  counts(tidx) = stats(tid);
560  }
561  double tstate_tot = counts.Sum();
562  count_sum += tstate_tot;
563  Vector<BaseFloat> old_probs(n), new_probs(n);
564  for (int32 tidx = 0; tidx < n; tidx++) {
565  int32 tid = PairToTransitionId(tstate, tidx);
566  old_probs(tidx) = new_probs(tidx) = GetTransitionProb(tid);
567  }
568  for (int32 tidx = 0; tidx < n; tidx++)
569  new_probs(tidx) = (counts(tidx) + cfg.tau * old_probs(tidx)) /
570  (cfg.tau + tstate_tot);
571  // Compute objf change
572  for (int32 tidx = 0; tidx < n; tidx++) {
573  double objf_change = counts(tidx) * (Log(new_probs(tidx))
574  - Log(old_probs(tidx)));
575  objf_impr_sum += objf_change;
576  }
577  // Commit updated values.
578  for (int32 tidx = 0; tidx < n; tidx++) {
579  int32 tid = PairToTransitionId(tstate, tidx);
580  log_probs_(tid) = Log(new_probs(tidx));
581  if (log_probs_(tid) - log_probs_(tid) != 0.0)
582  KALDI_ERR << "Log probs is inf or NaN: error in update or bad stats?";
583  }
584  }
585  }
586  KALDI_LOG << "Objf change is " << (objf_impr_sum / count_sum)
587  << " per frame over " << count_sum
588  << " frames.";
589  if (objf_impr_out) *objf_impr_out = objf_impr_sum;
590  if (count_out) *count_out = count_sum;
592 }
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
kaldi::int32 int32
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
struct rnnlm::@11::@12 n
int32 NumTransitionIndices(int32 trans_state) const
Returns the number of transition-indices for a particular transition-state.
#define KALDI_ERR
Definition: kaldi-error.h:147
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
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:185
#define KALDI_LOG
Definition: kaldi-error.h:153
int32 NumTransitionStates() const
Returns the total number of transition-states (note, these are one-based).
BaseFloat GetTransitionProb(int32 trans_id) const

◆ MapUpdateShared()

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 698 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().

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

◆ MleUpdate()

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 475 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().

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

◆ MleUpdateShared()

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 599 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().

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

◆ NumPdfs()

◆ NumPhones()

int32 NumPhones ( ) const

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

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

Referenced by main().

331  {
332  int32 num_trans_state = tuples_.size();
333  int32 max_phone_id = 0;
334  for (int32 i = 0; i < num_trans_state; ++i) {
335  if (tuples_[i].phone > max_phone_id)
336  max_phone_id = tuples_[i].phone;
337  }
338  return max_phone_id;
339 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32

◆ NumTransitionIds()

◆ NumTransitionIndices()

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 270 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().

270  {
271  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
272  return static_cast<int32>(state2id_[trans_state+1]-state2id_[trans_state]);
273 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
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:185

◆ NumTransitionStates()

int32 NumTransitionStates ( ) const
inline

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

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

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

184 { return tuples_.size(); }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...

◆ PairToTransitionId()

int32 PairToTransitionId ( int32  trans_state,
int32  trans_index 
) const

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

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

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

325  {
326  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
327  KALDI_ASSERT(trans_index < state2id_[trans_state+1] - state2id_[trans_state]);
328  return state2id_[trans_state] + trans_index;
329 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
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:185

◆ Print()

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 812 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().

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

◆ Read()

void Read ( std::istream &  is,
bool  binary 
)

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

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

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

394  {
395  ExpectToken(is, binary, "<TransitionModel>");
396  topo_.Read(is, binary);
397  std::string token;
398  ReadToken(is, binary, &token);
399  int32 size;
400  ReadBasicType(is, binary, &size);
401  tuples_.resize(size);
402  for (int32 i = 0; i < size; i++) {
403  ReadBasicType(is, binary, &(tuples_[i].phone));
404  ReadBasicType(is, binary, &(tuples_[i].hmm_state));
405  ReadBasicType(is, binary, &(tuples_[i].forward_pdf));
406  if (token == "<Tuples>")
407  ReadBasicType(is, binary, &(tuples_[i].self_loop_pdf));
408  else if (token == "<Triples>")
409  tuples_[i].self_loop_pdf = tuples_[i].forward_pdf;
410  }
411  ReadToken(is, binary, &token);
412  KALDI_ASSERT(token == "</Triples>" || token == "</Tuples>");
413  ComputeDerived();
414  ExpectToken(is, binary, "<LogProbs>");
415  log_probs_.Read(is, binary);
416  ExpectToken(is, binary, "</LogProbs>");
417  ExpectToken(is, binary, "</TransitionModel>");
419  Check();
420 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
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
kaldi::int32 int32
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:191
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ SelfLoopOf()

int32 SelfLoopOf ( int32  trans_state) const

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

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

Referenced by kaldi::AddSelfLoopsNoReorder(), kaldi::AddSelfLoopsReorder(), and TransitionModel::ComputeDerivedOfProbs().

360  { // returns the self-loop transition-id,
361  KALDI_ASSERT(static_cast<size_t>(trans_state-1) < tuples_.size());
362  const Tuple &tuple = tuples_[trans_state-1];
363  // or zero if does not exist.
364  int32 phone = tuple.phone, hmm_state = tuple.hmm_state;
365  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(phone);
366  KALDI_ASSERT(static_cast<size_t>(hmm_state) < entry.size());
367  for (int32 trans_index = 0;
368  trans_index < static_cast<int32>(entry[hmm_state].transitions.size());
369  trans_index++)
370  if (entry[hmm_state].transitions[trans_index].first == hmm_state)
371  return PairToTransitionId(trans_state, trans_index);
372  return 0; // invalid transition id.
373 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
int32 PairToTransitionId(int32 trans_state, int32 trans_index) const
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionIdToHmmState()

int32 TransitionIdToHmmState ( int32  trans_id) const

Definition at line 805 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().

805  {
806  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
807  int32 trans_state = id2state_[trans_id];
808  const Tuple &t = tuples_[trans_state-1];
809  return t.hmm_state;
810 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionIdToPdfClass()

int32 TransitionIdToPdfClass ( int32  trans_id) const

Definition at line 791 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().

791  {
792  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
793  int32 trans_state = id2state_[trans_id];
794 
795  const Tuple &t = tuples_[trans_state-1];
796  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(t.phone);
797  KALDI_ASSERT(static_cast<size_t>(t.hmm_state) < entry.size());
798  if (IsSelfLoop(trans_id))
799  return entry[t.hmm_state].self_loop_pdf_class;
800  else
801  return entry[t.hmm_state].forward_pdf_class;
802 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
bool IsSelfLoop(int32 trans_id) const
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionIdToPhone()

int32 TransitionIdToPhone ( int32  trans_id) const

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

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

Referenced by kaldi::AccumulateTreeStats(), LatticeLexiconWordAligner::ComputationState::Advance(), kaldi::CompactLatticeToWordProns(), kaldi::ConvertAlignmentForPhone(), kaldi::ConvertAlignmentInternal(), kaldi::ConvertCompactLatticeToPhones(), kaldi::ConvertLatticeToPhones(), kaldi::ConvertPosteriorToPhones(), fst::DeterminizeLatticeInsertPhones(), OnlineFasterDecoder::EndOfUtterance(), OnlineSilenceWeighting::GetDeltaWeights(), kaldi::GetPdfToPhonesMap(), 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::TrailingSilenceLength(), kaldi::WeightSilencePost(), and kaldi::WeightSilencePostDistributed().

785  {
786  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
787  int32 trans_state = id2state_[trans_id];
788  return tuples_[trans_state-1].phone;
789 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
std::vector< int32 > id2state_
For each transition-id, the corresponding transition state (indexed by transition-id).
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionIdToTransitionIndex()

int32 TransitionIdToTransitionIndex ( int32  trans_id) const

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

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

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

280  {
281  KALDI_ASSERT(trans_id != 0 && static_cast<size_t>(trans_id) < id2state_.size());
282  return trans_id - state2id_[id2state_[trans_id]];
283 }
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:185

◆ TransitionIdToTransitionState()

int32 TransitionIdToTransitionState ( int32  trans_id) const

◆ TransitionStateToForwardPdf()

int32 TransitionStateToForwardPdf ( int32  trans_state) const

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

References KALDI_ASSERT, and TransitionModel::tuples_.

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

290  {
291  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
292  return tuples_[trans_state-1].forward_pdf;
293 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionStateToForwardPdfClass()

int32 TransitionStateToForwardPdfClass ( int32  trans_state) const

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

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

Referenced by kaldi::ConvertAlignmentForPhone().

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

◆ TransitionStateToHmmState()

int32 TransitionStateToHmmState ( int32  trans_state) const

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

References KALDI_ASSERT, and TransitionModel::tuples_.

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

320  {
321  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
322  return tuples_[trans_state-1].hmm_state;
323 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionStateToPhone()

int32 TransitionStateToPhone ( int32  trans_state) const

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

References KALDI_ASSERT, and TransitionModel::tuples_.

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

285  {
286  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
287  return tuples_[trans_state-1].phone;
288 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionStateToSelfLoopPdf()

int32 TransitionStateToSelfLoopPdf ( int32  trans_state) const

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

References KALDI_ASSERT, and TransitionModel::tuples_.

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

315  {
316  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
317  return tuples_[trans_state-1].self_loop_pdf;
318 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TransitionStateToSelfLoopPdfClass()

int32 TransitionStateToSelfLoopPdfClass ( int32  trans_state) const

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

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

Referenced by kaldi::ConvertAlignmentForPhone().

306  {
307  KALDI_ASSERT(static_cast<size_t>(trans_state) <= tuples_.size());
308  const Tuple &t = tuples_[trans_state-1];
309  const HmmTopology::TopologyEntry &entry = topo_.TopologyForPhone(t.phone);
310  KALDI_ASSERT(static_cast<size_t>(t.hmm_state) < entry.size());
311  return entry[t.hmm_state].self_loop_pdf_class;
312 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
std::vector< HmmState > TopologyEntry
TopologyEntry is a typedef that represents the topology of a single (prototype) state.
Definition: hmm-topology.h:133
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ TupleToTransitionState()

int32 TupleToTransitionState ( int32  phone,
int32  hmm_state,
int32  pdf,
int32  self_loop_pdf 
) const

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

References KALDI_ERR, and TransitionModel::tuples_.

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

254  {
255  Tuple tuple(phone, hmm_state, pdf, self_loop_pdf);
256  // Note: if this ever gets too expensive, which is unlikely, we can refactor
257  // this code to sort first on pdf, and then index on pdf, so those
258  // that have the same pdf are in a contiguous range.
259  std::vector<Tuple>::const_iterator iter =
260  std::lower_bound(tuples_.begin(), tuples_.end(), tuple);
261  if (iter == tuples_.end() || !(*iter == tuple)) {
262  KALDI_ERR << "TransitionModel::TupleToTransitionState, tuple not found."
263  << " (incompatible tree and model?)";
264  }
265  // tuples_ is indexed by transition_state-1, so add one.
266  return static_cast<int32>((iter - tuples_.begin())) + 1;
267 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ Write()

void Write ( std::ostream &  os,
bool  binary 
) const

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

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

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

422  {
423  bool is_hmm = IsHmm();
424  WriteToken(os, binary, "<TransitionModel>");
425  if (!binary) os << "\n";
426  topo_.Write(os, binary);
427  if (is_hmm)
428  WriteToken(os, binary, "<Triples>");
429  else
430  WriteToken(os, binary, "<Tuples>");
431  WriteBasicType(os, binary, static_cast<int32>(tuples_.size()));
432  if (!binary) os << "\n";
433  for (int32 i = 0; i < static_cast<int32> (tuples_.size()); i++) {
434  WriteBasicType(os, binary, tuples_[i].phone);
435  WriteBasicType(os, binary, tuples_[i].hmm_state);
436  WriteBasicType(os, binary, tuples_[i].forward_pdf);
437  if (!is_hmm)
438  WriteBasicType(os, binary, tuples_[i].self_loop_pdf);
439  if (!binary) os << "\n";
440  }
441  if (is_hmm)
442  WriteToken(os, binary, "</Triples>");
443  else
444  WriteToken(os, binary, "</Tuples>");
445  if (!binary) os << "\n";
446  WriteToken(os, binary, "<LogProbs>");
447  if (!binary) os << "\n";
448  log_probs_.Write(os, binary);
449  WriteToken(os, binary, "</LogProbs>");
450  if (!binary) os << "\n";
451  WriteToken(os, binary, "</TransitionModel>");
452  if (!binary) os << "\n";
453 }
std::vector< Tuple > tuples_
Tuples indexed by transition state minus one; the tuples are in sorted order which allows us to do th...
kaldi::int32 int32
Vector< BaseFloat > log_probs_
For each transition-id, the corresponding log-prob. Indexed by transition-id.
void Write(std::ostream &os, bool binary) const
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

◆ id2pdf_id_

std::vector<int32> id2pdf_id_
private

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

Referenced by TransitionModel::ComputeDerived().

◆ id2state_

◆ log_probs_

◆ non_self_loop_log_probs_

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 317 of file transition-model.h.

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

◆ num_pdfs_

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 322 of file transition-model.h.

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

◆ state2id_

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 304 of file transition-model.h.

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

◆ topo_

◆ tuples_


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