⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 approx_cont_mgau.c

📁 CMU大名鼎鼎的SPHINX-3大词汇量连续语音识别系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    }  }  /*  E_INFO("The dynamic beam %d\n",fastgmm->gmms->dyn_ci_pbeam);*/  return fastgmm->gmms->dyn_ci_pbeam;}/** In this function,  1, It only compute the ci-phones score.  2, The score is not normalize, this routine is supposed to be used before approx_cont_mgau_frame_eval,     The best score is determined by the later function. */void approx_cont_mgau_ci_eval (kbcore_t *kbc,			       fast_gmm_t *fg, 			       mdef_t *mdef,			       float32 *feat,int32 *ci_senscr){  int32 s;  s3senid_t *cd2cisen;  int32 best_cid;  gs_t* gs;  subvq_t* svq;  mgau_model_t *g;  int32 svq_beam;  int32 n_cig;  int32 n_cis;  n_cis=0;  n_cig=0;  cd2cisen=mdef_cd2cisen(mdef);  svq_beam=fg->gaus->subvqbeam;    gs=kbcore_gs(kbc);  svq=kbcore_svq(kbc);  g=kbcore_mgau(kbc);  /*#ifdef APPROX_CONT_MGAU*/  /*Always turn on, so users can be the one who decide how fast/slow the recognizer can be */  best_cid=-1;#if 1  if(gs)  best_cid=gc_compute_closest_cw(gs,feat);  if(svq) subvq_gautbl_eval_logs3 (svq, feat);  for (s = 0; mdef_is_cisenone(mdef,s); s++) {    n_cig+=approx_mgau_eval (gs,svq,g,fg,s,ci_senscr,feat,best_cid,svq_beam);    n_cis++;  }#else  for (s = 0; mdef_is_cisenone(mdef,s); s++) {    ci_senscr[s] = mgau_eval (g, s, NULL, feat);    n_cig+=mgau_n_comp(g,s);    n_cis++;  }#endif  g->frm_ci_sen_eval=n_cis;  g->frm_ci_gau_eval=n_cig;}/** approx_con_mgau_frame_eval encapsulates all approximations in the   Gaussian computation.  This assumes programmers NOT to initialize the   senone scores at every frame (FIX me!) before using this function.   This layer of code controls the optimization performance in Frame   Leval and GMM Level.   Frame Level:   ^^^^^^^^^^^^   We select to compute the scores only if it is not similar to the   most recently computed frames.  There are multiple ways to   configures this.   Naive down-sampling : Skip the computation one every other n-frames   Conditional down-sampling : Skip the computation only if the   current frame doesn't belong to the same neighborhood of the same   frame.  This neighborhood corresponds to the codeword which the   feature vector found to be the closest.      No matter which down-sampling was used, the following problem will   appear in the computation.  Active senones of frame which supposed   to be skipped in computation were not computed in the most recently   computed frame.  In those case, we chose to compute those senones   GMM Level:   ^^^^^^^^^^   In the implementation of CI-based GMM selection makes use of the   fact that in s3.3 , CI models are always placed before all CD   models. Hence the following logic is implemented:   if(it is CI senone)      compute score   else if (it is CD senone)      if the ci-phone beam was not set           compute score      else          if the CD senone's parent has a score within the beam	     compute_score	  else CD senone's parent has a score out of the beam	     back-off using the parent senone score.    About renormalization   ^^^^^^^^^^^^^^^^^^^^^   Sphinx 3.4 generally renormalize the score using the best   score. Notice that this introduce extra complication to the   implementation.  I have separated the logic of computing or not   computing the scores.  This will clarify the code a bit.      Accounting of senone and gaussian computation   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   This function assumes approx_cont_mgau_ci_eval was run before it,   hence at the end the score was added on top of the it.      Design   ^^^^^^    The whole idea of this function is based on my paper on "4-level   categorization of GMM computation " which basically describe how   different techniques of fast GMM computation should interact with   each others.  The current implementation was there to make the   code to be as short as possible. I hope that no one will try to make   the code to be longer than 500 lines. */int32 approx_cont_mgau_frame_eval (kbcore_t *kbc,				   fast_gmm_t *fastgmm,				   float32 *feat,					   int32 frame,				   int32 *sen_active,  				   int32 *rec_sen_active,				   int32 *senscr,				   int32 *cache_ci_senscr,				   ptmr_t *tm_ovrhd){  int32 s;  int32 t;  int32 best, ns, ng, n_cis,n_cig;  int32 best_cid;  int32 is_skip;  int32 is_compute;  int32 pbest;  int32 is_ciphone;  int32 svq_beam;  int32* ci_occ;  mdef_t* mdef;  s3senid_t *cd2cisen;  gs_t* gs;  subvq_t* svq;  mgau_model_t *g;  int32 total;  int32 dyn_ci_pbeam;  best = MAX_NEG_INT32;  pbest = MAX_NEG_INT32;  ns = 0;  n_cis=0;    n_cig=0;  ng = 0;  total=0;  best_cid=-1;  gs=kbcore_gs(kbc);  svq=kbcore_svq(kbc);  g=kbcore_mgau(kbc);  svq_beam=fastgmm->gaus->subvqbeam;    mdef=kbc->mdef;  ci_occ=fastgmm->gmms->ci_occu;  cd2cisen=mdef_cd2cisen(mdef);  ptmr_start(tm_ovrhd);  if(gs)  best_cid=gc_compute_closest_cw(gs,feat);  if(svq) subvq_gautbl_eval_logs3 (svq, feat);  if(fastgmm->gmms->max_cd < mdef->n_sen-mdef->n_ci_sen)    dyn_ci_pbeam=approx_compute_dyn_ci_pbeam(mdef,fastgmm,g,					     ci_occ,sen_active,cache_ci_senscr,cd2cisen);  else    dyn_ci_pbeam=fastgmm->gmms->ci_pbeam;  ptmr_stop(tm_ovrhd);  is_skip=approx_isskip(frame,fastgmm,best_cid);  fastgmm->gaus->rec_bstcid=best_cid;   /* Use the original */  for (s = 0; s < g->n_mgau; s++) {    is_compute = !sen_active || sen_active[s];    is_ciphone  = mdef_is_cisenone(mdef,s);#if _DEBUG_GSCORE_    E_INFO("Sen active %d, rec_sen_active %d, sen id %d \n",sen_active[s],rec_sen_active[s],s);#endif    if(!is_skip){ /* Loop handling main computation*/      /* Compute the score of the CI phone even if it is not active. */      if(is_ciphone){	/*Just copied from the cache, we just do accouting here */	/*E_INFO("At senone %d, CI phoneme score %d \n",s,cache_ci_senscr[s]);*/	senscr[s]=cache_ci_senscr[s];	if (pbest < senscr[s]) pbest = senscr[s];	if (best < senscr[s]) best = senscr[s];	sen_active[s]=1;	/*n_cig+=mgau_n_comp(g,s); *//*Assume all CIs are computed fully*/	/*n_cis++;*/      }else{	if(is_compute) {	  if((senscr[cd2cisen[s]] >= pbest + dyn_ci_pbeam )){	    ng+=approx_mgau_eval (gs,svq,g,fastgmm,s,senscr,feat,best_cid,svq_beam);	    ns++;	  }else {	    senscr[s]=senscr[cd2cisen[s]]; /* backoff to CI score, not gaussians computed */	  }	  if (best < senscr[s]) best = senscr[s];	}      }      /*Make a copy to the most recent active list */      rec_sen_active[s]=sen_active[s];    }else{ /* Loop handling no computation*/      /* All complexity of the skipping loop will be coded here */      if(is_compute){	if(rec_sen_active[s])	  senscr[s]=senscr[s]; /*Yes. No change to the score */	else{	  rec_sen_active[s]=1;	  ng+=approx_mgau_eval (gs,svq,g,fastgmm,s,senscr,feat,best_cid,svq_beam);	  ns++;	  if(senscr[s]>fastgmm->rec_bst_senscr){ 	    /* Rescore everything if we are better best scores*/	    E_INFO("Re-normalizing the previous score\n");	    /*Every thing except the new score are recomputed*/	    for (t = 0; t < g->n_mgau; t++) {	      if(rec_sen_active[t]&& t!=s ){		senscr[t]-=(senscr[s]-fastgmm->rec_bst_senscr);	      }	    }	    /*Update the best senone score*/	    fastgmm->rec_bst_senscr=senscr[s];	  }	  /*Update the new senone score*/	  senscr[s]-=fastgmm->rec_bst_senscr;	}      }    }  }  if(!is_skip){    for (s = 0; s < g->n_mgau; s++){      if(sen_active[s])	senscr[s]-=best;    }  }else{   #if 0    E_INFO("Best score %d\n",fastgmm->rec_bst_senscr);    for(s=0 ;s < g-> n_mgau; s++){      if(sen_active[s]){	  E_INFO("At the end: Senone %d has scores %d\n",s,senscr[s]);	if(senscr[s]>0){	  E_FATAL("Something wrong, senone score > 0\n",s,senscr[s]);	}      }    }#endif  }  /*Don't delete this line, it is very useful in analysing the performance*/#if APPROX_ANALYSE  E_INFO("time: %d , cisen %d, sen: %d, gau: %d\n",frame, n_cis, ns, ng);#endif  g->frm_sen_eval = ns;  g->frm_gau_eval = ng;  ci_occ=NULL;  return best;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -