fgmm-global-init-from-accs.cc
Go to the documentation of this file.
1 // fgmmbin/fgmm-global-init-from-accs.cc
2 
3 // Copyright 2015-2017 David Snyder
4 // 2015 Johns Hopkins University (Author: Daniel Povey)
5 // 2015 Johns Hopkins University (Author: Daniel Garcia-Romero)
6 
7 // See ../../COPYING for clarification regarding multiple authors
8 //
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 //
13 // http://www.apache.org/licenses/LICENSE-2.0
14 //
15 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
17 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
18 // MERCHANTABLITY OR NON-INFRINGEMENT.
19 // See the Apache 2 License for the specific language governing permissions and
20 // limitations under the License.
21 
22 #include "base/kaldi-common.h"
23 #include "util/common-utils.h"
24 #include "gmm/full-gmm.h"
25 #include "gmm/mle-full-gmm.h"
26 
27 int main(int argc, char *argv[]) {
28  try {
29  using namespace kaldi;
30  typedef int32 int32;
31  MleFullGmmOptions gmm_opts;
32 
33  const char *usage =
34  "Initialize a full-covariance GMM from the accumulated stats.\n"
35  "This binary is similar to fgmm-global-est, but does not use "
36  "a preexisting model. See also fgmm-global-est.\n"
37  "Usage: fgmm-global-init-from-accs [options] <stats-in> "
38  "<number-of-components> <model-out>\n";
39 
40  bool binary_write = true;
41  ParseOptions po(usage);
42  po.Register("binary", &binary_write, "Write output in binary mode");
43  gmm_opts.Register(&po);
44 
45  po.Read(argc, argv);
46 
47  if (po.NumArgs() != 3) {
48  po.PrintUsage();
49  exit(1);
50  }
51 
52  std::string stats_filename = po.GetArg(1),
53  model_out_filename = po.GetArg(3);
54  int32 num_components = atoi(po.GetArg(2).c_str());
55 
56  AccumFullGmm gmm_accs;
57  {
58  bool binary;
59  Input ki(stats_filename, &binary);
60  gmm_accs.Read(ki.Stream(), binary, true /* add accs. */);
61  }
62 
63  int32 num_gauss = gmm_accs.NumGauss(), dim = gmm_accs.Dim(),
64  tot_floored = 0, gauss_floored = 0, tot_low_occ = 0;
65 
66  FullGmm fgmm(num_components, dim);
67 
68  Vector<BaseFloat> weights(num_gauss);
69  Matrix<BaseFloat> means(num_gauss, dim);
70  std::vector<SpMatrix<BaseFloat> > invcovars;
71 
72  for (int32 i = 0; i < num_components; i++) {
73  BaseFloat occ = gmm_accs.occupancy()(i);
74  weights(i) = occ;
75  Vector<BaseFloat> mean(dim, kSetZero);
76  SpMatrix<BaseFloat> covar(dim, kSetZero);
77 
78  // If the occupancy for a Gaussian is very low, set it to a small value.
79  if (occ < 1e-10) {
80  weights(i) = 1e-10;
81  mean.SetRandn();
82  Vector<BaseFloat> diag(mean.Dim());
83  diag.Set(1.0);
84  covar.AddDiagVec(1.0, diag);
85  tot_low_occ++;
86  // This is the typical case.
87  } else {
88  mean.CopyRowFromMat(gmm_accs.mean_accumulator(), i);
89  mean.Scale(1.0 / occ);
90  covar.CopyFromSp(gmm_accs.covariance_accumulator()[i]);
91  covar.Scale(1.0 / occ);
92  covar.AddVec2(-1.0, mean); // subtract squared means.
93  }
94  means.CopyRowFromVec(mean, i);
95 
96  // Floor variance Eigenvalues.
97  BaseFloat floor = std::max(
98  static_cast<BaseFloat>(gmm_opts.variance_floor),
99  static_cast<BaseFloat>(covar.MaxAbsEig() / gmm_opts.max_condition));
100  int32 floored = covar.ApplyFloor(floor);
101  if (floored) {
102  tot_floored += floored;
103  gauss_floored++;
104  }
105  covar.InvertDouble();
106  invcovars.push_back(covar);
107  }
108  weights.Scale(1.0 / weights.Sum());
109  fgmm.SetWeights(weights);
110  fgmm.SetInvCovarsAndMeans(invcovars, means);
111  int32 num_bad = fgmm.ComputeGconsts();
112  KALDI_LOG << "FullGmm has " << num_bad << " bad GConsts";
113 
114  if (tot_floored > 0) {
115  KALDI_WARN << tot_floored << " variances floored in " << gauss_floored
116  << " Gaussians.";
117  }
118  if (tot_low_occ > 0) {
119  KALDI_WARN << tot_low_occ << " out of " << num_gauss
120  << " Gaussians had very low occupancy.";
121  }
122 
123  WriteKaldiObject(fgmm, model_out_filename, binary_write);
124 
125  KALDI_LOG << "Written model to " << model_out_filename;
126  } catch(const std::exception &e) {
127  std::cerr << e.what() << '\n';
128  return -1;
129  }
130 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void SetWeights(const Vector< Real > &w)
Mutators for both float or double.
Definition: full-gmm-inl.h:31
Packed symetric matrix class.
Definition: matrix-common.h:62
void Scale(Real c)
Configuration variables like variance floor, minimum occupancy, etc.
Definition: mle-full-gmm.h:38
int32 ComputeGconsts()
Sets the gconsts.
Definition: full-gmm.cc:92
Definition for Gaussian Mixture Model with full covariances.
Definition: full-gmm.h:40
void PrintUsage(bool print_command_line=false)
Prints the usage documentation [provided in the constructor].
void InvertDouble(Real *logdet=NULL, Real *det_sign=NULL, bool inverse_needed=true)
Definition: sp-matrix.cc:312
void SetInvCovarsAndMeans(const std::vector< SpMatrix< Real > > &invcovars, const Matrix< Real > &means)
Use SetInvCovarsAndMeans if updating both means and (inverse) covariances.
Definition: full-gmm-inl.h:50
kaldi::int32 int32
BaseFloat variance_floor
Floor on eigenvalues of covariance matrices.
Definition: mle-full-gmm.h:44
void CopyFromSp(const SpMatrix< Real > &other)
Definition: sp-matrix.h:85
void CopyRowFromMat(const MatrixBase< Real > &M, MatrixIndexT row)
Extracts a row of the matrix M.
void Register(const std::string &name, bool *ptr, const std::string &doc)
int ApplyFloor(const SpMatrix< Real > &Floor, Real alpha=1.0, bool verbose=false)
Floors this symmetric matrix to the matrix alpha * Floor, where the matrix Floor is positive definite...
Definition: sp-matrix.cc:536
void AddVec2(const Real alpha, const VectorBase< OtherReal > &v)
rank-one update, this <– this + alpha v v&#39;
Definition: sp-matrix.cc:946
std::istream & Stream()
Definition: kaldi-io.cc:826
float BaseFloat
Definition: kaldi-types.h:29
int main(int argc, char *argv[])
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
Definition: parse-options.h:36
void Register(OptionsItf *opts)
Definition: mle-full-gmm.h:56
int Read(int argc, const char *const *argv)
Parses the command line options and fills the ParseOptions-registered variables.
Class for computing the maximum-likelihood estimates of the parameters of a Gaussian mixture model...
Definition: mle-full-gmm.h:74
#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.
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
void Scale(Real alpha)
Multiplies all elements by this constant.
Real Sum() const
Returns sum of the elements.
void SetRandn()
Set vector to random normally-distributed noise.
int NumArgs() const
Number of positional parameters (c.f. argc-1).
A class representing a vector.
Definition: kaldi-vector.h:406
void CopyRowFromVec(const VectorBase< Real > &v, const MatrixIndexT row)
Copy vector into specific row of matrix.
void WriteKaldiObject(const C &c, const std::string &filename, bool binary)
Definition: kaldi-io.h:257
BaseFloat max_condition
Maximum condition number of covariance matrices (apply floor to eigenvalues if they pass this)...
Definition: mle-full-gmm.h:47
#define KALDI_LOG
Definition: kaldi-error.h:153
Real MaxAbsEig() const
Returns the maximum of the absolute values of any of the eigenvalues.
Definition: sp-matrix.cc:67
void AddDiagVec(const Real alpha, const VectorBase< OtherReal > &v)
diagonal update, this <– this + diag(v)
Definition: sp-matrix.cc:183