/** * Return average of N-beat outprob for pseudo state set. * * @param wrk [i/o] HMM computation work area * @param t [in] input frame * @param lset [in] pseudo state set * @param param [in] input parameter data * * @return outprob log probability, average of top N states in @a lset. */ static LOGPROB outprob_cd_nbest(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param) { LOGPROB prob; int i, k, n; n = 0; for(i=0;i<lset->num;i++) { prob = outprob_state(wrk, t, lset->s[i], param); /*jlog("\t\t%d:%f\n", i, prob);*/ if (prob <= LOG_ZERO) continue; if (n == 0 || prob <= wrk->cd_nbest_maxprobs[n-1]) { if (n == wrk->cd_nbest_maxn) continue; wrk->cd_nbest_maxprobs[n] = prob; n++; } else { for(k=0; k<n; k++) { if (prob > wrk->cd_nbest_maxprobs[k]) { memmove(&(wrk->cd_nbest_maxprobs[k+1]), &(wrk->cd_nbest_maxprobs[k]), sizeof(LOGPROB) * (n - k - ( (n == wrk->cd_nbest_maxn) ? 1 : 0))); wrk->cd_nbest_maxprobs[k] = prob; break; } } if (n < wrk->cd_nbest_maxn) n++; } } prob = 0.0; for(i=0;i<n;i++) { /*jlog("\t\t\t- %d: %f\n", i, wrk->cd_nbest_maxprobs[i]);*/ prob += wrk->cd_nbest_maxprobs[i]; } return(prob/(float)n); }
/** * Top function to compute the output probability of a HMM state. * * @param wrk [i/o] HMM computation work area * @param t [in] input frame * @param hmmstate [in] HMM state * @param param [in] input parameter data * * @return the computed log output probability. */ LOGPROB outprob(HMMWork *wrk, int t, HMM_STATE *hmmstate, HTK_Param *param) { if (hmmstate->is_pseudo_state) { return(outprob_cd(wrk, t, hmmstate->out.cdset, param)); } else { return(outprob_state(wrk, t, hmmstate->out.state, param)); } }
/** * Return maximum outprob of the pseudo state set. * * @param wrk [i/o] HMM computation work area * @param t [in] input frame * @param lset [in] pseudo state set * @param param [in] input parameter data * * @return maximum output log probability among states in @a lset. */ static LOGPROB outprob_cd_max(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param) { LOGPROB maxprob, prob; int i; maxprob = LOG_ZERO; for(i=0;i<lset->num;i++) { prob = outprob_state(wrk, t, lset->s[i], param); if (maxprob < prob) maxprob = prob; } return(maxprob); }
/** * Return average outprob of the pseudo state set. * * @param wrk [i/o] HMM computation work area * @param t [in] input frame * @param lset [in] pseudo state set * @param param [in] input parameter data * * @return average output log probability of states in @a lset. */ static LOGPROB outprob_cd_avg(HMMWork *wrk, int t, CD_State_Set *lset, HTK_Param *param) { LOGPROB sum, p; int i,j; sum = 0.0; j = 0; for(i=0;i<lset->num;i++) { p = outprob_state(wrk, t, lset->s[i], param); if (p > LOG_ZERO) { sum += p; j++; } } return(sum/(float)j); }
/** * <JA> * 木構造化辞書上の状態の出力確率を計算する. * * @param wchmm [in] 木構造化辞書情報 * @param node [in] ノード番号 * @param last_wid [in] 直前単語(単語先頭のトライフォン計算に用いる) * @param t [in] 時間フレーム * @param param [in] 特徴量パラメータ構造体 (@a t 番目のベクトルについて計算する) * * @return 出力確率の対数値を返す. * </JA> * <EN> * Calculate output probability on a tree lexion node. This function * calculates log output probability of an input vector on time frame @a t * in input paramter @a param at a node on tree lexicon. * * @param wchmm [in] tree lexicon structure * @param node [in] node ID to compute the output probability * @param last_wid [in] word ID of last word hypothesis (used when the node is * within the word beginning phone and triphone is used. * @param t [in] time frame of input vector in @a param to compute. * @param param [in] input parameter structure * * @return the computed log probability. * </EN> * @callgraph * @callergraph */ LOGPROB outprob_style(WCHMM_INFO *wchmm, int node, int last_wid, int t, HTK_Param *param) { char rbuf[MAX_HMMNAME_LEN]; ///< Local workarea for HMM name conversion #ifndef PASS1_IWCD /* if cross-word triphone handling is disabled, we simply compute the output prob of the state */ return(outprob_state(wchmm->hmmwrk, t, wchmm->state[node].out, param)); #else /* PASS1_IWCD */ /* state type and context cache is considered */ HMM_Logical *ohmm, *rhmm; RC_INFO *rset; LRC_INFO *lrset; CD_Set *lcd; WORD_INFO *winfo = wchmm->winfo; HTK_HMM_INFO *hmminfo = wchmm->hmminfo; /* the actual computation is different according to their context dependency handling */ switch(wchmm->outstyle[node]) { case AS_STATE: /* normal state (word-internal or context-independent )*/ /* compute as usual */ return(outprob_state(wchmm->hmmwrk, t, wchmm->state[node].out.state, param)); case AS_LSET: /* node in word end phone */ /* compute approximated value using the state set in pseudo phone */ return(outprob_cd(wchmm->hmmwrk, t, wchmm->state[node].out.lset, param)); case AS_RSET: /* note in the beginning phone of word */ /* depends on the last word hypothesis to compute the actual triphone */ rset = wchmm->state[node].out.rset; /* consult cache */ if (rset->cache.state == NULL || rset->lastwid_cache != last_wid) { /* cache miss...calculate */ /* rset contains either defined biphone or pseudo biphone */ if (last_wid != WORD_INVALID) { /* lookup triphone with left-context (= last phoneme) */ if ((ohmm = get_left_context_HMM(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) { rhmm = ohmm; } else { /* if triphone not found, try to use the bi-phone itself */ rhmm = rset->hmm; /* If the bi-phone is explicitly specified in hmmdefs/HMMList, use it. if both triphone and biphone not found in user-given hmmdefs/HMMList, use "pseudo" phone, as same as the end of word */ if (debug2_flag) { if (rhmm->is_pseudo) { error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name); } } } } else { /* if last word is WORD_INVALID try to use the bi-phone itself */ rhmm = rset->hmm; /* If the bi-phone is explicitly specified in hmmdefs/HMMList, use it. if not, use "pseudo" phone, as same as the end of word */ if (debug2_flag) { if (rhmm->is_pseudo) { error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name); } } } /* rhmm may be a pseudo phone */ /* store to cache */ if (rhmm->is_pseudo) { rset->last_is_lset = TRUE; rset->cache.lset = &(rhmm->body.pseudo->stateset[rset->state_loc]); } else { rset->last_is_lset = FALSE; rset->cache.state = rhmm->body.defined->s[rset->state_loc]; } rset->lastwid_cache = last_wid; } /* calculate outprob and return */ if (rset->last_is_lset) { return(outprob_cd(wchmm->hmmwrk, t, rset->cache.lset, param)); } else { return(outprob_state(wchmm->hmmwrk, t, rset->cache.state, param)); } case AS_LRSET: /* node in word with only one phoneme --- both beginning and end */ lrset = wchmm->state[node].out.lrset; if (lrset->cache.state == NULL || lrset->lastwid_cache != last_wid) { /* cache miss...calculate */ rhmm = lrset->hmm; /* lookup cdset for given left context (= last phoneme) */ strcpy(rbuf, rhmm->name); if (last_wid != WORD_INVALID) { add_left_context(rbuf, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name); } if (wchmm->category_tree) { #ifdef USE_OLD_IWCD lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf); #else /* use category-indexed cdset */ if (last_wid != WORD_INVALID && (ohmm = get_left_context_HMM(rhmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) { lcd = lcdset_lookup_with_category(wchmm, ohmm, lrset->category); } else { lcd = lcdset_lookup_with_category(wchmm, rhmm, lrset->category); } #endif } else { lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf); } if (lcd != NULL) { /* found, set to cache */ lrset->last_is_lset = TRUE; lrset->cache.lset = &(lcd->stateset[lrset->state_loc]); lrset->lastwid_cache = last_wid; } else { /* no relating lcdset found, falling to normal state */ if (rhmm->is_pseudo) { lrset->last_is_lset = TRUE; lrset->cache.lset = &(rhmm->body.pseudo->stateset[lrset->state_loc]); lrset->lastwid_cache = last_wid; } else { lrset->last_is_lset = FALSE; lrset->cache.state = rhmm->body.defined->s[lrset->state_loc]; lrset->lastwid_cache = last_wid; } } /*printf("[%s->%s]\n", lrset->hmm->name, rhmm->name);*/ } /* calculate outprob and return */ if (lrset->last_is_lset) { return(outprob_cd(wchmm->hmmwrk, t, lrset->cache.lset, param)); } else { return(outprob_state(wchmm->hmmwrk, t, lrset->cache.state, param)); } default: /* should not happen */ j_internal_error("outprob_style: no outprob style??\n"); return(LOG_ZERO); } #endif /* PASS1_IWCD */ }