lattice-confidence.cc
Go to the documentation of this file.
1 // latbin/lattice-confidence.cc
2 
3 // Copyright 2013 Johns Hopkins University (Author: Daniel Povey)
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 
21 #include "base/kaldi-common.h"
22 #include "util/common-utils.h"
23 #include "fstext/fstext-lib.h"
24 #include "lat/kaldi-lattice.h"
25 #include "lat/lattice-functions.h"
26 #include "lat/confidence.h"
27 
28 int main(int argc, char *argv[]) {
29  try {
30  using namespace kaldi;
31  typedef kaldi::int32 int32;
32  typedef kaldi::int64 int64;
33 
34  using fst::VectorFst;
35  using fst::StdArc;
36  typedef StdArc::StateId StateId;
37 
38  const char *usage =
39  "Compute sentence-level lattice confidence measures for each lattice.\n"
40  "The output is simly the difference between the total costs of the best and\n"
41  "second-best paths in the lattice (or a very large value if the lattice\n"
42  "had only one path). Caution: this is not necessarily a very good confidence\n"
43  "measure. You almost certainly want to specify the acoustic scale.\n"
44  "If the input is a state-level lattice, you need to specify\n"
45  "--read-compact-lattice=false, or the confidences will be very small\n"
46  "(and wrong). You can get word-level confidence info from lattice-mbr-decode.\n"
47  "\n"
48  "Usage: lattice-confidence <lattice-rspecifier> <confidence-wspecifier>\n"
49  "E.g.: lattice-confidence --acoustic-scale=0.08333 ark:- ark,t:-\n";
50 
51  ParseOptions po(usage);
52 
53  bool read_compact_lattice = true;
54  kaldi::BaseFloat acoustic_scale = 1.0, lm_scale = 1.0;
55  po.Register("acoustic-scale", &acoustic_scale,
56  "Scaling factor for acoustic likelihoods");
57  po.Register("lm-scale", &lm_scale,
58  "Scaling factor for \"graph costs\" (including LM costs)");
59  po.Register("read-compact-lattice", &read_compact_lattice,
60  "If true, read CompactLattice format; else, read Lattice format "
61  "(necessary for state-level lattices that were written in that "
62  "format).");
63 
64  po.Read(argc, argv);
65 
66  if (po.NumArgs() != 2) {
67  po.PrintUsage();
68  exit(1);
69  }
70 
71  std::string lats_rspecifier = po.GetArg(1);
72  std::string confidence_wspecifier = po.GetArg(2);
73 
74  BaseFloatWriter confidence_writer(confidence_wspecifier);
75 
76  // Output this instead of infinity; I/O for infinity can be problematic.
77  const BaseFloat max_output = 1.0e+10;
78 
79  int64 num_done = 0, num_empty = 0,
80  num_one_sentence = 0, num_same_sentence = 0;
81  double sum_neg_exp = 0.0;
82 
83 
84  if (read_compact_lattice) {
85  SequentialCompactLatticeReader clat_reader(lats_rspecifier);
86 
87  for (; !clat_reader.Done(); clat_reader.Next()) {
88  CompactLattice clat = clat_reader.Value();
89  std::string key = clat_reader.Key();
90  // FreeCurrent() is an optimization that prevents the lattice from being
91  // copied unnecessarily (OpenFst does copy-on-write).
92  clat_reader.FreeCurrent();
93  if (acoustic_scale != 1.0 || lm_scale != 1.0)
94  fst::ScaleLattice(fst::LatticeScale(lm_scale, acoustic_scale), &clat);
95 
96  int32 num_paths;
97  std::vector<int32> best_sentence, second_best_sentence;
98  BaseFloat confidence;
99  confidence = SentenceLevelConfidence(clat, &num_paths,
100  &best_sentence,
101  &second_best_sentence);
102  if (num_paths == 0) {
103  KALDI_WARN << "Lattice for utterance " << key << " is equivalent to "
104  << "the empty lattice.";
105  num_empty++;
106  continue;
107  } else if (num_paths == 1) {
108  num_one_sentence++;
109  } else if (num_paths == 2 && best_sentence == second_best_sentence) {
110  KALDI_WARN << "Best and second-best sentences were identical: "
111  << "confidence is meaningless. You should call with "
112  << "--read-compact-lattice=false.";
113  num_same_sentence++;
114  }
115  num_done++;
116  confidence = std::min(max_output, confidence); // disallow infinity.
117  sum_neg_exp += Exp(-confidence); // diagnostic.
118  confidence_writer.Write(key, confidence);
119  }
120  } else {
121  SequentialLatticeReader lat_reader(lats_rspecifier);
122 
123  for (; !lat_reader.Done(); lat_reader.Next()) {
124  Lattice lat = lat_reader.Value();
125  std::string key = lat_reader.Key();
126  // FreeCurrent() is an optimization that prevents the lattice from being
127  // copied unnecessarily (OpenFst does copy-on-write).
128  lat_reader.FreeCurrent();
129  if (acoustic_scale != 1.0 || lm_scale != 1.0)
130  fst::ScaleLattice(fst::LatticeScale(lm_scale, acoustic_scale), &lat);
131  int32 num_paths;
132  std::vector<int32> best_sentence, second_best_sentence;
133  BaseFloat confidence;
134  confidence = SentenceLevelConfidence(lat, &num_paths,
135  &best_sentence,
136  &second_best_sentence);
137  if (num_paths == 0) {
138  KALDI_WARN << "Lattice for utterance " << key << " is equivalent to "
139  << "the empty lattice.";
140  num_empty++;
141  continue;
142  } else if (num_paths == 1) {
143  num_one_sentence++;
144  } else if (num_paths == 2 && best_sentence == second_best_sentence) {
145  // This would be an error in some algorithm, in this case.
146  KALDI_ERR << "Best and second-best sentences were identical.";
147  }
148  num_done++;
149  confidence = std::min(max_output, confidence); // disallow infinity.
150  sum_neg_exp += Exp(-confidence); // diagnostic.
151  confidence_writer.Write(key, confidence);
152  }
153  }
154 
155  KALDI_LOG << "Done " << num_done << " lattices, of which "
156  << num_one_sentence << " contained only one sentence. "
157  << num_empty << " were equivalent to the empty lattice.";
158  if (num_done != 0)
159  KALDI_LOG << "Average confidence (averaged in negative-log space) is "
160  << -Log(sum_neg_exp / num_done);
161 
162  if (num_same_sentence != 0) {
163  KALDI_WARN << num_same_sentence << " lattices had the same sentence on "
164  << "different paths (likely an error)";
165  return 1;
166  }
167  return (num_done != 0 ? 0 : 1);
168  } catch (const std::exception &e) {
169  std::cerr << e.what();
170  return -1;
171  }
172 }
fst::StdArc::StateId StateId
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
double Exp(double x)
Definition: kaldi-math.h:83
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
Lattice::StateId StateId
void PrintUsage(bool print_command_line=false)
Prints the usage documentation [provided in the constructor].
fst::StdArc StdArc
int main(int argc, char *argv[])
A templated class for writing objects to an archive or script file; see The Table concept...
Definition: kaldi-table.h:368
kaldi::int32 int32
void Write(const std::string &key, const T &value) const
void Register(const std::string &name, bool *ptr, const std::string &doc)
float BaseFloat
Definition: kaldi-types.h:29
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
Definition: parse-options.h:36
double Log(double x)
Definition: kaldi-math.h:100
void ScaleLattice(const std::vector< std::vector< ScaleFloat > > &scale, MutableFst< ArcTpl< Weight > > *fst)
Scales the pairs of weights in LatticeWeight or CompactLatticeWeight by viewing the pair (a...
A templated class for reading objects sequentially from an archive or script file; see The Table conc...
Definition: kaldi-table.h:287
std::vector< std::vector< double > > LatticeScale(double lmwt, double acwt)
fst::VectorFst< LatticeArc > Lattice
Definition: kaldi-lattice.h:44
int Read(int argc, const char *const *argv)
Parses the command line options and fills the ParseOptions-registered variables.
#define KALDI_ERR
Definition: kaldi-error.h:147
#define KALDI_WARN
Definition: kaldi-error.h:150
std::string GetArg(int param) const
Returns one of the positional parameters; 1-based indexing for argc/argv compatibility.
fst::VectorFst< CompactLatticeArc > CompactLattice
Definition: kaldi-lattice.h:46
int NumArgs() const
Number of positional parameters (c.f. argc-1).
#define KALDI_LOG
Definition: kaldi-error.h:153