All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
< PosteriorHolder > 
PosteriorWriter
 
typedef SequentialTableReader
< PosteriorHolder > 
SequentialPosteriorReader
 
typedef
RandomAccessTableReader
< PosteriorHolder > 
RandomAccessPosteriorReader
 
typedef TableWriter
< GaussPostHolder > 
GaussPostWriter
 
typedef SequentialTableReader
< GaussPostHolder > 
SequentialGaussPostReader
 
typedef
RandomAccessTableReader
< GaussPostHolder > 
RandomAccessGaussPostReader
 

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

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 52 of file posterior.h.

typedef TableWriter<GaussPostHolder> GaussPostWriter

Definition at line 145 of file posterior.h.

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 43 of file posterior.h.

typedef TableWriter<PosteriorHolder> PosteriorWriter

Definition at line 139 of file posterior.h.

typedef RandomAccessTableReader<GaussPostHolder> RandomAccessGaussPostReader

Definition at line 147 of file posterior.h.

typedef RandomAccessTableReader<PosteriorHolder> RandomAccessPosteriorReader

Definition at line 141 of file posterior.h.

typedef SequentialTableReader<GaussPostHolder> SequentialGaussPostReader

Definition at line 146 of file posterior.h.

typedef SequentialTableReader<PosteriorHolder> SequentialPosteriorReader

Definition at line 140 of file posterior.h.

Function Documentation

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(), and main().

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 }
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(), kaldi::LatticeForwardBackwardMmi(), and main().

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 }
float BaseFloat
Definition: kaldi-types.h:29
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().

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 }
float BaseFloat
Definition: kaldi-types.h:29
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 }
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:169
void MergePairVectorSumming(std::vector< std::pair< I, F > > *vec)
For a vector of pair where I is an integer and F a floating-point or integer type...
Definition: stl-utils.h:302
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 }
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 474 of file posterior.cc.

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

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

475  {
476  // Make a host-matrix,
477  int32 num_rows = post.size();
478  mat->Resize(num_rows, post_dim, kSetZero); // zero-filled
479  // Fill from Posterior,
480  for (int32 t = 0; t < post.size(); t++) {
481  for (int32 i = 0; i < post[t].size(); i++) {
482  int32 col = post[t][i].first;
483  if (col >= post_dim) {
484  KALDI_ERR << "Out-of-bound Posterior element with index " << col
485  << ", higher than number of columns " << post_dim;
486  }
487  (*mat)(t, col) = post[t][i].second;
488  }
489  }
490 }
#define KALDI_ERR
Definition: kaldi-error.h:127
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 501 of file posterior.cc.

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

503  {
504  // Allocate the matrix,
505  int32 num_rows = post.size(),
506  num_cols = model.NumPdfs();
507  mat->Resize(num_rows, num_cols, kSetZero); // zero-filled,
508  // Fill from Posterior,
509  for (int32 t = 0; t < post.size(); t++) {
510  for (int32 i = 0; i < post[t].size(); i++) {
511  int32 col = model.TransitionIdToPdf(post[t][i].first);
512  if (col >= num_cols) {
513  KALDI_ERR << "Out-of-bound Posterior element with index " << col
514  << ", higher than number of columns " << num_cols;
515  }
516  (*mat)(t, col) += post[t][i].second; // sum,
517  }
518  }
519 }
#define KALDI_ERR
Definition: kaldi-error.h:127
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:114
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
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_ERR
Definition: kaldi-error.h:127
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 }
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().

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 }
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 }
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.

Returns the total log-likelihood (the output of calling ApplySoftMax() on a copy of log_likes).

Definition at line 429 of file posterior.cc.

References VectorBase< Real >::ApplySoftMax(), VectorBase< Real >::Dim(), rnnlm::i, and KALDI_ASSERT.

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

433  {
434  KALDI_ASSERT(num_gselect > 0 && min_post >= 0 && min_post < 1.0);
435  // we name num_gauss assuming each entry in log_likes represents a Gaussian;
436  // it doesn't matter if they don't.
437  int32 num_gauss = log_likes.Dim();
438  KALDI_ASSERT(num_gauss > 0);
439  if (num_gselect > num_gauss)
440  num_gselect = num_gauss;
441  Vector<BaseFloat> log_likes_normalized(log_likes);
442  BaseFloat ans = log_likes_normalized.ApplySoftMax();
443  std::vector<std::pair<int32, BaseFloat> > temp_post(num_gauss);
444  for (int32 g = 0; g < num_gauss; g++)
445  temp_post[g] = std::pair<int32, BaseFloat>(g, log_likes_normalized(g));
446  CompareReverseSecond compare;
447  // Sort in decreasing order on posterior. For efficiency we
448  // first do nth_element and then sort, as we only need the part we're
449  // going to output, to be sorted.
450  std::nth_element(temp_post.begin(),
451  temp_post.begin() + num_gselect, temp_post.end(),
452  compare);
453  std::sort(temp_post.begin(), temp_post.begin() + num_gselect,
454  compare);
455 
456  post_entry->clear();
457  post_entry->insert(post_entry->end(),
458  temp_post.begin(), temp_post.begin() + num_gselect);
459  while (post_entry->size() > 1 && post_entry->back().second < min_post)
460  post_entry->pop_back();
461  // Now renormalize to sum to one after pruning.
462  BaseFloat tot = 0.0;
463  size_t size = post_entry->size();
464  for (size_t i = 0; i < size; i++)
465  tot += (*post_entry)[i].second;
466  BaseFloat inv_tot = 1.0 / tot;
467  for (size_t i = 0; i < size; i++)
468  (*post_entry)[i].second *= inv_tot;
469  return ans;
470 }
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:59
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 main().

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 }
float BaseFloat
Definition: kaldi-types.h:29
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().

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 }
float BaseFloat
Definition: kaldi-types.h:29
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
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 }
#define KALDI_ERR
Definition: kaldi-error.h:127
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