hmm-topology.h
Go to the documentation of this file.
1 // hmm/hmm-topology.h
2 
3 // Copyright 2009-2011 Microsoft Corporation
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 #ifndef KALDI_HMM_HMM_TOPOLOGY_H_
21 #define KALDI_HMM_HMM_TOPOLOGY_H_
22 
23 #include "base/kaldi-common.h"
24 #include "util/const-integer-set.h"
25 
26 
27 namespace kaldi {
28 
29 
32 
33 /*
34  // The following would be the text form for the "normal" HMM topology.
35  // Note that the first state is the start state, and the final state,
36  // which must have no output transitions and must be nonemitting, has
37  // an exit probability of one (no other state can have nonzero exit
38  // probability; you can treat the transition probability to the final
39  // state as an exit probability).
40  // Note also that it's valid to omit the "<PdfClass>" entry of the <State>, which
41  // will mean we won't have a pdf on that state [non-emitting state]. This is equivalent
42  // to setting the <PdfClass> to -1. We do this normally just for the final state.
43  // The Topology object can have multiple <TopologyEntry> blocks.
44  // This is useful if there are multiple types of topology in the system.
45 
46  <Topology>
47  <TopologyEntry>
48  <ForPhones> 1 2 3 4 5 6 7 8 </ForPhones>
49  <State> 0 <PdfClass> 0
50  <Transition> 0 0.5
51  <Transition> 1 0.5
52  </State>
53  <State> 1 <PdfClass> 1
54  <Transition> 1 0.5
55  <Transition> 2 0.5
56  </State>
57  <State> 2 <PdfClass> 2
58  <Transition> 2 0.5
59  <Transition> 3 0.5
60  <Final> 0.5
61  </State>
62  <State> 3
63  </State>
64  </TopologyEntry>
65  </Topology>
66 */
67 
68 // kNoPdf is used where pdf_class or pdf would be used, to indicate,
69 // none is there. Mainly useful in skippable models, but also used
70 // for end states.
71 // A caveat with nonemitting states is that their out-transitions
72 // are not trainable, due to technical issues with the way
73 // we decided to accumulate the stats. Any transitions arising from (*)
74 // HMM states with "kNoPdf" as the label are second-class transitions,
75 // They do not have "transition-states" or "transition-ids" associated
76 // with them. They are used to create the FST version of the
77 // HMMs, where they lead to epsilon arcs.
78 // (*) "arising from" is a bit of a technical term here, due to the way
79 // (if reorder == true), we put the transition-id associated with the
80 // outward arcs of the state, on the input transition to the state.
81 
85 
86 static const int32 kNoPdf = -1;
87 
92 
93 class HmmTopology {
94  public:
96  struct HmmState {
101 
105 
109  std::vector<std::pair<int32, BaseFloat> > transitions;
110 
111  explicit HmmState(int32 pdf_class) {
112  this->forward_pdf_class = pdf_class;
113  this->self_loop_pdf_class = pdf_class;
114  }
115  explicit HmmState(int32 forward_pdf_class, int32 self_loop_pdf_class) {
116  KALDI_ASSERT((forward_pdf_class != kNoPdf && self_loop_pdf_class != kNoPdf) ||
117  (forward_pdf_class == kNoPdf && self_loop_pdf_class == kNoPdf));
118  this->forward_pdf_class = forward_pdf_class;
119  this->self_loop_pdf_class = self_loop_pdf_class;
120  }
121 
122  bool operator == (const HmmState &other) const {
123  return (forward_pdf_class == other.forward_pdf_class &&
124  self_loop_pdf_class == other.self_loop_pdf_class &&
125  transitions == other.transitions);
126  }
127 
128  HmmState(): forward_pdf_class(-1), self_loop_pdf_class(-1) { }
129  };
130 
133  typedef std::vector<HmmState> TopologyEntry;
134 
135  void Read(std::istream &is, bool binary);
136  void Write(std::ostream &os, bool binary) const;
137 
138  // Checks that the object is valid, and throw exception otherwise.
139  void Check();
140 
149  bool IsHmm() const;
150 
153  const TopologyEntry &TopologyForPhone(int32 phone) const;
154 
157  int32 NumPdfClasses(int32 phone) const;
158 
163  const std::vector<int32> &GetPhones() const { return phones_; };
164 
168  void GetPhoneToNumPdfClasses(std::vector<int32> *phone2num_pdf_classes) const;
169 
170  // Returns the minimum number of frames it takes to traverse this model for
171  // this phone: e.g. 3 for the normal HMM topology.
172  int32 MinLength(int32 phone) const;
173 
175 
176  bool operator == (const HmmTopology &other) const {
177  return phones_ == other.phones_ && phone2idx_ == other.phone2idx_
178  && entries_ == other.entries_;
179  }
180  // Allow default assignment operator and copy constructor.
181  private:
182  std::vector<int32> phones_; // list of all phones we have topology for. Sorted, uniq. no epsilon (zero) phone.
183  std::vector<int32> phone2idx_; // map from phones to indexes into the entries vector (or -1 for not present).
184  std::vector<TopologyEntry> entries_;
185 };
186 
187 
189 
190 
191 } // end namespace kaldi
192 
193 
194 #endif
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
A structure defined inside HmmTopology to represent a HMM state.
Definition: hmm-topology.h:96
HmmState(int32 forward_pdf_class, int32 self_loop_pdf_class)
Definition: hmm-topology.h:115
A class for storing topology information for phones.
Definition: hmm-topology.h:93
bool IsHmm() const
Returns true if this HmmTopology is really &#39;hmm-like&#39;, i.e.
kaldi::int32 int32
void Read(std::istream &is, bool binary)
Definition: hmm-topology.cc:39
bool operator==(const HmmState &other) const
Definition: hmm-topology.h:122
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
std::vector< int32 > phones_
Definition: hmm-topology.h:182
int32 NumPdfClasses(int32 phone) const
Returns the number of pdf-classes for this phone; throws exception if phone not covered by this topol...
void Write(std::ostream &os, bool binary) const
const TopologyEntry & TopologyForPhone(int32 phone) const
Returns the topology entry (i.e.
std::vector< std::pair< int32, BaseFloat > > transitions
A list of transitions, indexed by what we call a &#39;transition-index&#39;.
Definition: hmm-topology.h:109
std::vector< TopologyEntry > entries_
Definition: hmm-topology.h:184
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
std::vector< int32 > phone2idx_
Definition: hmm-topology.h:183
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
int32 forward_pdf_class
The Pdf-classes forward-pdf-class, typically 0, 1 or 2 (the same as the HMM-state index)...
Definition: hmm-topology.h:100
int32 MinLength(int32 phone) const
void GetPhoneToNumPdfClasses(std::vector< int32 > *phone2num_pdf_classes) const
Outputs a vector of int32, indexed by phone, that gives the number of Pdf-classes pdf-classes for the...
Definition: hmm-topology.cc:31
int32 self_loop_pdf_class
The Pdf-classes self-loop pdf-class, similar to Pdf-classes forward-pdf-class.
Definition: hmm-topology.h:104