mle-diag-gmm.cc
Go to the documentation of this file.
1 // gmm/mle-diag-gmm.cc
2 
3 // Copyright 2009-2013 Saarland University; Georg Stemmer; Jan Silovsky;
4 // Microsoft Corporation; Yanmin Qian;
5 // Johns Hopkins University (author: Daniel Povey);
6 // Cisco Systems (author: Neha Agrawal)
7 
8 // See ../../COPYING for clarification regarding multiple authors
9 //
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 //
14 // http://www.apache.org/licenses/LICENSE-2.0
15 //
16 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
18 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
19 // MERCHANTABLITY OR NON-INFRINGEMENT.
20 // See the Apache 2 License for the specific language governing permissions and
21 // limitations under the License.
22 
23 #include <algorithm> // for std::max
24 #include <string>
25 #include <vector>
26 
27 #include "gmm/diag-gmm.h"
28 #include "gmm/mle-diag-gmm.h"
29 #include "util/kaldi-thread.h"
30 
31 namespace kaldi {
32 
33 void AccumDiagGmm::Read(std::istream &in_stream, bool binary, bool add) {
34  int32 dimension, num_components;
35  GmmFlagsType flags;
36  std::string token;
37 
38  ExpectToken(in_stream, binary, "<GMMACCS>");
39  ExpectToken(in_stream, binary, "<VECSIZE>");
40  ReadBasicType(in_stream, binary, &dimension);
41  ExpectToken(in_stream, binary, "<NUMCOMPONENTS>");
42  ReadBasicType(in_stream, binary, &num_components);
43  ExpectToken(in_stream, binary, "<FLAGS>");
44  ReadBasicType(in_stream, binary, &flags);
45 
46  if (add) {
47  if ((NumGauss() != 0 || Dim() != 0 || Flags() != 0)) {
48  if (num_components != NumGauss() || dimension != Dim()
49  || flags != Flags())
50  KALDI_ERR << "MlEstimatediagGmm::Read, dimension or flags mismatch, "
51  << NumGauss() << ", " << Dim() << ", "
52  << GmmFlagsToString(Flags()) << " vs. " << num_components << ", "
53  << dimension << ", " << flags << " (mixing accs from different "
54  << "models?";
55  } else {
56  Resize(num_components, dimension, flags);
57  }
58  } else {
59  Resize(num_components, dimension, flags);
60  }
61 
62  ReadToken(in_stream, binary, &token);
63  while (token != "</GMMACCS>") {
64  if (token == "<OCCUPANCY>") {
65  occupancy_.Read(in_stream, binary, add);
66  } else if (token == "<MEANACCS>") {
67  mean_accumulator_.Read(in_stream, binary, add);
68  } else if (token == "<DIAGVARACCS>") {
69  variance_accumulator_.Read(in_stream, binary, add);
70  } else {
71  KALDI_ERR << "Unexpected token '" << token << "' in model file ";
72  }
73  ReadToken(in_stream, binary, &token);
74  }
75 }
76 
77 void AccumDiagGmm::Write(std::ostream &out_stream, bool binary) const {
78  WriteToken(out_stream, binary, "<GMMACCS>");
79  WriteToken(out_stream, binary, "<VECSIZE>");
80  WriteBasicType(out_stream, binary, dim_);
81  WriteToken(out_stream, binary, "<NUMCOMPONENTS>");
82  WriteBasicType(out_stream, binary, num_comp_);
83  WriteToken(out_stream, binary, "<FLAGS>");
84  WriteBasicType(out_stream, binary, flags_);
85 
86  // convert into BaseFloat before writing things
87  Vector<BaseFloat> occupancy_bf(occupancy_.Dim());
88  Matrix<BaseFloat> mean_accumulator_bf(mean_accumulator_.NumRows(),
90  Matrix<BaseFloat> variance_accumulator_bf(variance_accumulator_.NumRows(),
92  occupancy_bf.CopyFromVec(occupancy_);
93  mean_accumulator_bf.CopyFromMat(mean_accumulator_);
94  variance_accumulator_bf.CopyFromMat(variance_accumulator_);
95 
96  WriteToken(out_stream, binary, "<OCCUPANCY>");
97  occupancy_bf.Write(out_stream, binary);
98  WriteToken(out_stream, binary, "<MEANACCS>");
99  mean_accumulator_bf.Write(out_stream, binary);
100  WriteToken(out_stream, binary, "<DIAGVARACCS>");
101  variance_accumulator_bf.Write(out_stream, binary);
102  WriteToken(out_stream, binary, "</GMMACCS>");
103 }
104 
105 
106 void AccumDiagGmm::Resize(int32 num_comp, int32 dim, GmmFlagsType flags) {
107  KALDI_ASSERT(num_comp > 0 && dim > 0);
108  num_comp_ = num_comp;
109  dim_ = dim;
110  flags_ = AugmentGmmFlags(flags);
111  occupancy_.Resize(num_comp);
112  if (flags_ & kGmmMeans)
113  mean_accumulator_.Resize(num_comp, dim);
114  else
116  if (flags_ & kGmmVariances)
117  variance_accumulator_.Resize(num_comp, dim);
118  else
120 }
121 
123  if (flags & ~flags_)
124  KALDI_ERR << "Flags in argument do not match the active accumulators";
125  if (flags & kGmmWeights) occupancy_.SetZero();
126  if (flags & kGmmMeans) mean_accumulator_.SetZero();
128 }
129 
130 
132  if (flags & ~flags_)
133  KALDI_ERR << "Flags in argument do not match the active accumulators";
134  double d = static_cast<double>(f);
135  if (flags & kGmmWeights) occupancy_.Scale(d);
136  if (flags & kGmmMeans) mean_accumulator_.Scale(d);
137  if (flags & kGmmVariances) variance_accumulator_.Scale(d);
138 }
139 
141  int32 comp_index, BaseFloat weight) {
142  if (flags_ & kGmmMeans)
143  KALDI_ASSERT(data.Dim() == Dim());
144  double wt = static_cast<double>(weight);
145  KALDI_ASSERT(comp_index < NumGauss());
146  // accumulate
147  occupancy_(comp_index) += wt;
148  if (flags_ & kGmmMeans) {
149  Vector<double> data_d(data); // Copy with type-conversion
150  mean_accumulator_.Row(comp_index).AddVec(wt, data_d);
151  if (flags_ & kGmmVariances) {
152  data_d.ApplyPow(2.0);
153  variance_accumulator_.Row(comp_index).AddVec(wt, data_d);
154  }
155  }
156 }
157 
159  double occ,
160  const VectorBase<double> &x_stats,
161  const VectorBase<double> &x2_stats) {
162  KALDI_ASSERT(g < NumGauss());
163  occupancy_(g) += occ;
164  if (flags_ & kGmmMeans)
165  mean_accumulator_.Row(g).AddVec(1.0, x_stats);
166  if (flags_ & kGmmVariances)
167  variance_accumulator_.Row(g).AddVec(1.0, x2_stats);
168 }
169 
170 
172  const VectorBase<BaseFloat> &data,
173  const VectorBase<BaseFloat> &posteriors) {
174  if (flags_ & kGmmMeans)
175  KALDI_ASSERT(static_cast<int32>(data.Dim()) == Dim());
176  KALDI_ASSERT(static_cast<int32>(posteriors.Dim()) == NumGauss());
177  Vector<double> post_d(posteriors); // Copy with type-conversion
178 
179  // accumulate
180  occupancy_.AddVec(1.0, post_d);
181  if (flags_ & kGmmMeans) {
182  Vector<double> data_d(data); // Copy with type-conversion
183  mean_accumulator_.AddVecVec(1.0, post_d, data_d);
184  if (flags_ & kGmmVariances) {
185  data_d.ApplyPow(2.0);
186  variance_accumulator_.AddVecVec(1.0, post_d, data_d);
187  }
188  }
189 }
190 
192  const VectorBase<BaseFloat> &data,
193  BaseFloat frame_posterior) {
194  KALDI_ASSERT(gmm.NumGauss() == NumGauss());
195  KALDI_ASSERT(gmm.Dim() == Dim());
196  KALDI_ASSERT(static_cast<int32>(data.Dim()) == Dim());
197 
198  Vector<BaseFloat> posteriors(NumGauss());
199  BaseFloat log_like = gmm.ComponentPosteriors(data, &posteriors);
200  posteriors.Scale(frame_posterior);
201 
202  AccumulateFromPosteriors(data, posteriors);
203  return log_like;
204 }
205 
206 // Careful: this wouldn't be valid if it were used to update the
207 // Gaussian weights.
209  Vector<double> smoothing_vec(occupancy_);
210  smoothing_vec.InvertElements();
211  smoothing_vec.Scale(static_cast<double>(tau));
212  smoothing_vec.Add(1.0);
213  // now smoothing_vec = (tau + occ) / occ
214 
215  mean_accumulator_.MulRowsVec(smoothing_vec);
216  variance_accumulator_.MulRowsVec(smoothing_vec);
217  occupancy_.Add(static_cast<double>(tau));
218 }
219 
220 
221 // want to add tau "virtual counts" of each Gaussian from "src_acc"
222 // to each Gaussian in this acc.
223 // Careful: this wouldn't be valid if it were used to update the
224 // Gaussian weights.
226  KALDI_ASSERT(src_acc.NumGauss() == num_comp_ && src_acc.Dim() == dim_);
227  for (int32 i = 0; i < num_comp_; i++) {
228  if (src_acc.occupancy_(i) != 0.0) { // can only smooth if src was nonzero...
229  occupancy_(i) += tau;
230  mean_accumulator_.Row(i).AddVec(tau / src_acc.occupancy_(i),
231  src_acc.mean_accumulator_.Row(i));
232  variance_accumulator_.Row(i).AddVec(tau / src_acc.occupancy_(i),
233  src_acc.variance_accumulator_.Row(i));
234  } else
235  KALDI_WARN << "Could not smooth since source acc had zero occupancy.";
236  }
237 }
238 
239 
241  KALDI_ASSERT(gmm.NumGauss() == num_comp_ && gmm.Dim() == dim_);
242  Matrix<double> means(num_comp_, dim_);
244  gmm.GetMeans(&means);
245  gmm.GetVars(&vars);
246 
247  mean_accumulator_.AddMat(tau, means);
248  means.ApplyPow(2.0);
249  vars.AddMat(1.0, means, kNoTrans);
250  variance_accumulator_.AddMat(tau, vars);
251 
252  occupancy_.Add(tau);
253 }
254 
256  : dim_(other.dim_), num_comp_(other.num_comp_),
257  flags_(other.flags_), occupancy_(other.occupancy_),
260 
262  const AccumDiagGmm &diag_gmm_acc) {
263  GmmFlagsType acc_flags = diag_gmm_acc.Flags();
264  Vector<BaseFloat> occ_bf(diag_gmm_acc.occupancy());
265  Matrix<BaseFloat> mean_accs_bf(diag_gmm_acc.mean_accumulator());
266  Matrix<BaseFloat> variance_accs_bf(diag_gmm_acc.variance_accumulator());
267  BaseFloat obj = VecVec(occ_bf, gmm.gconsts());
268  if (acc_flags & kGmmMeans)
269  obj += TraceMatMat(mean_accs_bf, gmm.means_invvars(), kTrans);
270  if (acc_flags & kGmmVariances)
271  obj -= 0.5 * TraceMatMat(variance_accs_bf, gmm.inv_vars(), kTrans);
272  return obj;
273 }
274 
276  const AccumDiagGmm &diag_gmm_acc,
277  GmmFlagsType flags,
278  DiagGmm *gmm,
279  BaseFloat *obj_change_out,
280  BaseFloat *count_out,
281  int32 *floored_elements_out,
282  int32 *floored_gaussians_out,
283  int32 *removed_gaussians_out) {
284  KALDI_ASSERT(gmm != NULL);
285 
286  if (flags & ~diag_gmm_acc.Flags())
287  KALDI_ERR << "Flags in argument do not match the active accumulators";
288 
289  KALDI_ASSERT(diag_gmm_acc.NumGauss() == gmm->NumGauss() &&
290  diag_gmm_acc.Dim() == gmm->Dim());
291 
292  int32 num_gauss = gmm->NumGauss();
293  double occ_sum = diag_gmm_acc.occupancy().Sum();
294 
295  int32 elements_floored = 0, gauss_floored = 0;
296 
297  // remember old objective value
298  gmm->ComputeGconsts();
299  BaseFloat obj_old = MlObjective(*gmm, diag_gmm_acc);
300 
301  // First get the gmm in "normal" representation (not the exponential-model
302  // form).
303  DiagGmmNormal ngmm(*gmm);
304 
305  std::vector<int32> to_remove;
306  for (int32 i = 0; i < num_gauss; i++) {
307  double occ = diag_gmm_acc.occupancy()(i);
308  double prob;
309  if (occ_sum > 0.0)
310  prob = occ / occ_sum;
311  else
312  prob = 1.0 / num_gauss;
313 
314  if (occ > static_cast<double>(config.min_gaussian_occupancy)
315  && prob > static_cast<double>(config.min_gaussian_weight)) {
316 
317  ngmm.weights_(i) = prob;
318 
319  // copy old mean for later normalizations
320  Vector<double> old_mean(ngmm.means_.Row(i));
321 
322  // update mean, then variance, as far as there are accumulators
323  if (diag_gmm_acc.Flags() & (kGmmMeans|kGmmVariances)) {
324  Vector<double> mean(diag_gmm_acc.mean_accumulator().Row(i));
325  mean.Scale(1.0 / occ);
326  // transfer to estimate
327  ngmm.means_.CopyRowFromVec(mean, i);
328  }
329 
330  if (diag_gmm_acc.Flags() & kGmmVariances) {
331  KALDI_ASSERT(diag_gmm_acc.Flags() & kGmmMeans);
332  Vector<double> var(diag_gmm_acc.variance_accumulator().Row(i));
333  var.Scale(1.0 / occ);
334  var.AddVec2(-1.0, ngmm.means_.Row(i)); // subtract squared means.
335 
336  // if we intend to only update the variances, we need to compensate by
337  // adding the difference between the new and old mean
338  if (!(flags & kGmmMeans)) {
339  old_mean.AddVec(-1.0, ngmm.means_.Row(i));
340  var.AddVec2(1.0, old_mean);
341  }
342  int32 floored;
343  if (config.variance_floor_vector.Dim() != 0) {
344  floored = var.ApplyFloor(config.variance_floor_vector);
345  } else {
346  var.ApplyFloor(config.min_variance, &floored);
347  }
348  if (floored != 0) {
349  elements_floored += floored;
350  gauss_floored++;
351  }
352  // transfer to estimate
353  ngmm.vars_.CopyRowFromVec(var, i);
354  }
355  } else { // Insufficient occupancy.
356  if (config.remove_low_count_gaussians &&
357  static_cast<int32>(to_remove.size()) < num_gauss-1) {
358  // remove the component, unless it is the last one.
359  KALDI_WARN << "Too little data - removing Gaussian (weight "
360  << std::fixed << prob
361  << ", occupation count " << std::fixed << diag_gmm_acc.occupancy()(i)
362  << ", vector size " << gmm->Dim() << ")";
363  to_remove.push_back(i);
364  } else {
365  KALDI_WARN << "Gaussian has too little data but not removing it because"
366  << (config.remove_low_count_gaussians ?
367  " it is the last Gaussian: i = "
368  : " remove-low-count-gaussians == false: g = ") << i
369  << ", occ = " << diag_gmm_acc.occupancy()(i) << ", weight = " << prob;
370  ngmm.weights_(i) =
371  std::max(prob, static_cast<double>(config.min_gaussian_weight));
372  }
373  }
374  }
375 
376  // copy to natural representation according to flags
377  ngmm.CopyToDiagGmm(gmm, flags);
378 
379  gmm->ComputeGconsts(); // or MlObjective will fail.
380  BaseFloat obj_new = MlObjective(*gmm, diag_gmm_acc);
381 
382  if (obj_change_out)
383  *obj_change_out = (obj_new - obj_old);
384  if (count_out) *count_out = occ_sum;
385  if (floored_elements_out) *floored_elements_out = elements_floored;
386  if (floored_gaussians_out) *floored_gaussians_out = gauss_floored;
387 
388  if (to_remove.size() > 0) {
389  gmm->RemoveComponents(to_remove, true /*renormalize weights*/);
390  gmm->ComputeGconsts();
391  }
392  if (removed_gaussians_out != NULL) *removed_gaussians_out = to_remove.size();
393 
394  if (gauss_floored > 0)
395  KALDI_VLOG(2) << gauss_floored << " variances floored in " << gauss_floored
396  << " Gaussians.";
397 }
398 
399 void AccumDiagGmm::Add(double scale, const AccumDiagGmm &acc) {
400  // The functions called here will crash if the dimensions etc.
401  // or the flags don't match.
402  occupancy_.AddVec(scale, acc.occupancy_);
403  if (flags_ & kGmmMeans)
405  if (flags_ & kGmmVariances)
407 }
408 
409 
411  const AccumDiagGmm &diag_gmm_acc,
412  GmmFlagsType flags,
413  DiagGmm *gmm,
414  BaseFloat *obj_change_out,
415  BaseFloat *count_out) {
416  KALDI_ASSERT(gmm != NULL);
417 
418  if (flags & ~diag_gmm_acc.Flags())
419  KALDI_ERR << "Flags in argument do not match the active accumulators";
420 
421  KALDI_ASSERT(diag_gmm_acc.NumGauss() == gmm->NumGauss() &&
422  diag_gmm_acc.Dim() == gmm->Dim());
423 
424  int32 num_gauss = gmm->NumGauss();
425  double occ_sum = diag_gmm_acc.occupancy().Sum();
426 
427  // remember the old objective function value
428  gmm->ComputeGconsts();
429  BaseFloat obj_old = MlObjective(*gmm, diag_gmm_acc);
430 
431  // allocate the gmm in normal representation; all parameters of this will be
432  // updated, but only the flagged ones will be transferred back to gmm
433  DiagGmmNormal ngmm(*gmm);
434 
435  for (int32 i = 0; i < num_gauss; i++) {
436  double occ = diag_gmm_acc.occupancy()(i);
437 
438  // First update the weight. The weight_tau is a tau for the
439  // whole state.
440  ngmm.weights_(i) = (occ + ngmm.weights_(i) * config.weight_tau) /
441  (occ_sum + config.weight_tau);
442 
443 
444  if (occ > 0.0 && (flags & kGmmMeans)) {
445  // Update the Gaussian mean.
446  Vector<double> old_mean(ngmm.means_.Row(i));
447  Vector<double> mean(diag_gmm_acc.mean_accumulator().Row(i));
448  mean.Scale(1.0 / (occ + config.mean_tau));
449  mean.AddVec(config.mean_tau / (occ + config.mean_tau), old_mean);
450  ngmm.means_.CopyRowFromVec(mean, i);
451  }
452 
453  if (occ > 0.0 && (flags & kGmmVariances)) {
454  // Computing the variance around the updated mean; this is:
455  // E( (x - mu)^2 ) = E( x^2 - 2 x mu + mu^2 ) =
456  // E(x^2) + mu^2 - 2 mu E(x).
457  Vector<double> old_var(ngmm.vars_.Row(i));
458  Vector<double> var(diag_gmm_acc.variance_accumulator().Row(i));
459  var.Scale(1.0 / occ);
460  var.AddVec2(1.0, ngmm.means_.Row(i));
461  SubVector<double> mean_acc(diag_gmm_acc.mean_accumulator(), i),
462  mean(ngmm.means_, i);
463  var.AddVecVec(-2.0 / occ, mean_acc, mean, 1.0);
464  // now var is E(x^2) + m^2 - 2 mu E(x).
465  // Next we do the appropriate weighting usnig the tau value.
466  var.Scale(occ / (config.variance_tau + occ));
467  var.AddVec(config.variance_tau / (config.variance_tau + occ), old_var);
468  // Now write to the model.
469  ngmm.vars_.Row(i).CopyFromVec(var);
470  }
471  }
472 
473  // Copy to natural/exponential representation.
474  ngmm.CopyToDiagGmm(gmm, flags);
475 
476  gmm->ComputeGconsts(); // or MlObjective will fail.
477  BaseFloat obj_new = MlObjective(*gmm, diag_gmm_acc);
478 
479  if (obj_change_out)
480  *obj_change_out = (obj_new - obj_old);
481 
482  if (count_out) *count_out = occ_sum;
483 }
484 
485 
487  public:
489  const MatrixBase<BaseFloat> &data,
490  const VectorBase<BaseFloat> &frame_weights,
491  AccumDiagGmm *accum,
492  double *tot_like):
493  diag_gmm_(diag_gmm), data_(data),
494  frame_weights_(frame_weights), dest_accum_(accum),
495  tot_like_ptr_(tot_like), tot_like_(0.0) { }
497  MultiThreadable(other),
498  diag_gmm_(other.diag_gmm_), data_(other.data_),
499  frame_weights_(other.frame_weights_), dest_accum_(other.dest_accum_),
500  accum_(diag_gmm_, dest_accum_->Flags()), tot_like_ptr_(other.tot_like_ptr_),
501  tot_like_(0.0) {
502  KALDI_ASSERT(data_.NumRows() == frame_weights_.Dim());
503  }
504  void operator () () {
505  int32 num_frames = data_.NumRows(), num_threads = num_threads_,
506  block_size = (num_frames + num_threads - 1) / num_threads,
507  block_start = block_size * thread_id_,
508  block_end = std::min(num_frames, block_start + block_size);
509  tot_like_ = 0.0;
510  double tot_weight = 0.0;
511  for (int32 t = block_start; t < block_end; t++) {
512  tot_like_ += frame_weights_(t) *
513  accum_.AccumulateFromDiag(diag_gmm_, data_.Row(t), frame_weights_(t));
514  tot_weight += frame_weights_(t);
515  }
516  KALDI_VLOG(3) << "Thread " << thread_id_ << " saw average likeliood/frame "
517  << (tot_like_ / tot_weight) << " over " << tot_weight
518  << " (weighted) frames.";
519  }
521  if (accum_.Dim() != 0) { // if our accumulator is set up (this is not true
522  // for the single object we use to initialize the others)
523  dest_accum_->Add(1.0, accum_);
524  *tot_like_ptr_ += tot_like_;
525  }
526  }
527  private:
533  double *tot_like_ptr_;
534  double tot_like_;
535 };
536 
537 
539  const DiagGmm &gmm,
540  const MatrixBase<BaseFloat> &data,
541  const VectorBase<BaseFloat> &frame_weights,
542  int32 num_threads) {
543 
544  double tot_like = 0.0;
545  AccumulateMultiThreadedClass accumulator(gmm, data, frame_weights,
546  this, &tot_like);
547  {
548  // Note: everything happens in the constructor and destructor of
549  // the object created below.
550  MultiThreader<AccumulateMultiThreadedClass> threader(num_threads,
551  accumulator);
552  // we need to make sure it's destroyed before we access the
553  // value of tot_like.
554  }
555  return tot_like;
556 }
557 
559  KALDI_ASSERT(dim_ == other.dim_ && num_comp_ == other.num_comp_ &&
560  flags_ == other.flags_);
564 }
565 
566 
567 } // End of namespace kaldi
bool ApproxEqual(const VectorBase< Real > &other, float tol=0.01) const
Returns true if ((*this)-other).Norm(2.0) <= tol * (*this).Norm(2.0).
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
int32 Dim() const
Returns the dimensionality of the Gaussian mean vectors.
Definition: diag-gmm.h:74
void MapDiagGmmUpdate(const MapDiagGmmOptions &config, const AccumDiagGmm &diag_gmm_acc, GmmFlagsType flags, DiagGmm *gmm, BaseFloat *obj_change_out, BaseFloat *count_out)
Maximum A Posteriori estimation of the model.
GmmFlagsType AugmentGmmFlags(GmmFlagsType f)
Returns "augmented" version of flags: e.g.
Definition: model-common.cc:52
BaseFloat weight_tau
Tau value for the weights– this tau value is applied per state, not per Gaussian.
Definition: mle-diag-gmm.h:87
BaseFloat AccumulateFromDiagMultiThreaded(const DiagGmm &gmm, const MatrixBase< BaseFloat > &data, const VectorBase< BaseFloat > &frame_weights, int32 num_threads)
This does the same job as AccumulateFromDiag, but using multiple threads.
Definition for Gaussian Mixture Model with diagonal covariances in normal mode: where the parameters ...
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Definition: kaldi-matrix.h:67
Base class which provides matrix operations not involving resizing or allocation. ...
Definition: kaldi-matrix.h:49
const Matrix< BaseFloat > & means_invvars() const
Definition: diag-gmm.h:179
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
BaseFloat min_gaussian_occupancy
Minimum count below which a Gaussian is not updated (and is removed, if remove_low_count_gaussians ==...
Definition: mle-diag-gmm.h:47
void MleDiagGmmUpdate(const MleDiagGmmOptions &config, const AccumDiagGmm &diag_gmm_acc, GmmFlagsType flags, DiagGmm *gmm, BaseFloat *obj_change_out, BaseFloat *count_out, int32 *floored_elements_out, int32 *floored_gaussians_out, int32 *removed_gaussians_out)
for computing the maximum-likelihood estimates of the parameters of a Gaussian mixture model...
bool ApproxEqual(const MatrixBase< Real > &other, float tol=0.01) const
Returns true if ((*this)-other).FrobeniusNorm() <= tol * (*this).FrobeniusNorm(). ...
BaseFloat MlObjective(const DiagGmm &gmm, const AccumDiagGmm &diag_gmm_acc)
Calc using the DiagGMM exponential form.
const Vector< BaseFloat > & gconsts() const
Const accessors.
Definition: diag-gmm.h:174
void AddMat(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transA=kNoTrans)
*this += alpha * M [or M^T]
Matrix< double > mean_accumulator_
Definition: mle-diag-gmm.h:196
int32 ComputeGconsts()
Sets the gconsts.
Definition: diag-gmm.cc:114
const VectorBase< double > & occupancy() const
Definition: mle-diag-gmm.h:183
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
uint16 GmmFlagsType
Bitwise OR of the above flags.
Definition: model-common.h:35
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
void CopyFromMat(const MatrixBase< OtherReal > &M, MatrixTransposeType trans=kNoTrans)
Copy given matrix. (no resize is done).
double min_variance
Minimum allowed variance in any dimension (if no variance floor) It is in double since the variance i...
Definition: mle-diag-gmm.h:50
void Scale(BaseFloat f, GmmFlagsType flags)
uint64 data_
void SmoothWithModel(BaseFloat tau, const DiagGmm &src_gmm)
Smooths the accumulated counts using the parameters of a given model.
GmmFlagsType flags_
Flags corresponding to the accumulators that are stored.
Definition: mle-diag-gmm.h:193
void GetVars(Matrix< Real > *v) const
Accessor for covariances.
Definition: diag-gmm-inl.h:115
void Read(std::istream &in, bool binary, bool add=false)
read from stream.
BaseFloat ComponentPosteriors(const VectorBase< BaseFloat > &data, Vector< BaseFloat > *posteriors) const
Computes the posterior probabilities of all Gaussian components given a data point.
Definition: diag-gmm.cc:601
float BaseFloat
Definition: kaldi-types.h:29
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
Definition: kaldi-matrix.h:188
const MatrixBase< BaseFloat > & data_
const MatrixBase< double > & variance_accumulator() const
Definition: mle-diag-gmm.h:185
void Scale(Real alpha)
Multiply each element with a scalar value.
BaseFloat AccumulateFromDiag(const DiagGmm &gmm, const VectorBase< BaseFloat > &data, BaseFloat frame_posterior)
Accumulate for all components given a diagonal-covariance GMM.
const MatrixBase< double > & mean_accumulator() const
Definition: mle-diag-gmm.h:184
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
GmmFlagsType Flags() const
Definition: mle-diag-gmm.h:182
void AddStatsForComponent(int32 comp_id, double occ, const VectorBase< double > &x_stats, const VectorBase< double > &x2_stats)
Increment the stats for this component by the specified amount (not all parts may be taken...
void GetMeans(Matrix< Real > *m) const
Accessor for means.
Definition: diag-gmm-inl.h:123
void Write(std::ostream &out_stream, bool binary) const
Definition: mle-diag-gmm.cc:77
void RemoveComponents(const std::vector< int32 > &gauss, bool renorm_weights)
Removes multiple components from model; "gauss" must not have dups.
Definition: diag-gmm.cc:632
void SmoothStats(BaseFloat tau)
Smooths the accumulated counts by adding &#39;tau&#39; extra frames.
void AccumulateForComponent(const VectorBase< BaseFloat > &data, int32 comp_index, BaseFloat weight)
Accumulate for a single component, given the posterior.
#define KALDI_ERR
Definition: kaldi-error.h:147
void Add(double scale, const AccumDiagGmm &acc)
Increment with stats from this other accumulator (times scale)
#define KALDI_WARN
Definition: kaldi-error.h:150
Real TraceMatMat(const MatrixBase< Real > &A, const MatrixBase< Real > &B, MatrixTransposeType trans)
We need to declare this here as it will be a friend function.
Matrix< double > vars_
diagonal variance
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
int32 NumGauss() const
Returns the number of mixture components in the GMM.
Definition: diag-gmm.h:72
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
void SetZero()
Sets matrix to zero.
Configuration variables like variance floor, minimum occupancy, etc.
Definition: mle-diag-gmm.h:38
void Scale(Real alpha)
Multiplies all elements by this constant.
Vector< double > occupancy_
Definition: mle-diag-gmm.h:195
void Read(std::istream &in_stream, bool binary, bool add)
Definition: mle-diag-gmm.cc:33
void SmoothWithAccum(BaseFloat tau, const AccumDiagGmm &src_acc)
Smooths the accumulated counts using some other accumulator.
void SetZero(GmmFlagsType flags)
AccumulateMultiThreadedClass(const DiagGmm &diag_gmm, const MatrixBase< BaseFloat > &data, const VectorBase< BaseFloat > &frame_weights, AccumDiagGmm *accum, double *tot_like)
int32 Dim() const
Returns the dimensionality of the feature vectors.
Definition: mle-diag-gmm.h:126
void MulRowsVec(const VectorBase< Real > &scale)
Equivalent to (*this) = diag(scale) * (*this).
Vector< double > variance_floor_vector
Variance floor for each dimension [empty if not supplied].
Definition: mle-diag-gmm.h:41
BaseFloat min_gaussian_weight
Minimum weight below which a Gaussian is not updated (and is removed, if remove_low_count_gaussians =...
Definition: mle-diag-gmm.h:44
Matrix< double > means_
Means.
A class representing a vector.
Definition: kaldi-vector.h:406
void InvertElements()
Invert all elements.
Matrix< double > variance_accumulator_
Definition: mle-diag-gmm.h:197
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
Definition: kaldi-matrix.h:64
void ApplyPow(Real power)
Take all elements of vector to a power.
Definition: kaldi-vector.h:179
void AddVecVec(const Real alpha, const VectorBase< OtherReal > &a, const VectorBase< OtherReal > &b)
*this += alpha * a * b^T
#define KALDI_VLOG(v)
Definition: kaldi-error.h:156
void CopyRowFromVec(const VectorBase< Real > &v, const MatrixIndexT row)
Copy vector into specific row of matrix.
Definition for Gaussian Mixture Model with diagonal covariances.
Definition: diag-gmm.h:42
std::string GmmFlagsToString(GmmFlagsType flags)
Convert GMM flags to string.
Definition: model-common.cc:43
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
void Resize(const MatrixIndexT r, const MatrixIndexT c, MatrixResizeType resize_type=kSetZero, MatrixStrideType stride_type=kDefaultStride)
Sets matrix to a specified size (zero is OK as long as both r and c are zero).
const VectorBase< BaseFloat > & frame_weights_
Vector< double > weights_
weights (not log).
AccumulateMultiThreadedClass(const AccumulateMultiThreadedClass &other)
Provides a vector abstraction class.
Definition: kaldi-vector.h:41
void Add(Real c)
Add a constant to each element of a vector.
void SetZero()
Set vector to all zeros.
void Resize(int32 num_gauss, int32 dim, GmmFlagsType flags)
Allocates memory for accumulators.
Real VecVec(const VectorBase< Real > &a, const VectorBase< Real > &b)
Returns dot product between v1 and v2.
Definition: kaldi-vector.cc:37
void AddVec(const Real alpha, const VectorBase< OtherReal > &v)
Add vector : *this = *this + alpha * rv (with casting between floats and doubles) ...
void AccumulateFromPosteriors(const VectorBase< BaseFloat > &data, const VectorBase< BaseFloat > &gauss_posteriors)
Accumulate for all components, given the posteriors.
BaseFloat variance_tau
Tau value for the variances.
Definition: mle-diag-gmm.h:83
void Read(std::istream &in, bool binary, bool add=false)
Read function using C++ streams.
Represents a non-allocating general vector which can be defined as a sub-vector of higher-level vecto...
Definition: kaldi-vector.h:501
BaseFloat mean_tau
Tau value for the means.
Definition: mle-diag-gmm.h:78
void AssertEqual(const AccumDiagGmm &other)
int32 NumGauss() const
Returns the number of mixture components.
Definition: mle-diag-gmm.h:124
Configuration variables for Maximum A Posteriori (MAP) update.
Definition: mle-diag-gmm.h:76
const Matrix< BaseFloat > & inv_vars() const
Definition: diag-gmm.h:180
void CopyToDiagGmm(DiagGmm *diaggmm, GmmFlagsType flags=kGmmAll) const
Copies to DiagGmm the requested parameters.