Posterior_group

Classes

class  PosteriorHolder
 
class  GaussPostHolder
 
struct  CompareReverseSecond
 

Typedefs

typedef std::vector< std::vector< std::pair< int32, BaseFloat > > > Posterior
 Posterior is a typedef for storing acoustic-state (actually, transition-id) posteriors over an utterance. More...
 
typedef std::vector< std::vector< std::pair< int32, Vector< BaseFloat > > > > GaussPost
 GaussPost is a typedef for storing Gaussian-level posteriors for an utterance. More...
 
typedef TableWriter< PosteriorHolderPosteriorWriter
 
typedef SequentialTableReader< PosteriorHolderSequentialPosteriorReader
 
typedef RandomAccessTableReader< PosteriorHolderRandomAccessPosteriorReader
 
typedef TableWriter< GaussPostHolderGaussPostWriter
 
typedef SequentialTableReader< GaussPostHolderSequentialGaussPostReader
 
typedef RandomAccessTableReader< GaussPostHolderRandomAccessGaussPostReader
 

Functions

void WritePosterior (std::ostream &os, bool binary, const Posterior &post)
 stand-alone function for writing a Posterior. More...
 
void ReadPosterior (std::istream &os, bool binary, Posterior *post)
 stand-alone function for reading a Posterior. More...
 
void ScalePosterior (BaseFloat scale, Posterior *post)
 Scales the BaseFloat (weight) element in the posterior entries. More...
 
BaseFloat TotalPosterior (const Posterior &post)
 Returns the total of all the weights in "post". More...
 
bool PosteriorEntriesAreDisjoint (const std::vector< std::pair< int32, BaseFloat > > &post_elem1, const std::vector< std::pair< int32, BaseFloat > > &post_elem2)
 Returns true if the two lists of pairs have no common .first element. More...
 
int32 MergePosteriors (const Posterior &post1, const Posterior &post2, bool merge, bool drop_frames, Posterior *post)
 Merge two sets of posteriors, which must have the same length. More...
 
BaseFloat VectorToPosteriorEntry (const VectorBase< BaseFloat > &log_likes, int32 num_gselect, BaseFloat min_post, std::vector< std::pair< int32, BaseFloat > > *post_entry)
 Given a vector of log-likelihoods (typically of Gaussians in a GMM but could be of pdf-ids), a number gselect >= 1 and a minimum posterior 0 <= min_post < 1, it gets the posterior for each element of log-likes by applying Softmax(), then prunes the posteriors using "gselect" and "min_post" (keeping at least one), and outputs the result into "post_entry", sorted from greatest to least posterior. More...
 
void AlignmentToPosterior (const std::vector< int32 > &ali, Posterior *post)
 Convert an alignment to a posterior (with a scale of 1.0 on each entry). More...
 
void SortPosteriorByPdfs (const TransitionModel &tmodel, Posterior *post)
 Sorts posterior entries so that transition-ids with same pdf-id are next to each other. More...
 
void ConvertPosteriorToPdfs (const TransitionModel &tmodel, const Posterior &post_in, Posterior *post_out)
 Converts a posterior over transition-ids to be a posterior over pdf-ids. More...
 
void ConvertPosteriorToPhones (const TransitionModel &tmodel, const Posterior &post_in, Posterior *post_out)
 Converts a posterior over transition-ids to be a posterior over phones. More...
 
void WeightSilencePost (const TransitionModel &trans_model, const ConstIntegerSet< int32 > &silence_set, BaseFloat silence_scale, Posterior *post)
 Weight any silence phones in the posterior (i.e. More...
 
void WeightSilencePostDistributed (const TransitionModel &trans_model, const ConstIntegerSet< int32 > &silence_set, BaseFloat silence_scale, Posterior *post)
 This is similar to WeightSilencePost, except that on each frame it works out the amount by which the overall posterior would be reduced, and scales down everything on that frame by the same amount. More...
 
template<typename Real >
void PosteriorToMatrix (const Posterior &post, const int32 post_dim, Matrix< Real > *mat)
 This converts a Posterior to a Matrix. More...
 
template<typename Real >
void PosteriorToPdfMatrix (const Posterior &post, const TransitionModel &model, Matrix< Real > *mat)
 This converts a Posterior to a Matrix. More...
 

Detailed Description

Typedef Documentation

◆ GaussPost

typedef std::vector<std::vector<std::pair<int32, Vector<BaseFloat> > > > GaussPost

GaussPost is a typedef for storing Gaussian-level posteriors for an utterance.

the "int32" is a transition-id, and the Vector<BaseFloat> is a vector of Gaussian posteriors. WARNING: We changed "int32" from transition-id to pdf-id, and the change is applied for all programs using GaussPost. This is for efficiency purpose. We also changed the name slightly from GauPost to GaussPost to reduce the chance that the change will go un-noticed in downstream code.

Definition at line 51 of file posterior.h.

◆ GaussPostWriter

Definition at line 144 of file posterior.h.

◆ Posterior

typedef std::vector<std::vector<std::pair<int32, BaseFloat> > > Posterior

Posterior is a typedef for storing acoustic-state (actually, transition-id) posteriors over an utterance.

The "int32" is a transition-id, and the BaseFloat is a probability (typically between zero and one).

Definition at line 42 of file posterior.h.

◆ PosteriorWriter

Definition at line 138 of file posterior.h.

◆ RandomAccessGaussPostReader

◆ RandomAccessPosteriorReader

◆ SequentialGaussPostReader

◆ SequentialPosteriorReader

Function Documentation

◆ AlignmentToPosterior()

void AlignmentToPosterior ( const std::vector< int32 > &  ali,
Posterior post 
)

Convert an alignment to a posterior (with a scale of 1.0 on each entry).

Definition at line 290 of file posterior.cc.

References rnnlm::i.

Referenced by DiscriminativeComputation::ComputeObjfAndDeriv(), kaldi::LatticeForwardBackwardMmi(), main(), and CompareReverseSecond::operator()().

291  {
292  post->clear();
293  post->resize(ali.size());
294  for (size_t i = 0; i < ali.size(); i++) {
295  (*post)[i].resize(1);
296  (*post)[i][0].first = ali[i];
297  (*post)[i][0].second = 1.0;
298  }
299 }

◆ ConvertPosteriorToPdfs()

void ConvertPosteriorToPdfs ( const TransitionModel tmodel,
const Posterior post_in,
Posterior post_out 
)

Converts a posterior over transition-ids to be a posterior over pdf-ids.

Definition at line 322 of file posterior.cc.

References rnnlm::i, rnnlm::j, and TransitionModel::TransitionIdToPdf().

Referenced by kaldi::AccStatsForUtterance(), kaldi::AccumulateForUtterance(), DiscriminativeComputation::ComputeObjfAndDeriv(), kaldi::nnet2::ExampleToPdfPost(), NnetDiscriminativeUpdater::GetDiscriminativePosteriors(), SingleUtteranceGmmDecoder::GetGaussianPosteriors(), kaldi::LatticeForwardBackwardMmi(), main(), and CompareReverseSecond::operator()().

324  {
325  post_out->clear();
326  post_out->resize(post_in.size());
327  for (size_t i = 0; i < post_out->size(); i++) {
328  unordered_map<int32, BaseFloat> pdf_to_post;
329  for (size_t j = 0; j < post_in[i].size(); j++) {
330  int32 tid = post_in[i][j].first,
331  pdf_id = tmodel.TransitionIdToPdf(tid);
332  BaseFloat post = post_in[i][j].second;
333  if (pdf_to_post.count(pdf_id) == 0)
334  pdf_to_post[pdf_id] = post;
335  else
336  pdf_to_post[pdf_id] += post;
337  }
338  (*post_out)[i].reserve(pdf_to_post.size());
339  for (unordered_map<int32, BaseFloat>::const_iterator iter =
340  pdf_to_post.begin(); iter != pdf_to_post.end(); ++iter) {
341  if (iter->second != 0.0)
342  (*post_out)[i].push_back(
343  std::make_pair(iter->first, iter->second));
344  }
345  }
346 }
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29

◆ ConvertPosteriorToPhones()

void ConvertPosteriorToPhones ( const TransitionModel tmodel,
const Posterior post_in,
Posterior post_out 
)

Converts a posterior over transition-ids to be a posterior over phones.

Definition at line 348 of file posterior.cc.

References rnnlm::i, rnnlm::j, and TransitionModel::TransitionIdToPhone().

Referenced by main(), and CompareReverseSecond::operator()().

350  {
351  post_out->clear();
352  post_out->resize(post_in.size());
353  for (size_t i = 0; i < post_out->size(); i++) {
354  std::map<int32, BaseFloat> phone_to_post;
355  for (size_t j = 0; j < post_in[i].size(); j++) {
356  int32 tid = post_in[i][j].first,
357  phone_id = tmodel.TransitionIdToPhone(tid);
358  BaseFloat post = post_in[i][j].second;
359  if (phone_to_post.count(phone_id) == 0)
360  phone_to_post[phone_id] = post;
361  else
362  phone_to_post[phone_id] += post;
363  }
364  (*post_out)[i].reserve(phone_to_post.size());
365  for (std::map<int32, BaseFloat>::const_iterator iter =
366  phone_to_post.begin(); iter != phone_to_post.end(); ++iter) {
367  if (iter->second != 0.0)
368  (*post_out)[i].push_back(
369  std::make_pair(iter->first, iter->second));
370  }
371  }
372 }
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29

◆ MergePosteriors()

int32 MergePosteriors ( const Posterior post1,
const Posterior post2,
bool  merge,
bool  drop_frames,
Posterior post 
)

Merge two sets of posteriors, which must have the same length.

If "merge" is true, it will make a common entry whenever there are duplicated entries, adding up the weights. If "drop_frames" is true, for frames where the two sets of posteriors were originally disjoint, makes no entries for that frame (relates to frame dropping, or drop_frames, see Vesely et al, ICASSP 2013). Returns the number of frames for which the two posteriors were disjoint (i.e. no common transition-ids or whatever index we are using).

Definition at line 258 of file posterior.cc.

References rnnlm::i, KALDI_ASSERT, kaldi::MergePairVectorSumming(), and kaldi::PosteriorEntriesAreDisjoint().

Referenced by kaldi::LatticeForwardBackwardMmi(), and main().

262  {
263  KALDI_ASSERT(post1.size() == post2.size()); // precondition.
264  post->resize(post1.size());
265 
266  int32 num_disjoint = 0;
267  for (size_t i = 0; i < post->size(); i++) {
268  (*post)[i].reserve(post1[i].size() + post2[i].size());
269  (*post)[i].insert((*post)[i].end(),
270  post1[i].begin(), post1[i].end());
271  (*post)[i].insert((*post)[i].end(),
272  post2[i].begin(), post2[i].end());
273  if (merge) { // combine and sum up entries with same transition-id.
274  MergePairVectorSumming(&((*post)[i])); // This sorts on
275  // the transition-id merges the entries with the same
276  // key (i.e. same .first element; same transition-id), and
277  // gets rid of entries with zero .second element.
278  } else { // just to keep them pretty, merge them.
279  std::sort( (*post)[i].begin(), (*post)[i].end() );
280  }
281  if (PosteriorEntriesAreDisjoint(post1[i], post2[i])) {
282  num_disjoint++;
283  if (drop_frames)
284  (*post)[i].clear();
285  }
286  }
287  return num_disjoint;
288 }
kaldi::int32 int32
bool PosteriorEntriesAreDisjoint(const std::vector< std::pair< int32, BaseFloat > > &post_elem1, const std::vector< std::pair< int32, BaseFloat > > &post_elem2)
Returns true if the two lists of pairs have no common .first element.
Definition: posterior.cc:242
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
void MergePairVectorSumming(std::vector< std::pair< I, F > > *vec)
For a vector of pair<I, F> where I is an integer and F a floating-point or integer type...
Definition: stl-utils.h:288

◆ PosteriorEntriesAreDisjoint()

bool PosteriorEntriesAreDisjoint ( const std::vector< std::pair< int32, BaseFloat > > &  post_elem1,
const std::vector< std::pair< int32, BaseFloat > > &  post_elem2 
)

Returns true if the two lists of pairs have no common .first element.

Definition at line 242 of file posterior.cc.

References rnnlm::i.

Referenced by kaldi::MergePosteriors().

244  {
245  unordered_set<int32> set1;
246  for (size_t i = 0; i < post_elem1.size(); i++) set1.insert(post_elem1[i].first);
247  for (size_t i = 0; i < post_elem2.size(); i++)
248  if (set1.count(post_elem2[i].first) != 0) return false;
249  return true; // The sets are disjoint.
250 }

◆ PosteriorToMatrix()

void PosteriorToMatrix ( const Posterior post,
const int32  post_dim,
Matrix< Real > *  mat 
)

This converts a Posterior to a Matrix.

The number of matrix-rows is the same as the 'post.size()', the number of matrix-columns is defined by 'post_dim'. The elements which are not specified in 'Posterior' are equal to zero.

Definition at line 512 of file posterior.cc.

References rnnlm::i, KALDI_ERR, kaldi::kSetZero, kaldi::PosteriorToMatrix< double >(), kaldi::PosteriorToMatrix< float >(), and Matrix< Real >::Resize().

Referenced by kaldi::AppendPostToFeats(), main(), and CompareReverseSecond::operator()().

513  {
514  // Make a host-matrix,
515  int32 num_rows = post.size();
516  mat->Resize(num_rows, post_dim, kSetZero); // zero-filled
517  // Fill from Posterior,
518  for (int32 t = 0; t < post.size(); t++) {
519  for (int32 i = 0; i < post[t].size(); i++) {
520  int32 col = post[t][i].first;
521  if (col >= post_dim) {
522  KALDI_ERR << "Out-of-bound Posterior element with index " << col
523  << ", higher than number of columns " << post_dim;
524  }
525  (*mat)(t, col) = post[t][i].second;
526  }
527  }
528 }
kaldi::int32 int32
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ PosteriorToPdfMatrix()

void PosteriorToPdfMatrix ( const Posterior post,
const TransitionModel model,
Matrix< Real > *  mat 
)

This converts a Posterior to a Matrix.

The number of matrix-rows is the same as the 'post.size()', the number of matrix-columns is defined by 'NumPdfs' in the TransitionModel. The elements which are not specified in 'Posterior' are equal to zero.

Definition at line 539 of file posterior.cc.

References rnnlm::i, KALDI_ERR, kaldi::kSetZero, TransitionModel::NumPdfs(), kaldi::PosteriorToPdfMatrix< double >(), kaldi::PosteriorToPdfMatrix< float >(), Matrix< Real >::Resize(), and TransitionModel::TransitionIdToPdf().

Referenced by CompareReverseSecond::operator()().

541  {
542  // Allocate the matrix,
543  int32 num_rows = post.size(),
544  num_cols = model.NumPdfs();
545  mat->Resize(num_rows, num_cols, kSetZero); // zero-filled,
546  // Fill from Posterior,
547  for (int32 t = 0; t < post.size(); t++) {
548  for (int32 i = 0; i < post[t].size(); i++) {
549  int32 col = model.TransitionIdToPdf(post[t][i].first);
550  if (col >= num_cols) {
551  KALDI_ERR << "Out-of-bound Posterior element with index " << col
552  << ", higher than number of columns " << num_cols;
553  }
554  (*mat)(t, col) += post[t][i].second; // sum,
555  }
556  }
557 }
kaldi::int32 int32
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ ReadPosterior()

void ReadPosterior ( std::istream &  is,
bool  binary,
Posterior post 
)

stand-alone function for reading a Posterior.

Definition at line 64 of file posterior.cc.

References kaldi::ConvertStringToInteger(), rnnlm::i, KALDI_ERR, and kaldi::ReadBasicType().

Referenced by main(), PosteriorHolder::Read(), and kaldi::TestPosteriorIo().

64  {
65  post->clear();
66  if (binary) {
67  int32 sz;
68  ReadBasicType(is, true, &sz);
69  if (sz < 0 || sz > 10000000)
70  KALDI_ERR << "Reading posterior: got negative or improbably large size"
71  << sz;
72  post->resize(sz);
73  for (Posterior::iterator iter = post->begin(); iter != post->end(); ++iter) {
74  int32 sz2;
75  ReadBasicType(is, true, &sz2);
76  if (sz2 < 0)
77  KALDI_ERR << "Reading posteriors: got negative size";
78  iter->resize(sz2);
79  for (std::vector<std::pair<int32, BaseFloat> >::iterator iter2=iter->begin();
80  iter2 != iter->end();
81  iter2++) {
82  ReadBasicType(is, true, &(iter2->first));
83  ReadBasicType(is, true, &(iter2->second));
84  }
85  }
86  } else {
87  std::string line;
88  getline(is, line); // This will discard the \n, if present.
89  // The Posterior is terminated by a newlinhe.
90  if (is.fail())
91  KALDI_ERR << "holder of Posterior: error reading line " << (is.eof() ? "[eof]" : "");
92  std::istringstream line_is(line);
93  while (1) {
94  std::string str;
95  line_is >> std::ws; // eat up whitespace.
96  if (line_is.eof()) break;
97  line_is >> str;
98  if (str != "[") {
99  int32 str_int;
100  // if str is an integer, we can give a slightly more concrete suggestion
101  // of what might have gone wrong.
102  KALDI_ERR << "Reading Posterior object: expecting [, got '" << str
103  << (ConvertStringToInteger(str, &str_int) ?
104  "': did you provide alignments instead of posteriors?" :
105  "'.");
106  }
107  std::vector<std::pair<int32, BaseFloat> > this_vec;
108  while (1) {
109  line_is >> std::ws;
110  if (line_is.peek() == ']') {
111  line_is.get();
112  break;
113  }
114  int32 i; BaseFloat p;
115  line_is >> i >> p;
116  if (line_is.fail())
117  KALDI_ERR << "Error reading Posterior object (could not get data after \"[\");";
118  this_vec.push_back(std::make_pair(i, p));
119  }
120  post->push_back(this_vec);
121  }
122  }
123 }
bool ConvertStringToInteger(const std::string &str, Int *out)
Converts a string into an integer via strtoll and returns false if there was any kind of problem (i...
Definition: text-utils.h:118
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
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ ScalePosterior()

void ScalePosterior ( BaseFloat  scale,
Posterior post 
)

Scales the BaseFloat (weight) element in the posterior entries.

Definition at line 218 of file posterior.cc.

References rnnlm::i, and rnnlm::j.

Referenced by kaldi::nnet2::ExampleToPdfPost(), NnetDiscriminativeUpdater::LatticeComputations(), kaldi::LatticeForwardBackwardMmi(), main(), and kaldi::RunPerSpeaker().

218  {
219  if (scale == 1.0) return;
220  for (size_t i = 0; i < post->size(); i++) {
221  if (scale == 0.0) {
222  (*post)[i].clear();
223  } else {
224  for (size_t j = 0; j < (*post)[i].size(); j++)
225  (*post)[i][j].second *= scale;
226  }
227  }
228 }

◆ SortPosteriorByPdfs()

void SortPosteriorByPdfs ( const TransitionModel tmodel,
Posterior post 
)

Sorts posterior entries so that transition-ids with same pdf-id are next to each other.

Definition at line 314 of file posterior.cc.

References rnnlm::i.

Referenced by main(), and CompareReverseSecond::operator()().

315  {
316  ComparePosteriorByPdfs compare(tmodel);
317  for (size_t i = 0; i < post->size(); i++) {
318  sort((*post)[i].begin(), (*post)[i].end(), compare);
319  }
320 }

◆ TotalPosterior()

BaseFloat TotalPosterior ( const Posterior post)

Returns the total of all the weights in "post".

Definition at line 230 of file posterior.cc.

References rnnlm::i.

Referenced by main(), and IvectorExtractTask::~IvectorExtractTask().

230  {
231  double sum = 0.0;
232  size_t T = post.size();
233  for (size_t t = 0; t < T; t++) {
234  size_t I = post[t].size();
235  for (size_t i = 0; i < I; i++) {
236  sum += post[t][i].second;
237  }
238  }
239  return sum;
240 }

◆ VectorToPosteriorEntry()

BaseFloat VectorToPosteriorEntry ( const VectorBase< BaseFloat > &  log_likes,
int32  num_gselect,
BaseFloat  min_post,
std::vector< std::pair< int32, BaseFloat > > *  post_entry 
)

Given a vector of log-likelihoods (typically of Gaussians in a GMM but could be of pdf-ids), a number gselect >= 1 and a minimum posterior 0 <= min_post < 1, it gets the posterior for each element of log-likes by applying Softmax(), then prunes the posteriors using "gselect" and "min_post" (keeping at least one), and outputs the result into "post_entry", sorted from greatest to least posterior.

It returns the log of the sum of the selected log-likes that contributed to the posterior.

Definition at line 440 of file posterior.cc.

References VectorBase< Real >::Dim(), kaldi::Exp(), kaldi::GetTotalPosterior(), KALDI_ASSERT, kaldi::Log(), and VectorBase< Real >::Max().

Referenced by main(), CompareReverseSecond::operator()(), kaldi::TestVectorToPosteriorEntry(), and OnlineIvectorFeature::UpdateStatsForFrames().

444  {
445  KALDI_ASSERT(num_gselect > 0 && min_post >= 0 && min_post < 1.0);
446  // we name num_gauss assuming each entry in log_likes represents a Gaussian;
447  // it doesn't matter if they don't.
448 
449  int32 num_gauss = log_likes.Dim();
450  KALDI_ASSERT(num_gauss > 0);
451  if (num_gselect > num_gauss)
452  num_gselect = num_gauss;
453  std::vector<std::pair<int32, BaseFloat> > temp_post;
454  BaseFloat max_like = log_likes.Max();
455  if (min_post != 0.0) {
456  BaseFloat like_cutoff = max_like + Log(min_post);
457  for (int32 g = 0; g < num_gauss; g++) {
458  BaseFloat like = log_likes(g);
459  if (like > like_cutoff) {
460  BaseFloat post = exp(like - max_like);
461  temp_post.push_back(std::pair<int32, BaseFloat>(g, post));
462  }
463  }
464  }
465  if (temp_post.empty()) {
466  // we reach here if min_post was 0.0 or if no posteriors reached the
467  // threshold min_post (we need at least one).
468  temp_post.resize(num_gauss);
469  for (int32 g = 0; g < num_gauss; g++)
470  temp_post[g] = std::pair<int32, BaseFloat>(g, Exp(log_likes(g) - max_like));
471  }
472 
473  CompareReverseSecond compare;
474  if (static_cast<int32>(temp_post.size()) > num_gselect * 2) {
475  // Sort in decreasing order on posterior. For efficiency we
476  // first do nth_element and then sort, as we only need the part we're
477  // going to output, to be sorted.
478  std::nth_element(temp_post.begin(),
479  temp_post.begin() + num_gselect, temp_post.end(),
480  compare);
481  std::sort(temp_post.begin(), temp_post.begin() + num_gselect,
482  compare);
483  } else {
484  std::sort(temp_post.begin(), temp_post.end(), compare);
485  }
486 
487  size_t num_to_insert = std::min<size_t>(temp_post.size(),
488  num_gselect);
489 
490  post_entry->clear();
491  post_entry->insert(post_entry->end(),
492  temp_post.begin(), temp_post.begin() + num_to_insert);
493 
494  BaseFloat tot_post = GetTotalPosterior(*post_entry),
495  cutoff = min_post * tot_post;
496 
497  while (post_entry->size() > 1 && post_entry->back().second < cutoff) {
498  tot_post -= post_entry->back().second;
499  post_entry->pop_back();
500  }
501  // Now renormalize to sum to one after pruning.
502  BaseFloat inv_tot = 1.0 / tot_post;
503  auto end = post_entry->end();
504  for (auto iter = post_entry->begin(); iter != end; ++iter)
505  iter->second *= inv_tot;
506 
507  return max_like + log(tot_post);
508 }
double Exp(double x)
Definition: kaldi-math.h:83
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29
double Log(double x)
Definition: kaldi-math.h:100
static BaseFloat GetTotalPosterior(const std::vector< std::pair< int32, BaseFloat > > &post_entry)
Definition: posterior.cc:429
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ WeightSilencePost()

void WeightSilencePost ( const TransitionModel trans_model,
const ConstIntegerSet< int32 > &  silence_set,
BaseFloat  silence_scale,
Posterior post 
)

Weight any silence phones in the posterior (i.e.

any phones in the set "silence_set" by scale "silence_scale". The interface was changed in Feb 2014 to do the modification "in-place" rather than having separate input and output.

Definition at line 375 of file posterior.cc.

References ConstIntegerSet< I >::count(), rnnlm::i, rnnlm::j, and TransitionModel::TransitionIdToPhone().

Referenced by SingleUtteranceGmmDecoder::GetGaussianPosteriors(), main(), and CompareReverseSecond::operator()().

378  {
379  for (size_t i = 0; i < post->size(); i++) {
380  std::vector<std::pair<int32, BaseFloat> > this_post;
381  this_post.reserve((*post)[i].size());
382  for (size_t j = 0; j < (*post)[i].size(); j++) {
383  int32 tid = (*post)[i][j].first,
384  phone = trans_model.TransitionIdToPhone(tid);
385  BaseFloat weight = (*post)[i][j].second;
386  if (silence_set.count(phone) != 0) { // is a silence.
387  if (silence_scale != 0.0)
388  this_post.push_back(std::make_pair(tid, weight*silence_scale));
389  } else {
390  this_post.push_back(std::make_pair(tid, weight));
391  }
392  }
393  (*post)[i].swap(this_post);
394  }
395 }
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29

◆ WeightSilencePostDistributed()

void WeightSilencePostDistributed ( const TransitionModel trans_model,
const ConstIntegerSet< int32 > &  silence_set,
BaseFloat  silence_scale,
Posterior post 
)

This is similar to WeightSilencePost, except that on each frame it works out the amount by which the overall posterior would be reduced, and scales down everything on that frame by the same amount.

It has the effect that frames that are mostly silence get down-weighted. The interface was changed in Feb 2014 to do the modification "in-place" rather than having separate input and output.

Definition at line 398 of file posterior.cc.

References ConstIntegerSet< I >::count(), rnnlm::i, rnnlm::j, KALDI_ASSERT, and TransitionModel::TransitionIdToPhone().

Referenced by main(), and CompareReverseSecond::operator()().

401  {
402  for (size_t i = 0; i < post->size(); i++) {
403  std::vector<std::pair<int32, BaseFloat> > this_post;
404  this_post.reserve((*post)[i].size());
405  BaseFloat sil_weight = 0.0, nonsil_weight = 0.0;
406  for (size_t j = 0; j < (*post)[i].size(); j++) {
407  int32 tid = (*post)[i][j].first,
408  phone = trans_model.TransitionIdToPhone(tid);
409  BaseFloat weight = (*post)[i][j].second;
410  if (silence_set.count(phone) != 0) sil_weight += weight;
411  else nonsil_weight += weight;
412  }
413  KALDI_ASSERT(sil_weight >= 0.0 && nonsil_weight >= 0.0); // This "distributed"
414  // weighting approach doesn't make sense if we have negative weights.
415  if (sil_weight + nonsil_weight == 0.0) continue;
416  BaseFloat frame_scale = (sil_weight * silence_scale + nonsil_weight) /
417  (sil_weight + nonsil_weight);
418  if (frame_scale != 0.0) {
419  for (size_t j = 0; j < (*post)[i].size(); j++) {
420  int32 tid = (*post)[i][j].first;
421  BaseFloat weight = (*post)[i][j].second;
422  this_post.push_back(std::make_pair(tid, weight * frame_scale));
423  }
424  }
425  (*post)[i].swap(this_post);
426  }
427 }
kaldi::int32 int32
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ WritePosterior()

void WritePosterior ( std::ostream &  os,
bool  binary,
const Posterior post 
)

stand-alone function for writing a Posterior.

Definition at line 32 of file posterior.cc.

References KALDI_ERR, and kaldi::WriteBasicType().

Referenced by kaldi::TestPosteriorIo(), and PosteriorHolder::Write().

32  {
33  if (binary) {
34  int32 sz = post.size();
35  WriteBasicType(os, binary, sz);
36  for (Posterior::const_iterator iter = post.begin(); iter != post.end(); ++iter) {
37  int32 sz2 = iter->size();
38  WriteBasicType(os, binary, sz2);
39  for (std::vector<std::pair<int32, BaseFloat> >::const_iterator
40  iter2 = iter->begin(); iter2 != iter->end(); ++iter2) {
41  WriteBasicType(os, binary, iter2->first);
42  WriteBasicType(os, binary, iter2->second);
43  }
44  }
45  } else { // In text-mode, choose a human-friendly, script-friendly format.
46  // format is [ 1235 0.6 12 0.4 ] [ 34 1.0 ] ...
47  // We could have used the same code as in the binary case above,
48  // but this would have resulted in less readable output.
49  for (Posterior::const_iterator iter = post.begin(); iter != post.end(); ++iter) {
50  os << "[ ";
51  for (std::vector<std::pair<int32, BaseFloat> >::const_iterator iter2=iter->begin();
52  iter2 != iter->end();
53  iter2++) {
54  os << iter2->first << ' ' << iter2->second << ' ';
55  }
56  os << "] ";
57  }
58  os << '\n'; // newline terminates the Posterior.
59  }
60  if (!os.good())
61  KALDI_ERR << "Output stream error writing Posterior.";
62 }
kaldi::int32 int32
#define KALDI_ERR
Definition: kaldi-error.h:147
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