search_bestfirst_main.c

来自「julius version 4.12.about sound recognit」· C语言 代码 · 共 2,134 行 · 第 1/5 页

C
2,134
字号
/**** CM computation method 1(default):                  ******//****   - Use local posterior probabilities while search ******//****   - Obtain CM at hypothesis expansion time         ******//**************************************************************//**  * <JA> * CM纷换脱のパラメ〖タを介袋步する. CM纷换の木涟に钙び叫される.  * * @param sd [i/o] 妈2パス脱ワ〖クエリア * @param wnum [in] スタックサイズ * @param cm_alpha [in] 蝗脱するスケ〖リング猛 *  * </JA> * <EN> * Initialize parameters for confidence scoring (will be called at * each startup of 2nd pass) * * @param sd [i/o] work area for 2nd pass * @param wnum [in] stack size * @param cm_alpha [in] scaling value to use at confidence scoring * </EN> */static voidcm_init(StackDecode *sd, int wnum, LOGPROB cm_alpha#ifdef CM_MULTIPLE_ALPHA	, cm_alpha_num#endif	){  sd->l_stacksize = wnum;  sd->l_start = sd->l_bottom = NULL;  sd->l_stacknum = 0;  sd->cm_alpha = cm_alpha;#ifdef CM_MULTIPLE_ALPHA  if (sd->cmsumlist) {    if (sd->cmsumlistlen < cm_alpha_num) {      free(sd->cmsumlist);      sd->cmsumlist = NULL;    }  }  if (sd->cmsumlist == NULL) {    sd->cmsumlist = (LOGPROB *)mymalloc(sizeof(LOGPROB) * cm_alpha_num);    sd->cmsumlistlen = cm_alpha_num;  }#endif    }/**  * <JA> * CM纷换のためにロ〖カルスタックに鸥倡簿棱を办箕弄に瘦赂する.  *  * @param sd [i/o] 妈2パス脱ワ〖クエリア * @param new [in] 鸥倡簿棱 * </JA> * <EN> * Store an expanded hypothesis to the local stack for later CM scoring *  * @param sd [i/o] work area for 2nd pass * @param new [in] expanded hypothesis * </EN> */static voidcm_store(StackDecode *sd, NODE *new){  /* store the generated hypo into local stack */  put_to_stack(new, &(sd->l_start), &(sd->l_bottom), &(sd->l_stacknum), sd->l_stacksize);}/**  * <JA> * CM纷换のためにロ〖カルスタック柒の簿棱の叫附澄唯の圭纷を滇める. * * @param sd [i/o] 妈2パス脱ワ〖クエリア *  * </JA> * <EN> * Compute sum of probabilities for hypotheses in the local stack for * CM scoring. * * @param sd [i/o] work area for 2nd pass *  * </EN> */static voidcm_sum_score(StackDecode *sd#ifdef CM_MULTIPLE_ALPHA	     , bgn, end, step#endif){  NODE *node;  LOGPROB sum;#ifdef CM_MULTIPLE_ALPHA  LOGPROB a;  int j;#endif  if (sd->l_start == NULL) return;	/* no hypo */  sd->cm_tmpbestscore = sd->l_start->score; /* best hypo is at the top of the stack */#ifdef CM_MULTIPLE_ALPHA  for (j = 0, a = bgn; a <= end; a += step) {    sum = 0.0;    for(node = sd->l_start; node; node = node->next) {      sum += pow(10, a * (node->score - sd->cm_tmpbestscore));    }    sd->cmsumlist[j++] = sum;	/* store sums for each alpha coef. */  }#else  sum = 0.0;  for(node = sd->l_start; node; node = node->next) {    sum += pow(10, sd->cm_alpha * (node->score - sd->cm_tmpbestscore));  }  sd->cm_tmpsum = sum;		/* store sum */#endif}/**  * <JA> * 鸥倡されたある矢簿棱について·その鸥倡帽胳の慨完刨を·祸稿澄唯に * 答づいて纷换する.  *  * @param sd [i/o] 妈2パス脱ワ〖クエリア * @param node [i/o] 鸥倡されたある矢簿棱 * </JA> * <EN> * Compute confidence score of a new word at the end of the given hypothesis, * based on the local posterior probabilities. *  * @param sd [i/o] work area for 2nd pass * @param node [i/o] expanded hypothesis * </EN> */static voidcm_set_score(StackDecode *sd, NODE *node#ifdef CM_MULTIPLE_ALPHA	     , bgn, end, step#endif	     ){#ifdef CM_MULTIPLE_ALPHA  int j;  LOGPROB a;#endif#ifdef CM_MULTIPLE_ALPHA  for (j = 0, a = bgn; a <= end; a += step) {    node->cmscore[node->seqnum-1][j] = pow(10, a * (node->score - sd->cm_tmpbestscore)) / sd->cmsumlist[j];    j++;  }#else  node->cmscore[node->seqnum-1] = pow(10, sd->cm_alpha * (node->score - sd->cm_tmpbestscore)) / sd->cm_tmpsum;#endif}/**  * <JA> * CM纷换脱のロ〖カルスタックから簿棱を艰り叫す.  *  * @param sd [i/o] 妈2パス脱ワ〖クエリア *  * @return 艰り叫された矢簿棱を手す.  * </JA> * <EN> * Pop one node from local stack for confidence scoring. *  * @param sd [i/o] work area for 2nd pass *  * @return the popped hypothesis. * </EN> */static NODE *cm_get_node(StackDecode *sd){  return(get_best_from_stack(&(sd->l_start), &(sd->l_stacknum)));}#endif /* CM_SEARCH */#ifdef CM_NBEST/*****************************************************************//**** CM computation method 2: conventional N-best scoring *******//**** NOTE: enough N-best should be computed (-n 10 ~ -n 100) ****//*****************************************************************//**  * <JA> * スタック柒にある矢铬输から帽胳慨完刨を纷换する.  *  * @param sd [i/o] 妈2パス脱ワ〖クエリア * @param start [in] スタックの黎片ノ〖ド * @param stacknum [in] スタックサイズ * @param jconf [in] SEARCH脱肋年パラメ〖タ * </JA> * <EN> * Compute confidence scores from N-best sentence candidates in the * given stack. *  * @param sd [i/o] work area for 2nd pass * @param start [in] stack top node  * @param stacknum [in] current stack size * @param jconf [in] SEARCH configuration parameters * </EN> */static voidcm_compute_from_nbest(StackDecode *sd, NODE *start, int stacknum, JCONF_SEARCH *jconf){  NODE *node;  LOGPROB bestscore, sum, s;  WORD_ID w;  int i;  LOGPROB cm_alpha;  int j;  /* prepare buffer */#ifdef CM_MULTIPLE_ALPHA  if (sd->cmsumlist) {    if (sd->cmsumlistlen < jconf->annotate.cm_alpha_num) {      free(sd->cmsumlist);      sd->cmsumlist = NULL;    }  }  if (sd->cmsumlist == NULL) {    sd->cmsumlist = (LOGPROB *)mymalloc(sizeof(LOGPROB) * jconf->annotate.cm_alpha_num);    sd->cmsumlistlen = cm_alpha_num;  }#endif      if (sd->sentcm == NULL) {		/* not allocated yet */    sd->sentcm = (LOGPROB *)mymalloc(sizeof(LOGPROB)*stacknum);    sd->sentnum = stacknum;  } else if (sd->sentnum < stacknum) { /* need expanded */    sd->sentcm = (LOGPROB *)myrealloc(sentcm, sizeof(LOGPROB)*stacknum);    sd->sentnum = stacknum;  }  if (sd->wordcm == NULL) {    sd->wordcm = (LOGPROB *)mymalloc(sizeof(LOGPROB) * winfo->num);  }    cm_alpha = jconf->annotate.cm_alpha;#ifdef CM_MULTIPLE_ALPHA  for (j = 0, cm_alpha = jconf->annotate.cm_alpha_bgn; cm_alpha <= jconf->annotate.cm_alpha_end; cm_alpha += jconf->annotate.cm_alpha_step) {#endif    /* clear whole word cm buffer */    for(w=0;w<winfo->num;w++) {      sd->wordcm[w] = 0.0;    }    /* get best score */    bestscore = start->score;    /* compute sum score of all hypothesis */    sum = 0.0;    for (node = start; node != NULL; node = node->next) {      sum += pow(10, cm_alpha * (node->score - bestscore));    }    /* compute sentence posteriori probabilities */    i = 0;    for (node = start; node != NULL; node = node->next) {      sd->sentcm[i] = pow(10, cm_alpha * (node->score - bestscore)) / sum;      i++;    }    /* compute word posteriori probabilities */    i = 0;    for (node = start; node != NULL; node = node->next) {      for (w=0;w<node->seqnum;w++) {	sd->wordcm[node->seq[w]] += sd->sentcm[i];      }      i++;    }    /* store the probabilities to node */    for (node = start; node != NULL; node = node->next) {      for (w=0;w<node->seqnum;w++) {#ifdef CM_MULTIPLE_ALPHA	node->cmscore[w][j] = sd->wordcm[node->seq[w]];#else		node->cmscore[w] = sd->wordcm[node->seq[w]];#endif      }    }#ifdef CM_MULTIPLE_ALPHA    j++;  }#endif}#endif /* CM_NBEST */#endif /* CONFIDENCE_MEASURE *//**********************************************************************//********** Enveloped best-first search *******************************//**********************************************************************//* * 1. Word envelope * * 办硷の簿棱ビ〖ム升を肋年: 鸥倡傅となった簿棱の眶をその簿棱墓(帽胳眶) * ごとにカウントする. 办年眶を臂えたらそれより没い簿棱は笆稿鸥倡しない.  *  * Introduce a kind of beam width to search tree: count the number of * popped hypotheses per the depth of the hypotheses, and when a count * in a certain depth reaches the threshold, all hypotheses shorter than * the depth will be dropped from candidates. * *//**  * <JA> * Word envelope 脱にカウンタを介袋步する. * * @param s [i/o] 妈2パス脱ワ〖クエリア *  * </JA> * <EN> * Initialize counters fro word enveloping. *  * @param s [i/o] work area for 2nd pass * </EN> */static voidwb_init(StackDecode *s){  int i;  for(i=0;i<=MAXSEQNUM;i++) s->hypo_len_count[i] = 0;  s->maximum_filled_length = -1;}/**  * <JA> * Word envelope を徊救して·涂えられた簿棱を鸥倡してよいかどうかを手す.  * また·Word envelope のカウンタを构糠する.  *  * @param s [i/o] 妈2パス脱ワ〖クエリア * @param now [in] 海から鸥倡しようとしている簿棱 * @param width [in] 鸥倡カウントの惧嘎猛 *  * @return 鸥倡材墙∈鸥倡カウントが惧嘎に茫していない∷なら TRUE, * 鸥倡稍材墙∈カウントが惧嘎に茫している∷なら FALSE を手す.  * </JA> * <EN> * Consult the current word envelope to check if word expansion from * the hypothesis node is allowed or not.  Also increment the counter * of word envelope if needed. *  * @param s [i/o] work area for 2nd pass * @param now [in] popped hypothesis * @param width [in] maximum limit of expansion count *  * @return TRUE if word expansion is allowed (in case word envelope count * of the corresponding hypothesis depth does not reach the limit), or * FALSE if already prohibited. * </EN> */static booleanwb_ok(StackDecode *s, NODE *now, int width){  if (now->seqnum <= s->maximum_filled_length) {    /* word expansion is not allowed because a word expansion count       at deeper level has already reached the limit */    return FALSE;  } else {    /* word expansion is possible.  Increment the word expansion count       of the given depth */    s->hypo_len_count[now->seqnum]++;    if (s->hypo_len_count[now->seqnum] > width) {      /* the word expansion count of this level has reached the limit, so	 set the beam-filled depth to this level to inhibit further	 expansion of shorter hypotheses. */      if (s->maximum_filled_length < now->seqnum) s->maximum_filled_length = now->seqnum;    }    return TRUE;  }}#ifdef SCAN_BEAM/* * 2. Score envelope * * Viterbi纷换翁の猴负: 掐蜗フレ〖ムごとの呵络锑刨 (score envelope) を * 链簿棱にわたって淡峡しておく. 簿棱の涟羹き锑刨纷换箕に·その envelope * から办年升笆惧スコアが布搀るとき·Viterbi パスの遍换を面们する.  * * ここでは·艰り叫した簿棱からフレ〖ムごとの score envelope を构糠する * 婶尸が淡揭されている. Envelope を雇胃した Viterbi 纷换の悸狠は * scan_word() を徊救のこと.  * * Reduce computation cost of hypothesis Viterbi processing by setting a * "score envelope" that holds the maximum scores at every frames * throughout the expanded hypotheses.  When calculating Viterbi path * on HMM trellis for updating score of popped hypothesis, Viterbi paths * that goes below a certain range from the score envelope are dropped. * * These functions are for updating the score envelope according to the * popped hypothesis.  For actual Viterbi process with score envelope,  * see scan_word(). * *//**  * <JA> * Score envelope を介袋步する. 妈2パスの倡幌箕に钙ばれる.  *  * @param s [i/o] 妈2パス脱ワ〖クエリア * @param framenum [in] 掐蜗フレ〖ム墓 * </JA> * <EN> * Initialize score envelope.  This will be called once at the beginning * of 2nd pass. *  * @param s [i/o] work area for 2nd pass * @param framenum [in] input frame length * </EN> */static voidenvl_init(StackDecode *s, int framenum){  int i;  for(i=0;i<framenum;i++) s->framemaxscore[i] = LOG_ZERO;}/**  * <JA> * 簿棱の涟羹きスコアから score envelope を构糠する.  *  * @param s [i/o] 妈2パス脱ワ〖クエリア * @param n [in] 簿棱

⌨️ 快捷键说明

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