confidence.cc
Go to the documentation of this file.
1 // lat/confidence.cc
2
3 // Copyright 2013 Johns Hopkins University (Author: Daniel Povey)
4
5 // See ../../COPYING for clarification regarding multiple authors
6 //
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
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 #include "lat/confidence.h"
21 #include "lat/lattice-functions.h"
23
24 namespace kaldi {
25
27  int32 *num_paths,
28  std::vector<int32> *best_sentence,
29  std::vector<int32> *second_best_sentence) {
30  /* It may seem strange that the first thing we do is to convert the
31  CompactLattice to a Lattice, given that we may have just created the
32  CompactLattice by determinizing a Lattice. However, this is not just
33  a circular conversion; "lat" will have the property that distinct
34  paths have distinct word sequences.
35  Below, we could run NbestAsFsts on a CompactLattice, but the time
36  taken would be quadratic in the length in words of the CompactLattice,
37  because of the alignment information getting appended as vectors.
38  That's why we convert back to Lattice.
39  */
40  Lattice lat;
41  ConvertLattice(clat, &lat);
42
43  std::vector<Lattice> lats;
44  NbestAsFsts(lat, 2, &lats);
45  int32 n = lats.size();
46  KALDI_ASSERT(n >= 0 && n <= 2);
47  if (num_paths != NULL) *num_paths = n;
48  if (best_sentence != NULL) best_sentence->clear();
49  if (second_best_sentence != NULL) second_best_sentence->clear();
50
51  LatticeWeight weight1, weight2;
52  if (n >= 1)
53  fst::GetLinearSymbolSequence<LatticeArc,int32>(lats[0], NULL,
54  best_sentence,
55  &weight1);
56  if (n >= 2)
57  fst::GetLinearSymbolSequence<LatticeArc,int32>(lats[1], NULL,
58  second_best_sentence,
59  &weight2);
60
61  if (n == 0) {
62  return 0; // this seems most appropriate because it will be interpreted as
63  // zero confidence, and something definitely went wrong for this
64  // to happen.
65  } else if (n == 1) {
66  // If there is only one sentence in the lattice, we interpret this as there
67  // being perfect confidence
68  return std::numeric_limits<BaseFloat>::infinity();
69  } else {
70  BaseFloat best_cost = ConvertToCost(weight1),
71  second_best_cost = ConvertToCost(weight2);
72  BaseFloat ans = second_best_cost - best_cost;
73  if (!(ans >= -0.001 * (fabs(best_cost) + fabs(second_best_cost)))) {
74  // Answer should be positive. Make sure it's at at least not
75  // substantially negative. This would be very strange.
76  KALDI_WARN << "Very negative difference." << ans;
77  }
78  if (ans < 0) ans = 0;
79  return ans;
80  }
81 }
82
83
84
86  int32 *num_paths,
87  std::vector<int32> *best_sentence,
88  std::vector<int32> *second_best_sentence) {
89  int32 max_sentence_length = LongestSentenceLength(lat);
90  fst::DeterminizeLatticePrunedOptions determinize_opts;
91  // The basic idea of expanding only up to "max_sentence_length * 2" arcs,
93  // through the lattice, which is all we need for this particular application.
94  // "safety_term" is just in case there is some reason why we might need a few
95  // extra arcs, e.g. in case of a tie on the weights of the second-best path.
96  int32 safety_term = 4 + max_sentence_length;
97  determinize_opts.max_arcs = max_sentence_length * 2 + safety_term;
98  // set prune_beam to a large value... we don't really rely on the beam; we
99  // rely on the max_arcs variable to limit the size of the lattice.
100  double prune_beam = std::numeric_limits<double>::infinity();
101
102  CompactLattice clat;
103  // We ignore the return status of DeterminizeLatticePruned. It will likely
104  // return false, but this is expected because the expansion is limited
105  // by "max_arcs" not "prune_beam".
106  Lattice inverse_lat(lat);
107  fst::Invert(&inverse_lat); // Swap input and output symbols.
108  DeterminizeLatticePruned(inverse_lat, prune_beam, &clat, determinize_opts);
109
110  // Call the version of this function that takes a CompactLattice.
111  return SentenceLevelConfidence(clat, num_paths,
112  best_sentence, second_best_sentence);
113 }
114
115
116
117 } // namespace kaldi
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
BaseFloat SentenceLevelConfidence(const CompactLattice &clat, int32 *num_paths, std::vector< int32 > *best_sentence, std::vector< int32 > *second_best_sentence)
Caution: this function is not the only way to get confidences in Kaldi.
Definition: confidence.cc:26
bool DeterminizeLatticePruned(const ExpandedFst< ArcTpl< Weight > > &ifst, double beam, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePrunedOptions opts)
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29
void NbestAsFsts(const Fst< Arc > &fst, size_t n, std::vector< VectorFst< Arc > > *fsts_out)
Takes the n-shortest-paths (using ShortestPath), but outputs the result as a vector of up to n fsts...
double ConvertToCost(const LatticeWeightTpl< Float > &w)
struct rnnlm::@11::@12 n
void ConvertLattice(const ExpandedFst< ArcTpl< Weight > > &ifst, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, Int > > > *ofst, bool invert)
Convert lattice from a normal FST to a CompactLattice FST.
fst::VectorFst< LatticeArc > Lattice
Definition: kaldi-lattice.h:44
#define KALDI_WARN
Definition: kaldi-error.h:150
fst::VectorFst< CompactLatticeArc > CompactLattice
Definition: kaldi-lattice.h:46
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
int32 LongestSentenceLength(const Lattice &lat)
This function returns the number of words in the longest sentence in a CompactLattice (i...