full-gmm-normal.cc
Go to the documentation of this file.
1 // gmm/full-gmm-normal.cc
2 
3 // Copyright 2009-2011 Microsoft Corporation; Saarland University;
4 // Yanmin Qian
5 // Univ. Erlangen-Nuremberg, Korbinian Riedhammer
6 // 2013 Johns Hopkins University (author: Daniel Povey)
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>
24 #include <limits>
25 #include <string>
26 #include <vector>
27 
28 #include "gmm/full-gmm-normal.h"
29 #include "gmm/full-gmm.h"
30 
31 namespace kaldi {
32 
34  KALDI_ASSERT(nmix > 0 && dim > 0);
35 
36  if (weights_.Dim() != nmix)
37  weights_.Resize(nmix);
38 
39  if (means_.NumRows() != nmix ||
40  means_.NumCols() != dim)
41  means_.Resize(nmix, dim);
42 
43  if (vars_.size() != nmix)
44  vars_.resize(nmix);
45  for (int32 i = 0; i < nmix; i++) {
46  if (vars_[i].NumRows() != nmix ||
47  vars_[i].NumCols() != dim) {
48  vars_[i].Resize(dim);
49  }
50  }
51 }
52 
55  size_t dim = fullgmm.Dim();
56  size_t num_gauss = fullgmm.NumGauss();
57  Resize(num_gauss, dim);
58 
60  weights_.CopyFromVec(fullgmm.weights_);
61 
63  Vector<double> mean_times_invcovar(dim);
64 
65  for (size_t i = 0; i < num_gauss; i++) {
66  // copy and invert (inverse) covariance matrix
67  vars_[i].CopyFromSp(fullgmm.inv_covars_[i]);
68  vars_[i].InvertDouble();
69 
70  // multiply the (mean x icov) by (cov) to get the means back
71  mean_times_invcovar.CopyFromVec(fullgmm.means_invcovars_.Row(i));
72  (means_.Row(i)).AddSpVec(1.0, vars_[i], mean_times_invcovar, 0.0);
73  }
74 }
75 
77  KALDI_ASSERT(weights_.Dim() == fullgmm->weights_.Dim()
78  && means_.NumCols() == fullgmm->Dim());
79 
80  FullGmmNormal oldg(*fullgmm);
81 
82  if (flags & kGmmWeights)
83  fullgmm->weights_.CopyFromVec(weights_);
84 
85  size_t num_comp = fullgmm->NumGauss(), dim = fullgmm->Dim();
86  for (size_t i = 0; i < num_comp; i++) {
87  if (flags & kGmmVariances) {
88  fullgmm->inv_covars_[i].CopyFromSp(vars_[i]);
89  fullgmm->inv_covars_[i].InvertDouble();
90 
91  // update the mean-related natural part with old mean, if necessary
92  if (!(flags & kGmmMeans)) {
93  Vector<BaseFloat> mean_times_inv(dim);
94  Vector<BaseFloat> mhelp(oldg.means_.Row(i));
95  mean_times_inv.AddSpVec(1.0, fullgmm->inv_covars_[i], mhelp, 0.0f);
96  fullgmm->means_invcovars_.Row(i).CopyFromVec(mean_times_inv);
97  }
98  }
99 
100  if (flags & kGmmMeans) {
101  Vector<BaseFloat> mean_times_inv(dim), mean(means_.Row(i));
102  mean_times_inv.AddSpVec(1.0, fullgmm->inv_covars_[i], mean, 0.0f);
103  fullgmm->means_invcovars_.Row(i).CopyFromVec(mean_times_inv);
104  }
105  }
106 
107  fullgmm->valid_gconsts_ = false;
108 }
109 
111  int32 dim = means_.NumCols(), num_frames = feats->NumRows(),
112  num_gauss = means_.NumRows();
113  KALDI_ASSERT(feats->NumCols() == dim);
114  std::vector<TpMatrix<BaseFloat> > sqrt_var(num_gauss);
115  for (int32 i = 0; i < num_gauss; i++) {
116  sqrt_var[i].Resize(dim);
117  sqrt_var[i].Cholesky(SpMatrix<BaseFloat>(vars_[i]));
118  }
119  Vector<BaseFloat> rand(dim);
120  for (int32 t = 0; t < num_frames; t++) {
121  int32 i = weights_.RandCategorical(); // index with prob propto weights_[i].
122  SubVector<BaseFloat> frame(*feats, t);
123  frame.CopyFromVec(means_.Row(i));
124  rand.SetRandn();
125  frame.AddTpVec(1.0, sqrt_var[i], kNoTrans, rand, 1.0);
126  }
127 }
128 
129 } // End namespace kaldi
void Resize(int32 nMix, int32 dim)
Resizes arrays to this dim. Does not initialize data.
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
Packed symetric matrix class.
Definition: matrix-common.h:62
int32 Dim() const
Returns the dimensionality of the Gaussian mean vectors.
Definition: full-gmm.h:60
Definition for Gaussian Mixture Model with full covariances in normal mode: where the parameters are ...
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
Definition for Gaussian Mixture Model with full covariances.
Definition: full-gmm.h:40
Vector< BaseFloat > weights_
weights (not log).
Definition: full-gmm.h:201
kaldi::int32 int32
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 AddSpVec(const Real alpha, const SpMatrix< Real > &M, const VectorBase< Real > &v, const Real beta)
Add symmetric positive definite matrix times vector: this <– beta*this + alpha*M*v.
std::vector< SpMatrix< double > > vars_
covariances
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
Vector< double > weights_
weights (not log).
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
Definition: kaldi-matrix.h:188
bool valid_gconsts_
Recompute gconsts_ if false.
Definition: full-gmm.h:200
void Rand(MatrixBase< BaseFloat > *feats)
Generates random features from the model.
void CopyToFullGmm(FullGmm *fullgmm, GmmFlagsType flags=kGmmAll)
Copies to FullGmm.
int32 NumGauss() const
Returns the number of mixture components in the GMM.
Definition: full-gmm.h:58
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
void SetRandn()
Set vector to random normally-distributed noise.
void AddTpVec(const Real alpha, const TpMatrix< Real > &M, const MatrixTransposeType trans, const VectorBase< Real > &v, const Real beta)
Add triangular matrix times vector: this <– beta*this + alpha*M*v.
#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 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).
std::vector< SpMatrix< BaseFloat > > inv_covars_
Inverse covariances.
Definition: full-gmm.h:202
MatrixIndexT RandCategorical() const
This function returns a random index into this vector, chosen with probability proportional to the co...
Matrix< BaseFloat > means_invcovars_
Means times inverse covariances.
Definition: full-gmm.h:203
Matrix< double > means_
Means.
Represents a non-allocating general vector which can be defined as a sub-vector of higher-level vecto...
Definition: kaldi-vector.h:501
void CopyFromFullGmm(const FullGmm &fullgmm)
Copies from given FullGmm.