regtree-fmllr-diag-gmm.cc
Go to the documentation of this file.
1 // transform/regtree-fmllr-diag-gmm.cc
2 
3 // Copyright 2009-2011 Saarland University; Georg Stemmer;
4 // Microsoft Corporation
5 
6 // See ../../COPYING for clarification regarding multiple authors
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 // MERCHANTABLITY OR NON-INFRINGEMENT.
18 // See the Apache 2 License for the specific language governing permissions and
19 // limitations under the License.
20 
21 #include <utility>
22 #include <vector>
23 using std::vector;
24 
25 #include "itf/optimizable-itf.h"
28 
29 namespace kaldi {
30 
31 void RegtreeFmllrDiagGmm::Init(size_t num_xforms, size_t dim) {
32  if (num_xforms == 0) { // empty transform
33  xform_matrices_.clear();
34  logdet_.Resize(0);
35  valid_logdet_ = false;
36  dim_ = 0; // non-zero dimension is meaningless with empty transform
37  num_xforms_ = 0;
38  } else {
39  KALDI_ASSERT(dim != 0); // if not empty, dim = 0 is meaningless
40  dim_ = dim;
41  num_xforms_ = num_xforms;
42  xform_matrices_.resize(num_xforms);
43  logdet_.Resize(num_xforms);
44  vector< Matrix<BaseFloat> >::iterator xform_itr = xform_matrices_.begin(),
45  xform_itr_end = xform_matrices_.end();
46  for (; xform_itr != xform_itr_end; ++xform_itr) {
47  xform_itr->Resize(dim, dim+1);
48  xform_itr->SetUnit();
49  }
50  valid_logdet_ = true;
51  }
52 }
53 
55  KALDI_ASSERT(num_xforms_ > 0 && dim_ > 0);
56  vector< Matrix<BaseFloat> >::iterator xform_itr = xform_matrices_.begin(),
57  xform_itr_end = xform_matrices_.end();
58  for (; xform_itr != xform_itr_end; ++xform_itr) {
59  xform_itr->SetUnit();
60  }
61 }
62 
64  if (dim_ < 0 || num_xforms_ < 0) { // uninitialized case
65  KALDI_ERR <<"Do not call Validate() with an uninitialized object (dim = "
66  << (dim_) << ", # transforms = " << (num_xforms_);
67  } else if (dim_ * num_xforms_ == 0) { // empty case
68  KALDI_ASSERT(num_xforms_ == 0 && dim_ == 0);
69  if (xform_matrices_.size() != 0 || logdet_.Dim() != 0) {
70  KALDI_ERR << "Number of transforms = " << (xform_matrices_.size())
71  << ", number of log-determinant terms = " << (logdet_.Dim())
72  << ". Expected number = 0";
73  }
74  return;
75  }
76 
77  // non-empty case: typical usage scenario
78  if (xform_matrices_.size() != static_cast<size_t>(num_xforms_)
79  || logdet_.Dim() != num_xforms_) {
80  KALDI_ERR << "Number of transforms = " << (xform_matrices_.size())
81  << ", number of log-determinant terms = " << (logdet_.Dim())
82  << ". `Expected number = " << (num_xforms_);
83  }
84  for (int32 i = 0; i < num_xforms_; i++) {
85  if (xform_matrices_[i].NumRows() != dim_ ||
86  xform_matrices_[i].NumCols() != (dim_+1)) {
87  KALDI_ERR << "For transform " << (i) << ": inconsistent size: rows = "
88  << (xform_matrices_[i].NumRows()) << ", cols = "
89  << xform_matrices_[i].NumCols() << ", dim = " << (dim_);
90  }
91  }
92  if (bclass2xforms_.size() > 0) {
93  for (int32 i = 0, maxi = bclass2xforms_.size(); i < maxi; i++) {
94  if (bclass2xforms_[i] >= num_xforms_) {
95  KALDI_ERR << "For baseclass " << (i) << ", transform index "
96  << (bclass2xforms_[i]) << " exceeds total transforms "
97  << (num_xforms_);
98  }
99  }
100  } else {
101  if (num_xforms_ > 1) {
102  KALDI_WARN << "Multiple FMLLR transforms found without baseclass info.";
103  }
104  }
105 }
106 
108  logdet_.Resize(num_xforms_);
109  for (int32 r = 0; r < num_xforms_; r++) {
110  SubMatrix<BaseFloat> tmp_a(xform_matrices_[r], 0, dim_, 0,
111  dim_);
112  logdet_(r) = tmp_a.LogDet();
114  }
115  valid_logdet_ = true;
116 }
117 
119  vector<Vector<BaseFloat> > *out) const {
120  KALDI_ASSERT(out != NULL);
121 
122  if (xform_matrices_.size() == 0) { // empty transform
123  KALDI_ASSERT(num_xforms_ == 0 && dim_ == 0 && logdet_.Dim() == 0);
124  KALDI_WARN << "Asked to apply empty feature transform. Copying instead.";
125  out->resize(1);
126  (*out)[0].Resize(in.Dim());
127  (*out)[0].CopyFromVec(in);
128  return;
129  } else {
130  KALDI_ASSERT(in.Dim() == dim_);
131  // if (!valid_logdet_)
132  // KALDI_ERR << "Must call ComputeLogDets() before transforming data.";
133  // [no need for this check].
134  Vector<BaseFloat> extended_feat(dim_ + 1);
135  extended_feat.Range(0, dim_).CopyFromVec(in);
136  extended_feat(dim_) = 1.0;
138  out->resize(num_xforms_);
139  for (int32 xform_index = 0; xform_index < num_xforms_;
140  ++xform_index) {
141  (*out)[xform_index].Resize(dim_);
142  (*out)[xform_index].AddMatVec(1.0, xform_matrices_[xform_index],
143  kNoTrans, extended_feat, 0.0);
144  }
145  }
146 }
147 
148 void RegtreeFmllrDiagGmm::Write(std::ostream &out, bool binary) const {
149  WriteToken(out, binary, "<FMLLRXFORM>");
150  WriteToken(out, binary, "<NUMXFORMS>");
151  WriteBasicType(out, binary, num_xforms_);
152  WriteToken(out, binary, "<DIMENSION>");
153  WriteBasicType(out, binary, dim_);
154 
155  vector< Matrix<BaseFloat> >::const_iterator xform_itr =
156  xform_matrices_.begin(), xform_itr_end = xform_matrices_.end();
157  for (; xform_itr != xform_itr_end; ++xform_itr) {
158  WriteToken(out, binary, "<XFORM>");
159  xform_itr->Write(out, binary);
160  }
161 
162  WriteToken(out, binary, "<BCLASS2XFORMS>");
163  WriteIntegerVector(out, binary, bclass2xforms_);
164  WriteToken(out, binary, "</FMLLRXFORM>");
165 }
166 
167 
168 void RegtreeFmllrDiagGmm::Read(std::istream &in, bool binary) {
169  ExpectToken(in, binary, "<FMLLRXFORM>");
170  ExpectToken(in, binary, "<NUMXFORMS>");
171  ReadBasicType(in, binary, &num_xforms_);
172  ExpectToken(in, binary, "<DIMENSION>");
173  ReadBasicType(in, binary, &dim_);
174  KALDI_ASSERT(num_xforms_ >= 0 && dim_ >= 0); // can be 0 for empty xform
175 
177  vector< Matrix<BaseFloat> >::iterator xform_itr = xform_matrices_.begin(),
178  xform_itr_end = xform_matrices_.end();
179  for (; xform_itr != xform_itr_end; ++xform_itr) {
180  ExpectToken(in, binary, "<XFORM>");
181  xform_itr->Read(in, binary);
182  KALDI_ASSERT(xform_itr->NumRows() == (xform_itr->NumCols() - 1)
183  && xform_itr->NumRows() == dim_);
184  }
185 
186  ExpectToken(in, binary, "<BCLASS2XFORMS>");
187  ReadIntegerVector(in, binary, &bclass2xforms_);
188  ExpectToken(in, binary, "</FMLLRXFORM>");
189  ComputeLogDets(); // so that the transforms can be used.
190 }
191 
192 // ************************************************************************
193 
194 
195 
196 
197 void RegtreeFmllrDiagGmmAccs::Init(size_t num_bclass, size_t dim) {
198  if (num_bclass == 0) { // empty stats
199  DeletePointers(&baseclass_stats_);
200  baseclass_stats_.clear();
201  num_baseclasses_ = 0;
202  dim_ = 0; // non-zero dimension is meaningless in empty stats
203  } else {
204  KALDI_ASSERT(dim != 0); // if not empty, dim = 0 is meaningless
205  num_baseclasses_ = num_bclass;
206  dim_ = dim;
207  DeletePointers(&baseclass_stats_);
208  baseclass_stats_.resize(num_bclass);
209  for (vector<AffineXformStats*>::iterator it = baseclass_stats_.begin(),
210  end = baseclass_stats_.end(); it != end; ++it) {
211  *it = new AffineXformStats();
212  (*it)->Init(dim, dim);
213  }
214  }
215 }
216 
218  for (vector<AffineXformStats*>::iterator it = baseclass_stats_.begin(),
219  end = baseclass_stats_.end(); it != end; ++it) {
220  (*it)->SetZero();
221  }
222 }
223 
225  const RegressionTree &regtree, const AmDiagGmm &am,
226  const VectorBase<BaseFloat> &data, size_t pdf_index, BaseFloat weight) {
227  const DiagGmm &pdf = am.GetPdf(pdf_index);
228  int32 num_comp = pdf.NumGauss();
229  Vector<BaseFloat> posterior(num_comp);
230  BaseFloat loglike = pdf.ComponentPosteriors(data, &posterior);
231  posterior.Scale(weight);
232  Vector<double> posterior_d(posterior);
233 
234  Vector<double> extended_data(dim_+1);
235  extended_data.Range(0, dim_).CopyFromVec(data);
236  extended_data(dim_) = 1.0;
237  SpMatrix<double> scatter(dim_+1);
238  scatter.AddVec2(1.0, extended_data);
239 
240  Vector<double> inv_var_mean(dim_);
241  Matrix<double> g_scale(baseclass_stats_.size(), dim_); // scale on "scatter" for each dim.
242  for (int32 m = 0; m < num_comp; m++) {
243  inv_var_mean.CopyRowFromMat(pdf.means_invvars(), m);
244  int32 bclass = regtree.Gauss2BaseclassId(pdf_index, m);
245 
246  baseclass_stats_[bclass]->beta_ += posterior_d(m);
247  baseclass_stats_[bclass]->K_.AddVecVec(posterior_d(m), inv_var_mean,
248  extended_data);
249  for (int32 d = 0; d < dim_; d++)
250  g_scale(bclass, d) += posterior(m) * pdf.inv_vars()(m, d);
251  }
252  for (size_t bclass = 0; bclass < baseclass_stats_.size(); bclass++) {
253  vector< SpMatrix<double> > &G = baseclass_stats_[bclass]->G_;
254  for (int32 d = 0; d < dim_; d++)
255  if (g_scale(bclass, d) != 0.0)
256  G[d].AddSp(g_scale(bclass, d), scatter);
257  }
258  return loglike;
259 }
260 
262  const RegressionTree &regtree, const AmDiagGmm &am,
263  const VectorBase<BaseFloat> &data, size_t pdf_index, size_t gauss_index,
264  BaseFloat weight) {
265  const DiagGmm &pdf = am.GetPdf(pdf_index);
266  size_t dim = static_cast<size_t>(dim_);
267  Vector<double> extended_data(dim+1);
268  extended_data.Range(0, dim).CopyFromVec(data);
269  extended_data(dim) = 1.0;
270  SpMatrix<double> scatter(dim+1);
271  scatter.AddVec2(1.0, extended_data);
272  double weight_d = static_cast<double>(weight);
273 
274  unsigned bclass = regtree.Gauss2BaseclassId(pdf_index, gauss_index);
275  Vector<double> inv_var_mean(dim_);
276  inv_var_mean.CopyRowFromMat(pdf.means_invvars(), gauss_index);
277 
278  baseclass_stats_[bclass]->beta_ += weight_d;
279  baseclass_stats_[bclass]->K_.AddVecVec(weight_d, inv_var_mean, extended_data);
280  vector< SpMatrix<double> > &G = baseclass_stats_[bclass]->G_;
281  for (size_t d = 0; d < dim; d++)
282  G[d].AddSp((weight_d * pdf.inv_vars()(gauss_index, d)), scatter);
283 }
284 
285 void RegtreeFmllrDiagGmmAccs::Write(std::ostream &out, bool binary) const {
286  WriteToken(out, binary, "<FMLLRACCS>");
287  WriteToken(out, binary, "<NUMBASECLASSES>");
288  WriteBasicType(out, binary, num_baseclasses_);
289  WriteToken(out, binary, "<DIMENSION>");
290  WriteBasicType(out, binary, dim_);
291  WriteToken(out, binary, "<STATS>");
292  vector<AffineXformStats*>::const_iterator itr = baseclass_stats_.begin(),
293  end = baseclass_stats_.end();
294  for ( ; itr != end; ++itr)
295  (*itr)->Write(out, binary);
296  WriteToken(out, binary, "</FMLLRACCS>");
297 }
298 
299 void RegtreeFmllrDiagGmmAccs::Read(std::istream &in, bool binary, bool add) {
300  ExpectToken(in, binary, "<FMLLRACCS>");
301  ExpectToken(in, binary, "<NUMBASECLASSES>");
302  ReadBasicType(in, binary, &num_baseclasses_);
303  ExpectToken(in, binary, "<DIMENSION>");
304  ReadBasicType(in, binary, &dim_);
305  KALDI_ASSERT(num_baseclasses_ > 0 && dim_ > 0);
306  baseclass_stats_.resize(num_baseclasses_);
307  ExpectToken(in, binary, "<STATS>");
308  vector<AffineXformStats*>::iterator itr = baseclass_stats_.begin(),
309  end = baseclass_stats_.end();
310  for ( ; itr != end; ++itr) {
311  *itr = new AffineXformStats();
312  (*itr)->Init(dim_, dim_);
313  (*itr)->Read(in, binary, add);
314  }
315  ExpectToken(in, binary, "</FMLLRACCS>");
316 }
317 
318 
320  const RegtreeFmllrOptions &opts,
321  RegtreeFmllrDiagGmm *out_fmllr,
322  BaseFloat *auxf_impr_out,
323  BaseFloat *tot_t_out) const {
324  BaseFloat tot_auxf_impr = 0.0, tot_t = 0.0;
325  Matrix<BaseFloat> xform_mat(dim_, dim_+1);
326  if (opts.use_regtree) { // estimate transforms using a regression tree
327  vector<AffineXformStats*> regclass_stats;
328  vector<int32> base2regclass;
329  bool update_xforms = regtree.GatherStats(baseclass_stats_, opts.min_count,
330  &base2regclass, &regclass_stats);
331  out_fmllr->set_bclass2xforms(base2regclass);
332  // If update_xforms == true, none should be negative, else all should be -1
333  if (update_xforms) {
334  out_fmllr->Init(regclass_stats.size(), dim_);
335  size_t num_rclass = regclass_stats.size();
336  for (size_t rclass_index = 0;
337  rclass_index < num_rclass; ++rclass_index) {
338  KALDI_ASSERT(regclass_stats[rclass_index]->beta_ >= opts.min_count);
339  xform_mat.SetUnit();
340  tot_t += regclass_stats[rclass_index]->beta_;
341 
342  tot_auxf_impr +=
343  ComputeFmllrMatrixDiagGmmFull(xform_mat, *(regclass_stats[rclass_index]),
344  opts.num_iters, &xform_mat);
345 
346  out_fmllr->SetParameters(xform_mat, rclass_index);
347  }
348  KALDI_LOG << "Estimated " << num_rclass << " regression classes.";
349  } else {
350  out_fmllr->Init(1, dim_); // Use a unit transform at the root.
351  }
352  DeletePointers(&regclass_stats);
353  // end of estimation using regression tree
354  } else { // No regtree: estimate 1 transform per baseclass (if enough count)
355  for (int32 bclass_index = 0; bclass_index < num_baseclasses_;
356  ++bclass_index) {
357  tot_t += baseclass_stats_[bclass_index]->beta_;
358  }
359 
360  out_fmllr->Init(num_baseclasses_, dim_);
361  vector<int32> base2regclass(num_baseclasses_);
362  for (int32 bclass_index = 0; bclass_index < num_baseclasses_;
363  ++bclass_index) {
364  if (baseclass_stats_[bclass_index]->beta_ >= opts.min_count) {
365  xform_mat.SetUnit();
366 
367  if (opts.update_type == "full") {
368  tot_auxf_impr +=
370  *(baseclass_stats_[bclass_index]),
371  opts.num_iters, &xform_mat);
372  } else if (opts.update_type == "diag")
373  tot_auxf_impr +=
375  *(baseclass_stats_[bclass_index]),
376  &xform_mat);
377  else if (opts.update_type == "offset")
378  tot_auxf_impr +=
380  *(baseclass_stats_[bclass_index]),
381  &xform_mat);
382  else if (opts.update_type == "none")
383  tot_auxf_impr = 0.0;
384  else
385  KALDI_ERR << "Unknown fMLLR update type " << opts.update_type
386  << ", fmllr-update-type must be one of \"full\"|\"diag\"|\"offset\"|\"none\"";
387 
388  out_fmllr->SetParameters(xform_mat, bclass_index);
389  base2regclass[bclass_index] = bclass_index;
390  } else {
391  KALDI_WARN << "For baseclass " << (bclass_index) << " count = "
392  << (baseclass_stats_[bclass_index]->beta_) << " < "
393  << opts.min_count << ": not updating FMLLR";
394  base2regclass[bclass_index] = -1;
395  }
396  out_fmllr->set_bclass2xforms(base2regclass);
397  } // end looping over all baseclasses
398  } // end of estimating one transform per baseclass without regtree
399  if (auxf_impr_out) *auxf_impr_out = tot_auxf_impr;
400  if (tot_t_out) *tot_t_out = tot_t;
401 }
402 
403 
404 
405 
406 } // namespace kaldi
407 
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void AccumulateForGaussian(const RegressionTree &regtree, const AmDiagGmm &am, const VectorBase< BaseFloat > &data, size_t pdf_index, size_t gauss_index, BaseFloat weight)
Accumulate stats for a single Gaussian component in the model.
int32 Gauss2BaseclassId(size_t pdf_id, size_t gauss_id) const
void DeletePointers(std::vector< A *> *v)
Deletes any non-NULL pointers in the vector v, and sets the corresponding entries of v to NULL...
Definition: stl-utils.h:184
void set_bclass2xforms(const std::vector< int32 > &in)
BaseFloat ComputeFmllrMatrixDiagGmmFull(const MatrixBase< BaseFloat > &in_xform, const AffineXformStats &stats, int32 num_iters, MatrixBase< BaseFloat > *out_xform)
Updates the FMLLR matrix using Mark Gales&#39; row-by-row update.
void Read(std::istream &in_stream, bool binary)
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
void ComputeLogDets()
Computes the log-determinant of the Jacobians for each transform.
void Init(size_t num_xforms, size_t dim)
Allocates memory for transform matrix & bias vector.
kaldi::int32 int32
void SetUnit()
Sets to zero, except ones along diagonal [for non-square matrices too].
std::vector< int32 > bclass2xforms_
For each baseclass index of which transform to use; -1 => no xform.
void CopyRowFromMat(const MatrixBase< Real > &M, MatrixIndexT row)
Extracts a row of the matrix M.
bool GatherStats(const std::vector< AffineXformStats *> &stats_in, double min_count, std::vector< int32 > *regclasses_out, std::vector< AffineXformStats *> *stats_out) const
Parses the regression tree and finds the nodes whose occupancies (read from stats_in) are greater tha...
An FMLLR (feature-space MLLR) transformation, also called CMLLR (constrained MLLR) is an affine trans...
BaseFloat ComputeFmllrMatrixDiagGmmOffset(const MatrixBase< BaseFloat > &in_xform, const AffineXformStats &stats, MatrixBase< BaseFloat > *out_xform)
This does offset-only fMLLR, i.e. it only estimates an offset.
void AddVec2(const Real alpha, const VectorBase< OtherReal > &v)
rank-one update, this <– this + alpha v v&#39;
Definition: sp-matrix.cc:946
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
Configuration variables for FMLLR transforms.
void ReadIntegerVector(std::istream &is, bool binary, std::vector< T > *v)
Function for reading STL vector of integer types.
Definition: io-funcs-inl.h:232
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
A regression tree is a clustering of Gaussian densities in an acoustic model, such that the group of ...
void TransformFeature(const VectorBase< BaseFloat > &in, std::vector< Vector< BaseFloat > > *out) const
Get the transformed features for each of the transforms.
#define KALDI_ERR
Definition: kaldi-error.h:147
void Validate()
Checks whether the various parameters are consistent.
BaseFloat min_count
Minimum occupancy for computing a transform.
#define KALDI_WARN
Definition: kaldi-error.h:150
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 Scale(Real alpha)
Multiplies all elements by this constant.
bool use_regtree
If &#39;true&#39;, find transforms to generate using regression tree.
BaseFloat ComputeFmllrMatrixDiagGmmDiagonal(const MatrixBase< BaseFloat > &in_xform, const AffineXformStats &stats, MatrixBase< BaseFloat > *out_xform)
This does diagonal fMLLR (i.e.
int32 num_xforms_
Number of transform matrices.
int32 num_iters
Number of iterations (if using an iterative update)
DiagGmm & GetPdf(int32 pdf_index)
Accessors.
Definition: am-diag-gmm.h:119
std::vector< Matrix< BaseFloat > > xform_matrices_
Transform matrices.
void SetParameters(const MatrixBase< BaseFloat > &mat, size_t regclass)
Mutators.
A class representing a vector.
Definition: kaldi-vector.h:406
#define KALDI_ISNAN
Definition: kaldi-math.h:72
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
void SetUnit()
Sets transform matrix to identity and bias vector to zero.
Real LogDet(Real *det_sign=NULL) const
Returns logdet of matrix.
void AddSp(const Real alpha, const SpMatrix< OtherReal > &S)
*this += alpha * S
int32 dim_
Dimension of feature vectors.
Definition for Gaussian Mixture Model with diagonal covariances.
Definition: diag-gmm.h:42
void WriteIntegerVector(std::ostream &os, bool binary, const std::vector< T > &v)
Function for writing STL vectors of integer types.
Definition: io-funcs-inl.h:198
Vector< BaseFloat > logdet_
Log-determinants of the Jacobians.
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 Write(std::ostream &out_stream, bool binary) const
void Read(std::istream &in_stream, bool binary, bool add)
BaseFloat AccumulateForGmm(const RegressionTree &regtree, const AmDiagGmm &am, const VectorBase< BaseFloat > &data, size_t pdf_index, BaseFloat weight)
Accumulate stats for a single GMM in the model; returns log likelihood.
std::string update_type
"full", "diag", "offset", "none"
void Update(const RegressionTree &regtree, const RegtreeFmllrOptions &opts, RegtreeFmllrDiagGmm *out_fmllr, BaseFloat *auxf_impr, BaseFloat *tot_t) const
Provides a vector abstraction class.
Definition: kaldi-vector.h:41
void Write(std::ostream &out_stream, bool binary) const
void Init(size_t num_bclass, size_t dim)
#define KALDI_LOG
Definition: kaldi-error.h:153
Sub-matrix representation.
Definition: kaldi-matrix.h:988
bool valid_logdet_
Whether logdets are for current transforms.
const Matrix< BaseFloat > & inv_vars() const
Definition: diag-gmm.h:180
SubVector< Real > Range(const MatrixIndexT o, const MatrixIndexT l)
Returns a sub-vector of a vector (a range of elements).
Definition: kaldi-vector.h:94