]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/kaldi.git/commitdiff
sandbox/online: merging changes from trunk.
authorDan Povey <dpovey@gmail.com>
Fri, 8 Aug 2014 22:33:00 +0000 (22:33 +0000)
committerDan Povey <dpovey@gmail.com>
Fri, 8 Aug 2014 22:33:00 +0000 (22:33 +0000)
git-svn-id: https://svn.code.sf.net/p/kaldi/code/sandbox/online@4284 5e6a8d80-dfce-4ca6-a32a-6e07a63d50c8

15 files changed:
1  2 
src/decoder/lattice-faster-decoder.cc
src/decoder/lattice-simple-decoder.cc
src/decoder/lattice-tracking-decoder.cc
src/feat/feature-functions.cc
src/feat/pitch-functions-test.cc
src/gmmbin/gmm-decode-faster.cc
src/gmmbin/gmm-decode-nbest.cc
src/hmm/posterior.cc
src/ivector/ivector-extractor-test.cc
src/lat/determinize-lattice-pruned.cc
src/latbin/Makefile
src/matrix/optimization.cc
src/nnet2/nnet-component.cc
src/nnet2/nnet-component.h
src/transform/cmvn.cc

index 1062ef5fbcca7deca3d19e9f27709121adf5c002,ecb4d1642a635379558941706ae6e85f5673254a..294abd52c3ef22cf1e0e6dee9239d02dab9dfd4f
@@@ -348,26 -316,35 +348,26 @@@ void LatticeFasterDecoder::PruneForward
  // PruneForwardLinksFinal is a version of PruneForwardLinks that we call
  // on the final frame.  If there are final tokens active, it uses
  // the final-probs for pruning, otherwise it treats all tokens as final.
 -void LatticeFasterDecoder::PruneForwardLinksFinal(int32 frame) {
 -  KALDI_ASSERT(static_cast<size_t>(frame+1) == active_toks_.size());
 -  if (active_toks_[frame].toks == NULL ) // empty list; should not happen.
 +void LatticeFasterDecoder::PruneForwardLinksFinal() {
 +  KALDI_ASSERT(!active_toks_.empty());
 +  int32 frame_plus_one = active_toks_.size() - 1;
 +
 +  if (active_toks_[frame_plus_one].toks == NULL )  // empty list; should not happen.
-     KALDI_WARN << "No tokens alive at end of file\n";
+     KALDI_WARN << "No tokens alive at end of file";
  
 -  // First go through, working out the best token (do it in parallel
 -  // including final-probs and not including final-probs; we'll take
 -  // the one with final-probs if it's valid).
 -  const BaseFloat infinity = std::numeric_limits<BaseFloat>::infinity();
 -  BaseFloat best_cost_final = infinity,
 -      best_cost_nofinal = infinity;
 -  unordered_map<Token*, BaseFloat> tok_to_final_cost;
 -    
 -  Elem *cur_toks = toks_.Clear(); // swapping prev_toks_ / cur_toks_
 -  for (Elem *e = cur_toks; e != NULL;  e = e->tail) {
 -    StateId state = e->key;
 -    Token *tok = e->val;
 -    BaseFloat final_cost = fst_.Final(state).Value();
 -    best_cost_final = std::min(best_cost_final, tok->tot_cost + final_cost);
 -    tok_to_final_cost[tok] = final_cost;
 -    best_cost_nofinal = std::min(best_cost_nofinal, tok->tot_cost);
 -  }
 -  DeleteElems(cur_toks);
 -  final_active_ = (best_cost_final != infinity);
 -    
 -  // Now go through tokens on this frame, pruning forward links...  may have
 -  // to iterate a few times until there is no more change, because the list is
 -  // not in topological order.
 +  typedef unordered_map<Token*, BaseFloat>::const_iterator IterType;
 +  ComputeFinalCosts(&final_costs_, &final_relative_cost_, &final_best_cost_);
 +  decoding_finalized_ = true;
 +  // We call DeleteElems() as a nicety, not because it's really necessary;
 +  // otherwise there would be a time, after calling PruneTokensForFrame() on the
 +  // final frame, when toks_.GetList() or toks_.Clear() would contain pointers
 +  // to nonexistent tokens.
 +  DeleteElems(toks_.Clear());
  
 +  // Now go through tokens on this frame, pruning forward links...  may have to
 +  // iterate a few times until there is no more change, because the list is not
 +  // in topological order.  This is a modified version of the code in
 +  // PruneForwardLinks, but here we also take account of the final-probs.
    bool changed = true;
    BaseFloat delta = 1.0e-05;
    while (changed) {
@@@ -450,11 -420,11 +450,11 @@@ BaseFloat LatticeFasterDecoder::FinalRe
  // [we don't do this in PruneForwardLinks because it would give us
  // a problem with dangling pointers].
  // It's called by PruneActiveTokens if any forward links have been pruned
 -void LatticeFasterDecoder::PruneTokensForFrame(int32 frame) {
 -  KALDI_ASSERT(frame >= 0 && frame < active_toks_.size());
 -  Token *&toks = active_toks_[frame].toks;
 +void LatticeFasterDecoder::PruneTokensForFrame(int32 frame_plus_one) {
 +  KALDI_ASSERT(frame_plus_one >= 0 && frame_plus_one < active_toks_.size());
 +  Token *&toks = active_toks_[frame_plus_one].toks;
    if (toks == NULL)
-     KALDI_WARN << "No tokens alive [doing pruning]\n";
+     KALDI_WARN << "No tokens alive [doing pruning]";
    Token *tok, *next_tok, *prev_tok = NULL;
    for (tok = toks; tok != NULL; tok = next_tok) {
      next_tok = tok->next;
Simple merge
Simple merge
index 3f93a94ec36617b0c615bcb35f974632784fee19,9c484b2b5012ec5611e516e36ed50d72ac641cec..642eff602c930e0fa9f40fd151c6b95c67a4e9cd
@@@ -48,170 -42,25 +48,170 @@@ bool DirExist(const std::string &dirnam
  }
  
  static void UnitTestSimple() {
-   KALDI_LOG << "=== UnitTestSimple() ===\n";
+   KALDI_LOG << "=== UnitTestSimple() ===";
    Vector<BaseFloat> v(1000);
 -  Vector<BaseFloat> out;
 -  Matrix<BaseFloat> m;
 +  Matrix<BaseFloat> m1, m2;
    // init with noise
    for (int32 i = 0; i < v.Dim(); i++) {
      v(i) = (abs(i * 433024253) % 65535) - (65535 / 2);
    }
-   KALDI_LOG << "<<<=== Just make sure it runs... Nothing is compared\n";
+   KALDI_LOG << "<<<=== Just make sure it runs... Nothing is compared";
 -  // the parametrization object
 -  PitchExtractionOptions op;
 -  // trying to have same opts as baseline.
 -  // compute pitch.
 -  Compute(op, v, &m);
 +  // trying to compute and process pitch with same opts as baseline.
 +  PitchExtractionOptions op1;
 +  ProcessPitchOptions op2;
 +  ComputeAndProcessKaldiPitch(op1, op2, v, &m1);
-   KALDI_LOG << "Test passed :)\n";
+   KALDI_LOG << "Test passed :)";
  }
 +
 +
 +// Make sure that doing a calculation on the whole waveform gives
 +// the same results as doing on the waveform broken into pieces.
 +static void UnitTestPieces() {
 +  KALDI_LOG << "=== UnitTestPieces() ===\n";
 +  for (int32 n = 0; n < 10; n++) {
 +    // the parametrization object
 +    PitchExtractionOptions op1;
 +    ProcessPitchOptions op2;
 +    op2.delta_pitch_noise_stddev = 0.0;  // to avoid mismatch of delta_log_pitch
 +                                         // brought by rand noise.
 +    op1.nccf_ballast_online = true;  // this is necessary for the computation
 +    // to be identical regardless how many pieces we break the signal into.
 +
 +    int32 size = 10000 + rand() % 50000;
 +
 +    Vector<BaseFloat> v(size);
 +    // init with noise plus a sine-wave whose frequency is changing randomly.
 +
 +    double cur_freq = 200.0, normalized_time = 0.0;
 +
 +    for (int32 i = 0; i < size; i++) {
 +      v(i) = RandGauss() + cos(normalized_time * M_2PI);
 +      cur_freq += RandGauss();  // let the frequency wander a little.
 +      if (cur_freq < 100.0) cur_freq = 100.0;
 +      if (cur_freq > 300.0) cur_freq = 300.0;
 +      normalized_time += cur_freq / op1.samp_freq;
 +    }
 +
 +    Matrix<BaseFloat> m1, m1p;
 +
 +    // trying to have same opts as baseline.
 +    ComputeKaldiPitch(op1, v, &m1);
 +    ProcessPitch(op2, m1, &m1p);
 +
 +    Matrix<BaseFloat> m2, m2p;
 +
 +    { // compute it online with multiple pieces.
 +      OnlinePitchFeature pitch_extractor(op1);
 +      OnlineProcessPitch process_pitch(op2, &pitch_extractor);
 +      int32 start_samp = 0;
 +      while (start_samp < v.Dim()) {
 +        int32 num_samp = rand() % (v.Dim() + 1 - start_samp);
 +        SubVector<BaseFloat> v_part(v, start_samp, num_samp);
 +        pitch_extractor.AcceptWaveform(op1.samp_freq, v_part);
 +        start_samp += num_samp;
 +      }
 +      pitch_extractor.InputFinished();
 +      int32 num_frames = pitch_extractor.NumFramesReady();
 +      m2.Resize(num_frames, 2);
 +      m2p.Resize(num_frames, process_pitch.Dim());
 +      for (int32 frame = 0; frame < num_frames; frame++) {
 +        SubVector<BaseFloat> row(m2, frame);
 +        pitch_extractor.GetFrame(frame, &row);
 +        SubVector<BaseFloat> rowp(m2p, frame);
 +        process_pitch.GetFrame(frame, &rowp);
 +      }
 +    }
 +    AssertEqual(m1, m2);
 +    if (!ApproxEqual(m1p, m2p)) {
 +      KALDI_ERR << "Post-processed pitch differs: " << m1p << " vs. " << m2p;
 +    }
 +    KALDI_LOG << "Test passed :)\n";
 +  }
 +}
 +
 +extern bool pitch_use_naive_search; // was declared in pitch-functions.cc
 +
 +// Make sure that doing a calculation on the whole waveform gives
 +// the same results as doing on the waveform broken into pieces.
 +static void UnitTestSearch() {
 +  KALDI_LOG << "=== UnitTestSearch() ===\n";
 +  for (int32 n = 0; n < 3; n++) {
 +    // the parametrization object
 +    PitchExtractionOptions op;
 +    op.nccf_ballast_online = true;  // this is necessary for the computation
 +    // to be identical regardless how many pieces we break the signal into.
 +
 +    int32 size = 10000 + rand() % 10000;
 +
 +    Vector<BaseFloat> v(size);
 +    // init with noise plus a sine-wave whose frequency is changing randomly.
 +
 +    double cur_freq = 200.0, normalized_time = 0.0;
 +
 +    for (int32 i = 0; i < size; i++) {
 +      v(i) = RandGauss() + cos(normalized_time * M_2PI);
 +      cur_freq += RandGauss();  // let the frequency wander a little.
 +      if (cur_freq < 100.0) cur_freq = 100.0;
 +      if (cur_freq > 300.0) cur_freq = 300.0;
 +      normalized_time += cur_freq / op.samp_freq;
 +    }
 +
 +    Matrix<BaseFloat> m1;
 +    ComputeKaldiPitch(op, v, &m1);
 +
 +    pitch_use_naive_search = true;
 +
 +    Matrix<BaseFloat> m2;
 +    ComputeKaldiPitch(op, v, &m2);
 +
 +    pitch_use_naive_search = false;
 +
 +    AssertEqual(m1, m2, 1.0e-08);  // should be identical.
 +  }
 +  KALDI_LOG << "Test passed :)\n";
 +}
 +
 +static void UnitTestComputeGPE() {
 +  KALDI_LOG << "=== UnitTestComputeGPE ===\n";
 +  int32 wrong_pitch = 0, tot_voiced = 0, tot_unvoiced = 0, num_frames = 0;
 +  BaseFloat tol = 0.1, avg_d_kpitch = 0, real_pitch = 0;
 +  for (int32 i = 1; i < 11; i++) {
 +    std::string wavefile;
 +    std::string num;
 +    if (i < 6) {
 +      num = "f" + ConvertIntToString(i) + "nw0000";
 +    } else {
 +      num = "m" + ConvertIntToString(i-5) + "nw0000";
 +    }
 +    Matrix<BaseFloat> gross_pitch;
 +    std::string pitchfile = "keele/keele-true-lags/"+num+".txt";
 +    std::ifstream pitch(pitchfile.c_str());
 +    gross_pitch.Read(pitch, false);
 +    Matrix<BaseFloat> kaldi_pitch;
 +    std::string kfile = "keele/tmp/+"+num+"-kaldi.txt";
 +    std::ifstream kpitch(kfile.c_str());
 +    kaldi_pitch.Read(kpitch, false);
 +    num_frames = std::min(kaldi_pitch.NumRows(),gross_pitch.NumRows());
 +    for (int32 j = 1; j < num_frames; j++) {
 +      if (gross_pitch(j,0) > 0.0) {
 +        tot_voiced++;
 +        real_pitch = 20000.0/gross_pitch(j,0);
 +        if (fabs((real_pitch - kaldi_pitch(j,1))/real_pitch) > tol) 
 +          wrong_pitch++;
 +      } else if (gross_pitch(j,0) == 0.0 && gross_pitch(j-1,0) == 0.0) {
 +        tot_unvoiced++;
 +        avg_d_kpitch += fabs(kaldi_pitch(j,1) - kaldi_pitch(j-1,1));
 +      }
 +    }
 +  }
 +  BaseFloat GPE = 1.0 * wrong_pitch / tot_voiced;
 +  KALDI_LOG << " Gross Pitch Error with Rel.Error " << tol << " is " << GPE;
 +  KALDI_LOG << "Average Kaldi delta_pitch for unvoiced regions " << avg_d_kpitch/tot_unvoiced;
 +}
 +
  // Compare pitch using Kaldi pitch tracker on KEELE corpora
  static void UnitTestKeele() {
-   KALDI_LOG << "=== UnitTestKeele() ===\n";
+   KALDI_LOG << "=== UnitTestKeele() ===";
    for (int32 i = 1; i < 11; i++) {
      std::string wavefile;
      std::string num;
@@@ -308,9 -156,86 +308,9 @@@ static void UnitTestKeeleNccfBallast() 
      }
    }
  }
 -static void UnitTestWeightedMwn() {
 -  KALDI_LOG << "=== UnitTestWeightedMwn1() ===";
 -  // compare the results of WeightedMwn1 and Sliding CMN with uniform weights.
 -  for (int32 i = 0; i < 1000; i++) {
 -    int32 num_frames = 1 + (rand()%10 * 10);
 -    int32 normalization_win_size = 5 + rand() % 50;
 -    Matrix<BaseFloat> feat(num_frames, 2),
 -                      output_feat(num_frames, 2);
 -    feat.SetRandn();
 -    for (int32 j = 0; j < num_frames; j++)
 -      feat(j, 0) = 1;
 -
 -    Vector<BaseFloat> pov(num_frames),
 -                      log_pitch(num_frames),
 -                      mean_subtracted_log_pitch(num_frames);
 -    pov.CopyColFromMat(feat, 0);
 -    log_pitch.CopyColFromMat(feat, 1);
 -    WeightedMwn(normalization_win_size, pov, log_pitch ,
 -                &mean_subtracted_log_pitch);
 -    output_feat.CopyColFromVec(mean_subtracted_log_pitch, 1);
 -
 -    // SlidingWindow
 -    SlidingWindowCmnOptions opts;
 -    opts.cmn_window = normalization_win_size;
 -    opts.center = true;
 -    opts.min_window = 1 + rand() % 100;
 -    if (opts.min_window > opts.cmn_window)
 -      opts.min_window = opts.cmn_window;
 -    Matrix<BaseFloat> output_feat2(num_frames, 2);
 -    SlidingWindowCmn(opts, feat, &output_feat2);
 -    for (int32 j = 0; j < num_frames; j++)
 -      output_feat(j, 0) = 0.0;
 -    if (!output_feat.ApproxEqual(output_feat2, 0.001)) {
 -      Matrix<BaseFloat> output_all(num_frames, 2);
 -      Vector<BaseFloat> pitch(num_frames),
 -                        pitch2(num_frames);
 -      pitch.CopyColFromMat(output_feat, 1);
 -      pitch2.CopyColFromMat(output_feat2, 1);
 -      output_all.CopyColFromVec(pitch, 0);
 -      output_all.CopyColFromVec(pitch2, 1);
 -      KALDI_ERR << "Feafures differ:\n" << output_all;
 -    }
 -  }
 -  // Weighted Moving Window Normalization with non-uniform weights
 -  /*
 -  int32 num_frames = 1 + (rand()%10 * 20);
 -  int32 normalization_win_size = 5 + rand() % 50;
 -  Matrix<BaseFloat> feat(num_frames, 2),
 -    output_feat(num_frames, 2);
 -  for (int32 j = 0; j < num_frames; j++) {
 -    int32 r = rand() % 2;
 -    feat(j, 0) = RandUniform() / (1 + 1000.0 * r);
 -    feat(j, 1) = feat(j, 1) * feat(j, 0);
 -  }
 -  ProcessPovFeatures(&feat, 2, true);
 -  WeightedMwn(normalization_win_size, feat, &output_feat);
 -  */
 -}
 -static void UnitTestTakeLogOfPitch() {
 -  for (int32 i = 0; i < 100; i++) {
 -    int num_frame = 50 + (rand() % 200 * 200);
 -    Matrix<BaseFloat> input(num_frame, 2);
 -    input.SetRandn();
 -    input.Scale(100);
 -    Matrix<BaseFloat> output(input);
 -    for (int j = 0; j < num_frame; j++) {
 -      if (input(j, 1) < 1) {
 -        input(j, 1) = 10;
 -        output(j, 1) = 10;
 -      }
 -      output(j, 1) = log(input(j, 2));
 -    }
 -    TakeLogOfPitch(&input);
 -    if (input.ApproxEqual(output, 0.0001)) {
 -      KALDI_ERR << " Log of Matrix differs " << input << " vs. " << output;
 -    }
 -  }
 -}
 +
  static void UnitTestPitchExtractionSpeed() {
-   KALDI_LOG << "=== UnitTestPitchExtractionSpeed() ===\n";
+   KALDI_LOG << "=== UnitTestPitchExtractionSpeed() ===";
    // use pitch code with default configuration..
    PitchExtractionOptions op;
    op.nccf_ballast = 0.1;
@@@ -468,20 -459,11 +468,20 @@@ int main() 
      if (DirExist("keele/16kHz")) {
        UnitTestFeatWithKeele();
      } else {
 -      KALDI_LOG << "Not running tests that require the Keele database, "
 -        << "please ask g.meyer@somewhere.edu for the database if you need it.\n"
 -        << " you need to put keele wave file in keele/16kHz directory";
 +      KALDI_LOG
 +          << "Not running tests that require the Keele database, "
 +          << "please ask g.meyer@liverpool.ac.uk for the database if you need it.\n"
 +          << "Once you have the keele/ subdirectory, containing *.{pel,pet,pev,raw,wav}, do this:\n"
 +          << "cd keele; mkdir -p 16kHz; mkdir -p tmp; for x in *.wav; do \n"
 +          << "sox $x -r 16000 16kHz/$x; done  \n"
 +          << "mkdir -p keele-true-lags; for f in *.pev; do \n"
 +          << "out_f=keele-true-lags/$(echo $f | sed s:pev:txt:); ( echo ' ['; len=`cat $f | wc -l`; \n"
 +          << "head -n $(($len-1)) $f | tail -n $(($len-14)) ; echo -n ']') >$out_f; done \n"
 +          << "\n"
 +          << "Note: the GPE reported in paper is computed using pseudo-ground-truth pitch obtained\n"
 +          << "by voting among the pitch trackers mentioned in the paper.\n";
      }
-     KALDI_LOG << "Tests succeeded.\n";
+     KALDI_LOG << "Tests succeeded.";
      return 0;
    } catch(const std::exception &e) {
      KALDI_ERR << e.what();
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 7c7051b4011984d2467144a73bfb10ed63cc3418,300248cd367445c64127a682e3a455caaf5d4139..daa8e91fde24c66099843c5d6cae832e3ec15ab8
@@@ -18,9 -18,9 +18,8 @@@ BINFILES = lattice-best-path lattice-pr
             lattice-to-smbr-post lattice-determinize-pruned-parallel \
             lattice-add-penalty lattice-align-words-lexicon lattice-push \
             lattice-minimize lattice-limit-depth lattice-depth-per-frame \
 -           lattice-determinize-phone-pruned lattice-determinize-phone-pruned-parallel \
 -           lattice-expand-ngram
 -
 +           lattice-confidence lattice-determinize-phone-pruned \
-            lattice-determinize-phone-pruned-parallel
++           lattice-determinize-phone-pruned-parallel lattice-expand-ngram
  
  OBJFILES =
  
Simple merge
Simple merge
Simple merge
Simple merge