posterior.cc
Go to the documentation of this file.
1 // hmm/posterior.cc
2 
3 // Copyright 2009-2011 Microsoft Corporation
4 // 2013-2014 Johns Hopkins University (author: Daniel Povey)
5 // 2014 Guoguo Chen
6 // 2014 Guoguo Chen
7 
8 // See ../../COPYING for clarification regarding multiple authors
9 //
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 //
14 // http://www.apache.org/licenses/LICENSE-2.0
15 //
16 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
18 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
19 // MERCHANTABLITY OR NON-INFRINGEMENT.
20 // See the Apache 2 License for the specific language governing permissions and
21 // limitations under the License.
22 
23 #include <vector>
24 #include "hmm/posterior.h"
25 #include "util/kaldi-table.h"
26 #include "util/stl-utils.h"
27 #include "matrix/kaldi-matrix.h"
28 
29 
30 namespace kaldi {
31 
32 void WritePosterior(std::ostream &os, bool binary, const Posterior &post) {
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 }
63 
64 void ReadPosterior(std::istream &is, bool binary, Posterior *post) {
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 }
124 
125 
126 // static
127 bool PosteriorHolder::Write(std::ostream &os, bool binary, const T &t) {
128  InitKaldiOutputStream(os, binary); // Puts binary header if binary mode.
129  try {
130  WritePosterior(os, binary, t);
131  return true;
132  } catch(const std::exception &e) {
133  KALDI_WARN << "Exception caught writing table of posteriors. " << e.what();
134  return false; // Write failure.
135  }
136 }
137 
138 bool PosteriorHolder::Read(std::istream &is) {
139  t_.clear();
140 
141  bool is_binary;
142  if (!InitKaldiInputStream(is, &is_binary)) {
143  KALDI_WARN << "Reading Table object, failed reading binary header";
144  return false;
145  }
146  try {
147  ReadPosterior(is, is_binary, &t_);
148  return true;
149  } catch (std::exception &e) {
150  KALDI_WARN << "Exception caught reading table of posteriors. " << e.what();
151  t_.clear();
152  return false;
153  }
154 }
155 
156 // static
157 bool GaussPostHolder::Write(std::ostream &os, bool binary, const T &t) {
158  InitKaldiOutputStream(os, binary); // Puts binary header if binary mode.
159  try {
160  // We don't bother making this a one-line format.
161  int32 sz = t.size();
162  WriteBasicType(os, binary, sz);
163  for (GaussPost::const_iterator iter = t.begin(); iter != t.end(); ++iter) {
164  int32 sz2 = iter->size();
165  WriteBasicType(os, binary, sz2);
166  for (std::vector<std::pair<int32, Vector<BaseFloat> > >::const_iterator iter2=iter->begin();
167  iter2 != iter->end();
168  iter2++) {
169  WriteBasicType(os, binary, iter2->first);
170  iter2->second.Write(os, binary);
171  }
172  }
173  if(!binary) os << '\n';
174  return os.good();
175  } catch (const std::exception &e) {
176  KALDI_WARN << "Exception caught writing table of posteriors. " << e.what();
177  return false; // Write failure.
178  }
179 }
180 
181 bool GaussPostHolder::Read(std::istream &is) {
182  t_.clear();
183 
184  bool is_binary;
185  if (!InitKaldiInputStream(is, &is_binary)) {
186  KALDI_WARN << "Reading Table object, failed reading binary header";
187  return false;
188  }
189  try {
190  int32 sz;
191  ReadBasicType(is, is_binary, &sz);
192  if (sz < 0)
193  KALDI_ERR << "Reading posteriors: got negative size";
194  t_.resize(sz);
195  for (GaussPost::iterator iter = t_.begin(); iter != t_.end(); ++iter) {
196  int32 sz2;
197  ReadBasicType(is, is_binary, &sz2);
198  if (sz2 < 0)
199  KALDI_ERR << "Reading posteriors: got negative size";
200  iter->resize(sz2);
201  for (std::vector<std::pair<int32, Vector<BaseFloat> > >::iterator
202  iter2=iter->begin();
203  iter2 != iter->end();
204  iter2++) {
205  ReadBasicType(is, is_binary, &(iter2->first));
206  iter2->second.Read(is, is_binary);
207  }
208  }
209  return true;
210  } catch (std::exception &e) {
211  KALDI_WARN << "Exception caught reading table of posteriors. " << e.what();
212  t_.clear();
213  return false;
214  }
215 }
216 
217 
218 void ScalePosterior(BaseFloat scale, Posterior *post) {
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 }
229 
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 }
241 
243  const std::vector<std::pair<int32,BaseFloat> > &post_elem1,
244  const std::vector<std::pair<int32,BaseFloat> > &post_elem2) {
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 }
251 
252 // For each frame, merges the posteriors in post1 into post2,
253 // frame-by-frame, combining any duplicated entries.
254 // note: Posterior is vector<vector<pair<int32, BaseFloat> > >
255 // Returns the number of frames for which the two posteriors
256 // were disjoint (no common transition-ids or whatever index
257 // we are using).
259  const Posterior &post2,
260  bool merge,
261  bool drop_frames,
262  Posterior *post) {
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 }
289 
290 void AlignmentToPosterior(const std::vector<int32> &ali,
291  Posterior *post) {
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 }
300 
303  ComparePosteriorByPdfs(const TransitionModel &tmodel): tmodel_(&tmodel) {}
304  bool operator() (const std::pair<int32, BaseFloat> &a,
305  const std::pair<int32, BaseFloat> &b) {
306  if (tmodel_->TransitionIdToPdf(a.first)
307  < tmodel_->TransitionIdToPdf(b.first))
308  return true;
309  else
310  return false;
311  }
312 };
313 
315  Posterior *post) {
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 }
321 
323  const Posterior &post_in,
324  Posterior *post_out) {
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 }
347 
349  const Posterior &post_in,
350  Posterior *post_out) {
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 }
373 
374 
375 void WeightSilencePost(const TransitionModel &trans_model,
376  const ConstIntegerSet<int32> &silence_set,
377  BaseFloat silence_scale,
378  Posterior *post) {
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 }
396 
397 
399  const ConstIntegerSet<int32> &silence_set,
400  BaseFloat silence_scale,
401  Posterior *post) {
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 }
428 
430  const std::vector<std::pair<int32, BaseFloat> > &post_entry) {
431  BaseFloat tot = 0.0;
432  std::vector<std::pair<int32, BaseFloat> >::const_iterator
433  iter = post_entry.begin(), end = post_entry.end();
434  for (; iter != end; ++iter) {
435  tot += iter->second;
436  }
437  return tot;
438 }
439 
441  const VectorBase<BaseFloat> &log_likes,
442  int32 num_gselect,
443  BaseFloat min_post,
444  std::vector<std::pair<int32, BaseFloat> > *post_entry) {
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 }
509 
510 
511 template <typename Real>
512 void PosteriorToMatrix(const Posterior &post,
513  const int32 post_dim, Matrix<Real> *mat) {
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 }
529 // instantiate the template function,
530 template void PosteriorToMatrix<float>(const Posterior &post,
531  const int32 post_dim,
532  Matrix<float> *mat);
533 template void PosteriorToMatrix<double>(const Posterior &post,
534  const int32 post_dim,
535  Matrix<double> *mat);
536 
537 
538 template <typename Real>
540  const TransitionModel &model,
541  Matrix<Real> *mat) {
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 }
558 // instantiate the template function,
559 template void PosteriorToPdfMatrix<float>(const Posterior &post,
560  const TransitionModel &model,
561  Matrix<float> *mat);
562 template void PosteriorToPdfMatrix<double>(const Posterior &post,
563  const TransitionModel &model,
564  Matrix<double> *mat);
565 
566 } // End namespace kaldi
void PosteriorToMatrix(const Posterior &post, const int32 post_dim, Matrix< Real > *mat)
This converts a Posterior to a Matrix.
Definition: posterior.cc:512
const TransitionModel * tmodel_
Definition: posterior.cc:302
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
double Exp(double x)
Definition: kaldi-math.h:83
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
bool InitKaldiInputStream(std::istream &is, bool *binary)
Initialize an opened stream for reading by detecting the binary header and.
Definition: io-funcs-inl.h:306
bool Read(std::istream &is)
Definition: posterior.cc:181
void PosteriorToPdfMatrix(const Posterior &post, const TransitionModel &model, Matrix< Real > *mat)
This converts a Posterior to a Matrix.
Definition: posterior.cc:539
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
static bool Write(std::ostream &os, bool binary, const T &t)
Definition: posterior.cc:127
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)...
Definition: posterior.cc:440
kaldi::int32 int32
A class for storing matrices.
Definition: kaldi-matrix.h:823
int32 TransitionIdToPdf(int32 trans_id) const
BaseFloat TotalPosterior(const Posterior &post)
Returns the total of all the weights in "post".
Definition: posterior.cc:230
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.
Definition: posterior.cc:375
bool Read(std::istream &is)
Definition: posterior.cc:138
void SortPosteriorByPdfs(const TransitionModel &tmodel, Posterior *post)
Sorts posterior entries so that transition-ids with same pdf-id are next to each other.
Definition: posterior.cc:314
float BaseFloat
Definition: kaldi-types.h:29
std::vector< std::vector< std::pair< int32, BaseFloat > > > Posterior
Posterior is a typedef for storing acoustic-state (actually, transition-id) posteriors over an uttera...
Definition: posterior.h:42
double Log(double x)
Definition: kaldi-math.h:100
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 ...
Definition: posterior.cc:398
ComparePosteriorByPdfs(const TransitionModel &tmodel)
Definition: posterior.cc:303
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: posterior.cc:290
#define KALDI_ERR
Definition: kaldi-error.h:147
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
Real Max() const
Returns the maximum value of any element, or -infinity for the empty vector.
#define KALDI_WARN
Definition: kaldi-error.h:150
MatrixIndexT Dim() const
Returns the dimension of the vector.
Definition: kaldi-vector.h:64
template void PosteriorToMatrix< float >(const Posterior &post, const int32 post_dim, Matrix< float > *mat)
static bool Write(std::ostream &os, bool binary, const T &t)
Definition: posterior.cc:157
static BaseFloat GetTotalPosterior(const std::vector< std::pair< int32, BaseFloat > > &post_entry)
Definition: posterior.cc:429
void ScalePosterior(BaseFloat scale, Posterior *post)
Scales the BaseFloat (weight) element in the posterior entries.
Definition: posterior.cc:218
A class representing a vector.
Definition: kaldi-vector.h:406
template void PosteriorToPdfMatrix< double >(const Posterior &post, const TransitionModel &model, Matrix< double > *mat)
#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
template void PosteriorToPdfMatrix< float >(const Posterior &post, const TransitionModel &model, Matrix< float > *mat)
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 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 InitKaldiOutputStream(std::ostream &os, bool binary)
InitKaldiOutputStream initializes an opened stream for writing by writing an optional binary header a...
Definition: io-funcs-inl.h:291
void WritePosterior(std::ostream &os, bool binary, const Posterior &post)
stand-alone function for writing a Posterior.
Definition: posterior.cc:32
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: posterior.cc:348
Provides a vector abstraction class.
Definition: kaldi-vector.h:41
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: posterior.cc:322
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.
Definition: posterior.cc:258
int32 TransitionIdToPhone(int32 trans_id) const
void ReadPosterior(std::istream &is, bool binary, Posterior *post)
stand-alone function for reading a Posterior.
Definition: posterior.cc:64
template void PosteriorToMatrix< double >(const Posterior &post, const int32 post_dim, Matrix< double > *mat)