FmllrRawAccs Class Reference

#include <fmllr-raw.h>

Collaboration diagram for FmllrRawAccs:

Classes

struct  SingleFrameStats
 

Public Member Functions

 FmllrRawAccs ()
 
int32 RawDim () const
 Dimension of raw MFCC (etc.) features. More...
 
int32 FullDim () const
 Full feature dimension after splicing. More...
 
int32 SpliceWidth () const
 Number of frames that are spliced together each time. More...
 
int32 ModelDim () const
 Dimension of the model. More...
 
 FmllrRawAccs (int32 raw_dim, int32 model_dim, const Matrix< BaseFloat > &full_transform)
 
BaseFloat AccumulateForGmm (const DiagGmm &gmm, const VectorBase< BaseFloat > &data, BaseFloat weight)
 Accumulate stats for a single GMM in the model; returns log likelihood. More...
 
void AccumulateFromPosteriors (const DiagGmm &gmm, const VectorBase< BaseFloat > &data, const VectorBase< BaseFloat > &posteriors)
 Accumulate stats for a GMM, given supplied posteriors. More...
 
void Update (const FmllrRawOptions &opts, MatrixBase< BaseFloat > *raw_fmllr_mat, BaseFloat *objf_impr, BaseFloat *count)
 Update "raw_fmllr_mat"; it should have the correct dimension and reasonable values at entry (see the function InitFmllr in fmllr-diag-gmm.h for how to initialize it.) The only reason this function is not const is because we may have to call CommitSingleFrameStats(). More...
 
void SetZero ()
 

Private Member Functions

void CommitSingleFrameStats ()
 
void InitSingleFrameStats (const VectorBase< BaseFloat > &data)
 
bool DataHasChanged (const VectorBase< BaseFloat > &data) const
 
double GetAuxf (const Vector< double > &simple_linear_stats, const SpMatrix< double > &simple_quadratic_stats, const Matrix< double > &fmllr_mat) const
 Compute the auxiliary function for this matrix. More...
 
void ConvertToSimpleStats (Vector< double > *simple_linear_stats, SpMatrix< double > *simple_quadratic_stats) const
 Converts from the Q and S stats to a simple objective function of the form l . More...
 
void ComputeM (std::vector< Matrix< double > > *M) const
 Computes the M_i matrices used in the update, see the extended comment in fmllr-raw.cc for explanation. More...
 
void ConvertToPerRowStats (const Vector< double > &simple_linear_stats, const SpMatrix< double > &simple_quadratic_stats_sp, Matrix< double > *linear_stats, std::vector< SpMatrix< double > > *diag_stats, std::vector< std::vector< Matrix< double > > > *off_diag_stats) const
 Transform stats into a convenient format for the update. More...
 
 KALDI_DISALLOW_COPY_AND_ASSIGN (FmllrRawAccs)
 

Private Attributes

int32 raw_dim_
 
int32 model_dim_
 
Matrix< BaseFloatfull_transform_
 
Vector< BaseFloattransform_offset_
 
SingleFrameStats single_frame_stats_
 
double count_
 
SpMatrix< double > temp_
 
Matrix< double > Q_
 
Matrix< double > S_
 

Detailed Description

Definition at line 81 of file fmllr-raw.h.

Constructor & Destructor Documentation

◆ FmllrRawAccs() [1/2]

FmllrRawAccs ( )
inline

Definition at line 83 of file fmllr-raw.h.

83 { }

◆ FmllrRawAccs() [2/2]

FmllrRawAccs ( int32  raw_dim,
int32  model_dim,
const Matrix< BaseFloat > &  full_transform 
)

Definition at line 29 of file fmllr-raw.cc.

References FmllrRawAccs::SingleFrameStats::a, FmllrRawAccs::SingleFrameStats::b, FmllrRawAccs::SingleFrameStats::count, FmllrRawAccs::count_, FmllrRawAccs::full_transform_, KALDI_ERR, MatrixBase< Real >::NumCols(), MatrixBase< Real >::NumRows(), FmllrRawAccs::Q_, MatrixBase< Real >::Range(), SpMatrix< Real >::Resize(), Vector< Real >::Resize(), Matrix< Real >::Resize(), FmllrRawAccs::SingleFrameStats::s, FmllrRawAccs::S_, FmllrRawAccs::single_frame_stats_, FmllrRawAccs::temp_, FmllrRawAccs::transform_offset_, and FmllrRawAccs::SingleFrameStats::transformed_data.

31  :
32  raw_dim_(raw_dim),
33  model_dim_(model_dim) {
34  if (full_transform.NumCols() != full_transform.NumRows() &&
35  full_transform.NumCols() != full_transform.NumRows() + 1) {
36  KALDI_ERR << "Expecting full LDA+MLLT transform to be square or d by d+1 "
37  << "(make sure you are including rejected rows).";
38  }
39  if (raw_dim <= 0 || full_transform.NumRows() % raw_dim != 0)
40  KALDI_ERR << "Raw feature dimension is invalid " << raw_dim
41  << "(must be positive and divide feature dimension)";
42  int32 full_dim = full_transform.NumRows();
43  full_transform_ = full_transform.Range(0, full_dim, 0, full_dim);
44  transform_offset_.Resize(full_dim);
45  if (full_transform_.NumCols() == full_dim + 1)
46  transform_offset_.CopyColFromMat(full_transform_, full_dim);
47 
48  int32 full_dim2 = ((full_dim+1)*(full_dim+2))/2;
49  count_ = 0.0;
50 
51  temp_.Resize(full_dim + 1);
52  Q_.Resize(model_dim + 1, full_dim + 1);
53  S_.Resize(model_dim + 1, full_dim2);
54 
55  single_frame_stats_.s.Resize(full_dim + 1);
56  single_frame_stats_.transformed_data.Resize(full_dim);
58  single_frame_stats_.a.Resize(model_dim);
59  single_frame_stats_.b.Resize(model_dim);
60 }
Matrix< double > S_
Definition: fmllr-raw.h:196
Vector< BaseFloat > transform_offset_
Definition: fmllr-raw.h:185
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Definition: kaldi-matrix.h:67
kaldi::int32 int32
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
Matrix< BaseFloat > full_transform_
Definition: fmllr-raw.h:183
Matrix< double > Q_
Definition: fmllr-raw.h:195
#define KALDI_ERR
Definition: kaldi-error.h:147
Vector< BaseFloat > transformed_data
Definition: fmllr-raw.h:132
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
Definition: kaldi-matrix.h:64
SpMatrix< double > temp_
Definition: fmllr-raw.h:194
SubMatrix< Real > Range(const MatrixIndexT row_offset, const MatrixIndexT num_rows, const MatrixIndexT col_offset, const MatrixIndexT num_cols) const
Return a sub-part of matrix.
Definition: kaldi-matrix.h:202
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).
void Resize(MatrixIndexT nRows, MatrixResizeType resize_type=kSetZero)
Definition: sp-matrix.h:81

Member Function Documentation

◆ AccumulateForGmm()

BaseFloat AccumulateForGmm ( const DiagGmm gmm,
const VectorBase< BaseFloat > &  data,
BaseFloat  weight 
)

Accumulate stats for a single GMM in the model; returns log likelihood.

Here, "data" will typically be of larger dimension than the model. Note: "data" is the original, spliced features– before LDA+MLLT. Returns log-like for this data given this GMM, including rejected dimensions (not multiplied by weight).

Definition at line 107 of file fmllr-raw.cc.

References FmllrRawAccs::AccumulateFromPosteriors(), FmllrRawAccs::CommitSingleFrameStats(), DiagGmm::ComponentPosteriors(), FmllrRawAccs::DataHasChanged(), VectorBase< Real >::Dim(), FmllrRawAccs::FullDim(), FmllrRawAccs::InitSingleFrameStats(), KALDI_ASSERT, M_LOG_2PI, FmllrRawAccs::ModelDim(), DiagGmm::NumGauss(), VectorBase< Real >::Scale(), FmllrRawAccs::single_frame_stats_, FmllrRawAccs::SingleFrameStats::transformed_data, and kaldi::VecVec().

Referenced by kaldi::AccStatsForUtterance(), and kaldi::UnitTestFmllrRaw().

109  {
110  int32 model_dim = ModelDim(), full_dim = FullDim();
111  KALDI_ASSERT(data.Dim() == full_dim &&
112  "Expect raw, spliced data, which should have same dimension as "
113  "full transform.");
114  if (DataHasChanged(data)) {
115  // this is part of our mechanism to accumulate certain sub-parts of
116  // the computation for each frame, to avoid excessive compute.
118  InitSingleFrameStats(data);
119  }
120  SingleFrameStats &stats = single_frame_stats_;
121 
122  SubVector<BaseFloat> projected_data(stats.transformed_data, 0, model_dim);
123 
124  int32 num_gauss = gmm.NumGauss();
125  Vector<BaseFloat> posterior(num_gauss);
126  BaseFloat log_like = gmm.ComponentPosteriors(projected_data, &posterior);
127  posterior.Scale(weight);
128  // Note: AccumulateFromPosteriors takes the original, spliced data,
129  // and returns the log-like of the rejected dimensions.
130  AccumulateFromPosteriors(gmm, data, posterior);
131 
132  // Add the likelihood of the rejected dimensions to the objective function
133  // (assume zero-mean, unit-variance Gaussian; the LDA should have any offset
134  // required to ensure this).
135  if (full_dim > model_dim) {
136  SubVector<BaseFloat> rejected_data(stats.transformed_data,
137  model_dim, full_dim - model_dim);
138  log_like += -0.5 * (VecVec(rejected_data, rejected_data)
139  + (full_dim - model_dim) * M_LOG_2PI);
140  }
141  return log_like;
142 }
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
#define M_LOG_2PI
Definition: kaldi-math.h:60
int32 ModelDim() const
Dimension of the model.
Definition: fmllr-raw.h:92
kaldi::int32 int32
void AccumulateFromPosteriors(const DiagGmm &gmm, const VectorBase< BaseFloat > &data, const VectorBase< BaseFloat > &posteriors)
Accumulate stats for a GMM, given supplied posteriors.
Definition: fmllr-raw.cc:246
float BaseFloat
Definition: kaldi-types.h:29
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
void InitSingleFrameStats(const VectorBase< BaseFloat > &data)
Definition: fmllr-raw.cc:93
bool DataHasChanged(const VectorBase< BaseFloat > &data) const
Definition: fmllr-raw.cc:63
Real VecVec(const VectorBase< Real > &a, const VectorBase< Real > &b)
Returns dot product between v1 and v2.
Definition: kaldi-vector.cc:37
void CommitSingleFrameStats()
Definition: fmllr-raw.cc:68

◆ AccumulateFromPosteriors()

void AccumulateFromPosteriors ( const DiagGmm gmm,
const VectorBase< BaseFloat > &  data,
const VectorBase< BaseFloat > &  posteriors 
)

Accumulate stats for a GMM, given supplied posteriors.

Note: "data" is the original, spliced features– before LDA+MLLT.

Definition at line 246 of file fmllr-raw.cc.

References FmllrRawAccs::SingleFrameStats::a, VectorBase< Real >::AddVec(), VectorBase< Real >::AddVecVec(), FmllrRawAccs::SingleFrameStats::b, FmllrRawAccs::CommitSingleFrameStats(), count, FmllrRawAccs::SingleFrameStats::count, FmllrRawAccs::DataHasChanged(), FmllrRawAccs::InitSingleFrameStats(), DiagGmm::inv_vars(), DiagGmm::means_invvars(), FmllrRawAccs::ModelDim(), DiagGmm::NumGauss(), MatrixBase< Real >::Row(), FmllrRawAccs::single_frame_stats_, and FmllrRawAccs::transform_offset_.

Referenced by kaldi::AccStatsForUtterance(), and FmllrRawAccs::AccumulateForGmm().

249  {
250  // The user may call this function directly, even though we also
251  // call it from AccumulateForGmm(), so check again:
252  if (DataHasChanged(data)) {
254  InitSingleFrameStats(data);
255  }
256 
257  int32 model_dim = ModelDim();
258 
259  SingleFrameStats &stats = single_frame_stats_;
260 
261  // The quantities a and b describe the diagonal auxiliary function
262  // for each of the retained dimensions in the transformed space--
263  // in the format F = \sum_d alpha(d) x(d) -0.5 beta(d) x(d)^2,
264  // where x(d) is the d'th dimensional fully processed feature.
265  // For d, see the comment-- it's alpha processed to take into
266  // account any offset in the LDA. Note that it's a reference.
267  //
268  Vector<double> a(model_dim), b(model_dim);
269 
270  int32 num_comp = diag_gmm.NumGauss();
271 
272  double count = 0.0; // data-count contribution from this frame.
273 
274  // Note: we could do this using matrix-matrix operations instead of
275  // row by row. In the end it won't really matter as this is not
276  // the slowest part of the computation.
277  for (size_t m = 0; m < num_comp; m++) {
278  BaseFloat this_post = posterior(m);
279  if (this_post != 0.0) {
280  count += this_post;
281  a.AddVec(this_post, diag_gmm.means_invvars().Row(m));
282  b.AddVec(this_post, diag_gmm.inv_vars().Row(m));
283  }
284  }
285  // Correct "a" for any offset term in the LDA transform-- we view it as
286  // the opposite offset in the model [note: we'll handle the rejected dimensions
287  // in update time.] Here, multiplying the element of "b" (which is the
288  // weighted inv-vars) by transform_offset_, and subtracting the result from
289  // a, is like subtracting the transform-offset from the original means
290  // (because a contains the means times inv-vars_.
291  Vector<double> offset(transform_offset_.Range(0, model_dim));
292  a.AddVecVec(-1.0, b, offset, 1.0);
293  stats.a.AddVec(1.0, a);
294  stats.b.AddVec(1.0, b);
295  stats.count += count;
296 }
Vector< BaseFloat > transform_offset_
Definition: fmllr-raw.h:185
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
int32 ModelDim() const
Dimension of the model.
Definition: fmllr-raw.h:92
kaldi::int32 int32
const size_t count
float BaseFloat
Definition: kaldi-types.h:29
void InitSingleFrameStats(const VectorBase< BaseFloat > &data)
Definition: fmllr-raw.cc:93
bool DataHasChanged(const VectorBase< BaseFloat > &data) const
Definition: fmllr-raw.cc:63
void CommitSingleFrameStats()
Definition: fmllr-raw.cc:68

◆ CommitSingleFrameStats()

void CommitSingleFrameStats ( )
private

Definition at line 68 of file fmllr-raw.cc.

References FmllrRawAccs::SingleFrameStats::a, SpMatrix< Real >::AddVec2(), MatrixBase< Real >::AddVecVec(), FmllrRawAccs::SingleFrameStats::b, FmllrRawAccs::SingleFrameStats::count, FmllrRawAccs::count_, PackedMatrix< Real >::Data(), FmllrRawAccs::FullDim(), FmllrRawAccs::ModelDim(), FmllrRawAccs::Q_, VectorBase< Real >::Range(), FmllrRawAccs::SingleFrameStats::s, FmllrRawAccs::S_, PackedMatrix< Real >::SetZero(), FmllrRawAccs::single_frame_stats_, and FmllrRawAccs::temp_.

Referenced by FmllrRawAccs::AccumulateForGmm(), FmllrRawAccs::AccumulateFromPosteriors(), and FmllrRawAccs::Update().

68  {
69  // Commit the stats for this from (in SingleFrameStats).
70  int32 model_dim = ModelDim(), full_dim = FullDim();
71  SingleFrameStats &stats = single_frame_stats_;
72  if (stats.count == 0.0) return;
73 
74  count_ += stats.count;
75 
76  // a_ext and b_ext are a and b extended with the count,
77  // which we'll later use to reconstruct the full stats for
78  // the rejected dimensions.
79  Vector<double> a_ext(model_dim + 1), b_ext(model_dim + 1);
80  a_ext.Range(0, model_dim).CopyFromVec(stats.a);
81  b_ext.Range(0, model_dim).CopyFromVec(stats.b);
82  a_ext(model_dim) = stats.count;
83  b_ext(model_dim) = stats.count;
84  Q_.AddVecVec(1.0, a_ext, Vector<double>(stats.s));
85 
86  temp_.SetZero();
87  temp_.AddVec2(1.0, stats.s);
88  int32 full_dim2 = ((full_dim + 1) * (full_dim + 2)) / 2;
89  SubVector<double> temp_vec(temp_.Data(), full_dim2);
90  S_.AddVecVec(1.0, b_ext, temp_vec);
91 }
Matrix< double > S_
Definition: fmllr-raw.h:196
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
int32 ModelDim() const
Dimension of the model.
Definition: fmllr-raw.h:92
kaldi::int32 int32
void AddVec2(const Real alpha, const VectorBase< OtherReal > &v)
rank-one update, this <– this + alpha v v&#39;
Definition: sp-matrix.cc:946
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
Matrix< double > Q_
Definition: fmllr-raw.h:195
SpMatrix< double > temp_
Definition: fmllr-raw.h:194
void AddVecVec(const Real alpha, const VectorBase< OtherReal > &a, const VectorBase< OtherReal > &b)
*this += alpha * a * b^T

◆ ComputeM()

void ComputeM ( std::vector< Matrix< double > > *  M) const
private

Computes the M_i matrices used in the update, see the extended comment in fmllr-raw.cc for explanation.

Definition at line 412 of file fmllr-raw.cc.

References FmllrRawAccs::full_transform_, FmllrRawAccs::FullDim(), rnnlm::i, rnnlm::j, and FmllrRawAccs::RawDim().

Referenced by FmllrRawAccs::ConvertToSimpleStats().

412  {
413  int32 full_dim = FullDim(), raw_dim = RawDim(),
414  raw_dim2 = raw_dim * (raw_dim + 1);
415  M->resize(full_dim);
416  for (int32 i = 0; i < full_dim; i++)
417  (*M)[i].Resize(raw_dim2, full_dim + 1);
418 
419  // the N's are simpler matrices from which we'll interpolate the M's.
420  // In this loop we imagine w are computing the vector of N's, but
421  // when we get each element, if it's nonzero we propagate it straight
422  // to the M's.
423  for (int32 i = 0; i < full_dim; i++) {
424  // i is index after fMLLR transform; i1 is splicing index,
425  // i2 is cepstral index.
426  int32 i1 = i / raw_dim, i2 = i % raw_dim;
427  for (int32 j = 0; j < raw_dim2; j++) {
428  // j1 is row-index of fMLLR transform, j2 is column-index
429  int32 j1 = j / (raw_dim + 1), j2 = j % (raw_dim + 1);
430  for (int32 k = 0; k < full_dim + 1; k++) {
431  BaseFloat n_ijk;
432  if (j1 != i2) {
433  n_ijk = 0.0;
434  } else if (k == full_dim) {
435  if (j2 == raw_dim) // offset term in fMLLR matrix.
436  n_ijk = 1.0;
437  else
438  n_ijk = 0.0;
439  } else {
440  // k1 is splicing index, k2 is cepstral idnex.
441  int32 k1 = k / raw_dim, k2 = k % raw_dim;
442  if (k1 != i1 || k2 != j2)
443  n_ijk = 0.0;
444  else
445  n_ijk = 1.0;
446  }
447  if (n_ijk != 0.0)
448  for (int32 l = 0; l < full_dim; l++)
449  (*M)[l](j, k) += n_ijk * full_transform_(l, i);
450  }
451  }
452  }
453 }
kaldi::int32 int32
Matrix< BaseFloat > full_transform_
Definition: fmllr-raw.h:183
float BaseFloat
Definition: kaldi-types.h:29
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
int32 RawDim() const
Dimension of raw MFCC (etc.) features.
Definition: fmllr-raw.h:86

◆ ConvertToPerRowStats()

void ConvertToPerRowStats ( const Vector< double > &  simple_linear_stats,
const SpMatrix< double > &  simple_quadratic_stats_sp,
Matrix< double > *  linear_stats,
std::vector< SpMatrix< double > > *  diag_stats,
std::vector< std::vector< Matrix< double > > > *  off_diag_stats 
) const
private

Transform stats into a convenient format for the update.

linear_stats is of dim RawDim() by RawDim() + 1, it's the linear term. diag_stats (of dimension RawDim(), each element of dimension RawDim() + 1 is the quadratic terms w.r.t. the diagonals. off_diag_stats contains the cross-terms between different rows; it is indexed [i][j], with 0 <= i < RawDim(), and j < i, and each element is of dimension RawDim() + 1 by RawDim() + 1. The [i][j]'th element is interpreted as follows: the inner product with the [i'th row] [element [i][j]] [j'th row] is the term in the objective function. This function resizes its output.

Definition at line 493 of file fmllr-raw.cc.

References MatrixBase< Real >::CopyRowsFromVec(), rnnlm::i, rnnlm::j, kaldi::kTakeMean, FmllrRawAccs::RawDim(), and Matrix< Real >::Resize().

Referenced by FmllrRawAccs::Update().

498  {
499 
500  // get it as a Matrix, which makes it easier to extract sub-parts.
501  Matrix<double> simple_quadratic_stats(simple_quadratic_stats_sp);
502 
503  linear_stats->Resize(RawDim(), RawDim() + 1);
504  linear_stats->CopyRowsFromVec(simple_linear_stats);
505  diag_stats->resize(RawDim());
506  off_diag_stats->resize(RawDim());
507 
508  // Set *diag_stats
509  int32 rd1 = RawDim() + 1;
510  for (int32 i = 0; i < RawDim(); i++) {
511  SubMatrix<double> this_diag(simple_quadratic_stats,
512  i * rd1, rd1,
513  i * rd1, rd1);
514  (*diag_stats)[i].Resize(RawDim() + 1);
515  (*diag_stats)[i].CopyFromMat(this_diag, kTakeMean);
516  }
517 
518  for (int32 i = 0; i < RawDim(); i++) {
519  (*off_diag_stats)[i].resize(i);
520  for (int32 j = 0; j < i; j++) {
521  SubMatrix<double> this_off_diag(simple_quadratic_stats,
522  i * rd1, rd1,
523  j * rd1, rd1);
524  (*off_diag_stats)[i][j] = this_off_diag;
525  }
526  }
527 }
kaldi::int32 int32
int32 RawDim() const
Dimension of raw MFCC (etc.) features.
Definition: fmllr-raw.h:86

◆ ConvertToSimpleStats()

void ConvertToSimpleStats ( Vector< double > *  simple_linear_stats,
SpMatrix< double > *  simple_quadratic_stats 
) const
private

Converts from the Q and S stats to a simple objective function of the form l .

simple_linear_stats -0.5 l^t simple_quadratic_stats l, plus the determinant term, where l is the linearized transform.

Definition at line 455 of file fmllr-raw.cc.

References VectorBase< Real >::AddMatVec(), SpMatrix< Real >::AddSmat2Sp(), FmllrRawAccs::ComputeM(), VectorBase< Real >::CopyFromVec(), PackedMatrix< Real >::Data(), FmllrRawAccs::FullDim(), rnnlm::i, kaldi::kNoTrans, FmllrRawAccs::ModelDim(), FmllrRawAccs::Q_, FmllrRawAccs::RawDim(), SpMatrix< Real >::Resize(), Vector< Real >::Resize(), MatrixBase< Real >::Row(), FmllrRawAccs::S_, VectorBase< Real >::Scale(), and FmllrRawAccs::transform_offset_.

Referenced by FmllrRawAccs::Update().

457  {
458  std::vector<Matrix<double> > M;
459  ComputeM(&M);
460 
461  int32 full_dim = FullDim(), raw_dim = RawDim(), model_dim = ModelDim(),
462  raw_dim2 = raw_dim * (raw_dim + 1),
463  full_dim2 = ((full_dim+1)*(full_dim+2))/2;
464  simple_linear_stats->Resize(raw_dim2);
465  simple_quadratic_stats->Resize(raw_dim2);
466  for (int32 i = 0; i < full_dim; i++) {
467  Vector<double> q_i(full_dim + 1);
468  SpMatrix<double> S_i(full_dim + 1);
469  SubVector<double> S_i_vec(S_i.Data(), full_dim2);
470  if (i < model_dim) {
471  q_i.CopyFromVec(Q_.Row(i));
472  S_i_vec.CopyFromVec(S_.Row(i));
473  } else {
474  q_i.CopyFromVec(Q_.Row(model_dim)); // The last row contains stats proportional
475  // to "count", which we need to modify to be correct.
476  q_i.Scale(-transform_offset_(i)); // These stats are zero (corresponding to
477  // a zero-mean model) if there is no offset in the LDA transform. Note:
478  // the two statements above are the equivalent, for the rejected dims,
479  // of the statement "a.AddVecVec(-1.0, b, offset);" for the kept ones.
480  //
481  S_i_vec.CopyFromVec(S_.Row(model_dim)); // these are correct, and
482  // all the same (corresponds to unit variance).
483  }
484  // The equation v = \sum_i M_i q_i:
485  simple_linear_stats->AddMatVec(1.0, M[i], kNoTrans, q_i, 1.0);
486  // The equation W = \sum_i M_i S_i M_i^T
487  // Here, M[i] is quite sparse, so AddSmat2Sp will be faster.
488  simple_quadratic_stats->AddSmat2Sp(1.0, M[i], kNoTrans, S_i, 1.0);
489  }
490 }
Matrix< double > S_
Definition: fmllr-raw.h:196
Vector< BaseFloat > transform_offset_
Definition: fmllr-raw.h:185
int32 ModelDim() const
Dimension of the model.
Definition: fmllr-raw.h:92
void ComputeM(std::vector< Matrix< double > > *M) const
Computes the M_i matrices used in the update, see the extended comment in fmllr-raw.cc for explanation.
Definition: fmllr-raw.cc:412
kaldi::int32 int32
void Resize(MatrixIndexT length, MatrixResizeType resize_type=kSetZero)
Set vector to a specified size (can be zero).
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
void AddSmat2Sp(const Real alpha, const MatrixBase< Real > &M, MatrixTransposeType transM, const SpMatrix< Real > &A, const Real beta=0.0)
This is a version of AddMat2Sp specialized for when M is fairly sparse.
Definition: sp-matrix.cc:1026
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
Definition: kaldi-matrix.h:188
Matrix< double > Q_
Definition: fmllr-raw.h:195
void AddMatVec(const Real alpha, const MatrixBase< Real > &M, const MatrixTransposeType trans, const VectorBase< Real > &v, const Real beta)
Add matrix times vector : this <– beta*this + alpha*M*v.
Definition: kaldi-vector.cc:92
int32 RawDim() const
Dimension of raw MFCC (etc.) features.
Definition: fmllr-raw.h:86
void Resize(MatrixIndexT nRows, MatrixResizeType resize_type=kSetZero)
Definition: sp-matrix.h:81

◆ DataHasChanged()

bool DataHasChanged ( const VectorBase< BaseFloat > &  data) const
private

Definition at line 63 of file fmllr-raw.cc.

References VectorBase< Real >::ApproxEqual(), VectorBase< Real >::Dim(), FmllrRawAccs::FullDim(), KALDI_ASSERT, FmllrRawAccs::SingleFrameStats::s, and FmllrRawAccs::single_frame_stats_.

Referenced by FmllrRawAccs::AccumulateForGmm(), and FmllrRawAccs::AccumulateFromPosteriors().

63  {
64  KALDI_ASSERT(data.Dim() == FullDim());
65  return !data.ApproxEqual(single_frame_stats_.s.Range(0, FullDim()), 0.0);
66 }
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ FullDim()

int32 FullDim ( ) const
inline

Full feature dimension after splicing.

Definition at line 88 of file fmllr-raw.h.

Referenced by FmllrRawAccs::AccumulateForGmm(), FmllrRawAccs::CommitSingleFrameStats(), FmllrRawAccs::ComputeM(), FmllrRawAccs::ConvertToSimpleStats(), FmllrRawAccs::DataHasChanged(), and FmllrRawAccs::InitSingleFrameStats().

88 { return full_transform_.NumRows(); }
Matrix< BaseFloat > full_transform_
Definition: fmllr-raw.h:183
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
Definition: kaldi-matrix.h:64

◆ GetAuxf()

double GetAuxf ( const Vector< double > &  simple_linear_stats,
const SpMatrix< double > &  simple_quadratic_stats,
const Matrix< double > &  fmllr_mat 
) const
private

Compute the auxiliary function for this matrix.

Definition at line 529 of file fmllr-raw.cc.

References VectorBase< Real >::CopyRowsFromMat(), FmllrRawAccs::count_, MatrixBase< Real >::LogDet(), FmllrRawAccs::RawDim(), FmllrRawAccs::SpliceWidth(), kaldi::VecSpVec(), and kaldi::VecVec().

Referenced by FmllrRawAccs::Update().

531  {
532  // linearize transform...
533  int32 raw_dim = RawDim(), spice_width = SpliceWidth();
534  Vector<double> fmllr_vec(raw_dim * (raw_dim + 1));
535  fmllr_vec.CopyRowsFromMat(fmllr_mat);
536  SubMatrix<double> square_part(fmllr_mat, 0, raw_dim,
537  0, raw_dim);
538  double logdet = square_part.LogDet();
539  return VecVec(fmllr_vec, simple_linear_stats) -
540  0.5 * VecSpVec(fmllr_vec, simple_quadratic_stats, fmllr_vec) +
541  logdet * spice_width * count_;
542 }
int32 SpliceWidth() const
Number of frames that are spliced together each time.
Definition: fmllr-raw.h:90
kaldi::int32 int32
Real VecSpVec(const VectorBase< Real > &v1, const SpMatrix< Real > &M, const VectorBase< Real > &v2)
Computes v1^T * M * v2.
Definition: sp-matrix.cc:964
int32 RawDim() const
Dimension of raw MFCC (etc.) features.
Definition: fmllr-raw.h:86
Real VecVec(const VectorBase< Real > &a, const VectorBase< Real > &b)
Returns dot product between v1 and v2.
Definition: kaldi-vector.cc:37

◆ InitSingleFrameStats()

void InitSingleFrameStats ( const VectorBase< BaseFloat > &  data)
private

Definition at line 93 of file fmllr-raw.cc.

References FmllrRawAccs::SingleFrameStats::a, FmllrRawAccs::SingleFrameStats::b, FmllrRawAccs::SingleFrameStats::count, VectorBase< Real >::Dim(), FmllrRawAccs::full_transform_, FmllrRawAccs::FullDim(), KALDI_ASSERT, kaldi::kNoTrans, FmllrRawAccs::SingleFrameStats::s, VectorBase< Real >::SetZero(), FmllrRawAccs::single_frame_stats_, FmllrRawAccs::transform_offset_, and FmllrRawAccs::SingleFrameStats::transformed_data.

Referenced by FmllrRawAccs::AccumulateForGmm(), and FmllrRawAccs::AccumulateFromPosteriors().

93  {
94  SingleFrameStats &stats = single_frame_stats_;
95  int32 full_dim = FullDim();
96  KALDI_ASSERT(data.Dim() == full_dim);
97  stats.s.Range(0, full_dim).CopyFromVec(data);
98  stats.s(full_dim) = 1.0;
99  stats.transformed_data.AddMatVec(1.0, full_transform_, kNoTrans, data, 0.0);
100  stats.transformed_data.AddVec(1.0, transform_offset_);
101  stats.count = 0.0;
102  stats.a.SetZero();
103  stats.b.SetZero();
104 }
Vector< BaseFloat > transform_offset_
Definition: fmllr-raw.h:185
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
kaldi::int32 int32
Matrix< BaseFloat > full_transform_
Definition: fmllr-raw.h:183
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ KALDI_DISALLOW_COPY_AND_ASSIGN()

KALDI_DISALLOW_COPY_AND_ASSIGN ( FmllrRawAccs  )
private

◆ ModelDim()

int32 ModelDim ( ) const
inline

◆ RawDim()

int32 RawDim ( ) const
inline

Dimension of raw MFCC (etc.) features.

Definition at line 86 of file fmllr-raw.h.

Referenced by FmllrRawAccs::ComputeM(), FmllrRawAccs::ConvertToPerRowStats(), FmllrRawAccs::ConvertToSimpleStats(), FmllrRawAccs::GetAuxf(), and FmllrRawAccs::Update().

86 { return raw_dim_; }

◆ SetZero()

void SetZero ( )

◆ SpliceWidth()

int32 SpliceWidth ( ) const
inline

Number of frames that are spliced together each time.

Definition at line 90 of file fmllr-raw.h.

Referenced by FmllrRawAccs::GetAuxf(), and FmllrRawAccs::Update().

90 { return FullDim() / RawDim(); }
int32 FullDim() const
Full feature dimension after splicing.
Definition: fmllr-raw.h:88
int32 RawDim() const
Dimension of raw MFCC (etc.) features.
Definition: fmllr-raw.h:86

◆ Update()

void Update ( const FmllrRawOptions opts,
MatrixBase< BaseFloat > *  raw_fmllr_mat,
BaseFloat objf_impr,
BaseFloat count 
)

Update "raw_fmllr_mat"; it should have the correct dimension and reasonable values at entry (see the function InitFmllr in fmllr-diag-gmm.h for how to initialize it.) The only reason this function is not const is because we may have to call CommitSingleFrameStats().

Definition at line 299 of file fmllr-raw.cc.

References VectorBase< Real >::AddMatVec(), FmllrRawAccs::CommitSingleFrameStats(), FmllrRawAccs::ConvertToPerRowStats(), FmllrRawAccs::ConvertToSimpleStats(), MatrixBase< Real >::CopyFromMat(), VectorBase< Real >::CopyFromVec(), FmllrRawAccs::SingleFrameStats::count, FmllrRawAccs::count_, kaldi::FmllrInnerUpdate(), FmllrRawAccs::GetAuxf(), kaldi::GetVerboseLevel(), rnnlm::i, MatrixBase< Real >::IsZero(), KALDI_ASSERT, KALDI_VLOG, KALDI_WARN, kaldi::kNoTrans, kaldi::kTrans, FmllrRawOptions::min_count, FmllrRawOptions::num_iters, MatrixBase< Real >::NumCols(), MatrixBase< Real >::NumRows(), FmllrRawAccs::RawDim(), MatrixBase< Real >::Row(), FmllrRawAccs::single_frame_stats_, and FmllrRawAccs::SpliceWidth().

Referenced by kaldi::UnitTestFmllrRaw().

302  {
303  // First commit any pending stats from the last frame.
304  if (single_frame_stats_.count != 0.0)
306 
307  if (this->count_ < opts.min_count) {
308  KALDI_WARN << "Not updating (raw) fMLLR since count " << this->count_
309  << " is less than min count " << opts.min_count;
310  *objf_impr = 0.0;
311  *count = this->count_;
312  return;
313  }
314  KALDI_ASSERT(raw_fmllr_mat->NumRows() == RawDim() &&
315  raw_fmllr_mat->NumCols() == RawDim() + 1 &&
316  !raw_fmllr_mat->IsZero());
317  Matrix<double> fmllr_mat(*raw_fmllr_mat); // temporary, double-precision version
318  // of matrix.
319 
320 
321  Matrix<double> linear_stats; // like K in diagonal update.
322  std::vector<SpMatrix<double> > diag_stats; // like G in diagonal update.
323  // Note: we will invert these.
324  std::vector<std::vector<Matrix<double> > > off_diag_stats; // these will
325  // contribute to the linear term.
326 
327  Vector<double> simple_linear_stats;
328  SpMatrix<double> simple_quadratic_stats;
329  ConvertToSimpleStats(&simple_linear_stats, &simple_quadratic_stats);
330 
331  ConvertToPerRowStats(simple_linear_stats, simple_quadratic_stats,
332  &linear_stats, &diag_stats, &off_diag_stats);
333 
334  try {
335  for (size_t i = 0; i < diag_stats.size(); i++) {
336  diag_stats[i].Invert();
337  }
338  } catch (...) {
339  KALDI_WARN << "Error inverting stats matrices for fMLLR "
340  << "[min-count too small? Bad data?], not updating.";
341  return;
342  }
343 
344  int32 raw_dim = RawDim(), splice_width = SpliceWidth();
345 
346  double effective_beta = count_ * splice_width; // We "count" the determinant
347  // splice_width times in the objective function.
348 
349  double auxf_orig = GetAuxf(simple_linear_stats, simple_quadratic_stats,
350  fmllr_mat);
351  for (int32 iter = 0; iter < opts.num_iters; iter++) {
352  for (int32 row = 0; row < raw_dim; row++) {
353  SubVector<double> this_row(fmllr_mat, row);
354  Vector<double> this_linear(raw_dim + 1); // Here, k_i is the linear term
355  // in the auxf expressed as a function of this row.
356  this_linear.CopyFromVec(linear_stats.Row(row));
357  for (int32 row2 = 0; row2 < raw_dim; row2++) {
358  if (row2 != row) {
359  if (row2 < row) {
360  this_linear.AddMatVec(-1.0, off_diag_stats[row][row2], kNoTrans,
361  fmllr_mat.Row(row2), 1.0);
362  } else {
363  // We won't have the element [row][row2] stored, but use symmetry.
364  this_linear.AddMatVec(-1.0, off_diag_stats[row2][row], kTrans,
365  fmllr_mat.Row(row2), 1.0);
366  }
367  }
368  }
369  FmllrInnerUpdate(diag_stats[row],
370  this_linear,
371  effective_beta,
372  row,
373  &fmllr_mat);
374  }
375  if (GetVerboseLevel() >= 2) {
376  double cur_auxf = GetAuxf(simple_linear_stats, simple_quadratic_stats,
377  fmllr_mat),
378  auxf_change = cur_auxf - auxf_orig;
379  KALDI_VLOG(2) << "Updating raw fMLLR: objf improvement per frame was "
380  << (auxf_change / this->count_) << " over "
381  << this->count_ << " frames, by the " << iter
382  << "'th iteration";
383  }
384  }
385  double auxf_final = GetAuxf(simple_linear_stats, simple_quadratic_stats,
386  fmllr_mat),
387  auxf_change = auxf_final - auxf_orig;
388  *count = this->count_;
389  KALDI_VLOG(1) << "Updating raw fMLLR: objf improvement per frame was "
390  << (auxf_change / this->count_) << " over "
391  << this->count_ << " frames.";
392  if (auxf_final > auxf_orig) {
393  *objf_impr = auxf_change;
394  *count = this->count_;
395  raw_fmllr_mat->CopyFromMat(fmllr_mat);
396  } else {
397  *objf_impr = 0.0;
398  // don't update "raw_fmllr_mat"
399  }
400 }
SingleFrameStats single_frame_stats_
Definition: fmllr-raw.h:188
int32 SpliceWidth() const
Number of frames that are spliced together each time.
Definition: fmllr-raw.h:90
void ConvertToSimpleStats(Vector< double > *simple_linear_stats, SpMatrix< double > *simple_quadratic_stats) const
Converts from the Q and S stats to a simple objective function of the form l .
Definition: fmllr-raw.cc:455
int32 GetVerboseLevel()
Get verbosity level, usually set via command line &#39;–verbose=&#39; switch.
Definition: kaldi-error.h:60
kaldi::int32 int32
const size_t count
void ConvertToPerRowStats(const Vector< double > &simple_linear_stats, const SpMatrix< double > &simple_quadratic_stats_sp, Matrix< double > *linear_stats, std::vector< SpMatrix< double > > *diag_stats, std::vector< std::vector< Matrix< double > > > *off_diag_stats) const
Transform stats into a convenient format for the update.
Definition: fmllr-raw.cc:493
#define KALDI_WARN
Definition: kaldi-error.h:150
double GetAuxf(const Vector< double > &simple_linear_stats, const SpMatrix< double > &simple_quadratic_stats, const Matrix< double > &fmllr_mat) const
Compute the auxiliary function for this matrix.
Definition: fmllr-raw.cc:529
void FmllrInnerUpdate(SpMatrix< double > &inv_G, VectorBase< double > &k, double beta, int32 row, MatrixBase< double > *transform)
This function does one row of the inner-loop fMLLR transform update.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
#define KALDI_VLOG(v)
Definition: kaldi-error.h:156
int32 RawDim() const
Dimension of raw MFCC (etc.) features.
Definition: fmllr-raw.h:86
void CommitSingleFrameStats()
Definition: fmllr-raw.cc:68

Member Data Documentation

◆ count_

◆ full_transform_

Matrix<BaseFloat> full_transform_
private

◆ model_dim_

int32 model_dim_
private

Definition at line 181 of file fmllr-raw.h.

◆ Q_

◆ raw_dim_

int32 raw_dim_
private

Definition at line 180 of file fmllr-raw.h.

◆ S_

◆ single_frame_stats_

◆ temp_

SpMatrix<double> temp_
private

◆ transform_offset_


The documentation for this class was generated from the following files: