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

📄 hfb.c

📁 实现HMM算法
💻 C
📖 第 1 页 / 共 5 页
字号:
         }         if (trace&T_TOP) {            printf("Retrying Beta pass at %5.1f\n",pruneThresh);         }      }   while(pruneThresh<=pruneSetting.pruneLim);      if (lbeta<LSMALL)      HError(7323,"StepBack: Beta prune error");   return TRUE;}/* ---------------------- Statistics Accumulation -------------------- *//* UpTranParms: update the transition counters of given hmm */static void UpTranParms(FBInfo *fbInfo, HLink hmm, int t, int q,                        DVector aqt, DVector bqt, DVector bqt1, DVector bq1t,                         LogDouble pr){   int i,j,N;   Vector ti,ai;   float ***outprob,***outprob1;   double sum,x;   TrAcc *ta;   AlphaBeta *ab;   N = hmm->numStates;   ab = fbInfo->ab;   ta = (TrAcc *) GetHook(hmm->transP);/*转移矩阵Accumulators*/   outprob = ab->otprob[t][q]; /*t时刻第q个模型的观察概率*/   if (bqt1!=NULL) outprob1 = ab->otprob[t+1][q];  /* Bug fix */   else outprob1 = NULL;   for (i=1;i<N;i++)      ta->occ[i] += ab->occt[i];/* 状态占有累加器,每个状态i的状态占有等于每个时刻t该状态i的状态占有的累加state occupation */   for (i=1;i<N;i++) {      ti = ta->tran[i]; ai = hmm->transP[i];/*ti为第i个状态的转移向量的累加器,ai为当前时刻t第i个状态的转移向量*/      for (j=2;j<=N;j++) {         if (i==1 && j<N) {                  /* 入口状态1到其它状态j(j<N)的转移entry transition */            x = aqt[1]+ai[j]+outprob[j][0][0]+bqt[j]-pr;/*计算HTKBOOK第131页的公式(1)分子部分的时间t的累加单项,此为对数概率形式*/            if (x>MINEARG) ti[j] += exp(x);/*状态i和状态j之间转移的时间t的累加单项,恢复为原始概率*/         } else            if (i>1 && j<N && bqt1!=NULL) {     /* 内部状态之间的转移internal transition */               x = aqt[i]+ai[j]+outprob1[j][0][0]+bqt1[j]-pr;/*计算HTKBOOK第130页的公式(1)分子部分的时间t的累加单项,此为对数概率形式*/               if (x>MINEARG) ti[j] += exp(x);/*状态i和状态j之间转移的时间t的累加单项,恢复为原始概率*/            } else               if (i>1 && j==N) {/*计算HTKBOOK第131页的公式(2)分子部分的时间t的累加单项,此为对数概率形式*/ /* 状态i(i>1)到模型出口状态Nq的转移exit transition */                  x = aqt[i]+ai[N]+bqt[N]-pr;                  if (x>MINEARG) ti[N] += exp(x);/*状态i和状态N之间转移的时间t的累加单项,恢复为原始概率*/               }         if (i==1 && j==N && ai[N]>LSMALL && bq1t != NULL){ /*计算HTKBOOK第131页的公式(3)分子部分的时间t的累加单项,此为对数概率形式*//* 模型的入口状态1到出口状态Nq的转移tee transition */            x = aqt[1]+ai[N]+bq1t[1]-pr;            if (x>MINEARG) ti[N] += exp(x);/*状态1和状态N之间转移的时间t的累加单项,恢复为原始概率*/         }      }   }   if (trace&T_TRA && NonSkipRegion(fbInfo->skipstart,fbInfo->skipend,t)) {/*当前不执行此处*/      printf("Tran Counts at time %d, Model Q%d %s\n",t,q,ab->qIds[q]->name);      for (i=1;i<=N;i++) {         printf("  %d. Occ %8.2f: Trans ",i,ta->occ[i]);         sum = 0.0;         for (j=2; j<=N; j++) {            x = ta->tran[i][j]; sum += x;            printf("%7.2f ",x);         }         printf(" [%8.2f]\n",sum);      }   }}/* UpMixParms: update mu/va accs of given hmm在当前时刻t,更新第q个模型的相关累加器 */static void UpMixParms(FBInfo *fbInfo, int q, HLink hmm, HLink al_hmm,                       Observation ot, Observation ot2,                        int t, DVector aqt, DVector aqt1, DVector bqt, int S,                       Boolean twoDataFiles, LogDouble pr){   int i,s,j,k,kk,m=0,mx,M=0,N,vSize;   Vector mu_jm,var,mean=NULL,invk,otvs;   TMixRec *tmRec = NULL;   float **outprob;   Matrix inv;   LogFloat c_jm,a,prob=0.0;   LogDouble x,initx = LZERO;   float zmean,zmeanlr,zmean2,tmp;   double Lr,steSumLr;   HMMSet *hset;   HSetKind hsKind;   AlphaBeta *ab;   StreamElem *ste, *al_ste=NULL;   MixtureElem *me;   MixPDF *mp=NULL;   MuAcc *ma;   VaAcc *va;   WtAcc *wa = NULL;   Boolean mmix=FALSE;  /* TRUE if multiple mixture */   float wght=0.0;   /* variables for 2-model reestimation */   Vector comp_prob=NULL;        /* array[1..M] of Component probability */   float norm=0.0;               /* total mixture prob */   LogFloat det;   AdaptXForm *inxform;   ab     = fbInfo->ab;   hset   = fbInfo->up_hset;   hsKind = fbInfo->hsKind;   if (trace&T_MIX && fbInfo->uFlags&UPMIXES &&        NonSkipRegion(fbInfo->skipstart,fbInfo->skipend,t)){/*当前不执行此处*/      printf("Mixture Weights at time %d, model Q%d %s\n",             t,q,ab->qIds[q]->name);   }   if (fbInfo->twoModels)/*当前不执行此处*/       comp_prob = CreateVector(&gstack,fbInfo->maxM);   N = hmm->numStates;   for (j=2;j<N;j++) {/*第1个状态和最后一个状态都没有观察*/      if (fbInfo->maxM>1){/*当前此判断条件为假,不执行此处*/         initx = hmm->transP[1][j] + aqt[1];         if (t>1)            for (i=2;i<N;i++){               a = hmm->transP[i][j];               if (a>LSMALL)                  initx = LAdd(initx,aqt1[i]+a);            }         initx += bqt[j] - pr;      }/*以上不被执行*/      if (trace&T_MIX && fbInfo->uFlags&UPMIXES &&           NonSkipRegion(fbInfo->skipstart,fbInfo->skipend,t))/*当前此判断条件为假,不执行此处*/         printf("  State %d: ",j);/*当前从下面开始执行*/      ste = hmm->svec[j].info->pdf+1;/*当前要更新模型的第j个状态的流信息指针*/      outprob = ab->otprob[t][q][j];/*当前时刻t第q个模型的第j个状态的观察概率*/      for (s=1;s<=S;s++,ste++){         /* Get observation vector for this state/stream */         vSize = hset->swidth[s];/*当前特征向量的长度vSize=39*/               switch (hsKind){/*当前ksKind=1,即等于SHAREDHS*/         case TIEDHS:             /* if tied mixtures then we only */            tmRec = &(hset->tmRecs[s]); /* want to process the non-pruned */            M = tmRec->topM;            /* components */            mmix = TRUE;            break;         case DISCRETEHS:            M = 1;            mmix = FALSE;            break;         case PLAINHS:         case SHAREDHS:/*当前执行此分支*/            M = ste->nMix;/*当前流的混合数*/            mmix = (M>1);            break;         }         /* update weight occupation count 更新权占有计数*/         wa = (WtAcc *) ste->hook; steSumLr = 0.0;/*状态元素Lr加和*/         if (fbInfo->twoModels) { /* component probs of update hmm *//*当前不执行这里*/            norm = LZERO;            for (mx=1; mx<=M; mx++) {               if (alCompLevel) {                  al_ste = al_hmm->svec[j].info->pdf+1;                  if (al_ste->nMix != M)                     HError(999,"Cannot align at the component level if number of components is different!");               }               if (alCompLevel) {                  me = al_ste->spdf.cpdf+mx;               } else {                  me = ste->spdf.cpdf+mx;               }	           inxform = fbInfo->inXForm;               mp=me->mpdf;               if (twoDataFiles){                    if (alCompLevel) {                     otvs = ApplyCompFXForm(mp,ot.fv[s],fbInfo->al_inXForm,&det,t);                  }                  else {                     otvs = ApplyCompFXForm(mp,ot2.fv[s],inxform,&det,t);                  }               } else {                  otvs = ApplyCompFXForm(mp,ot.fv[s],inxform,&det,t);               }               wght = MixLogWeight(hset,me->weight);               comp_prob[mx]=wght+MOutP(otvs,mp)+det;               norm = LAdd(norm,comp_prob[mx]);            }         }/*从下面开始执行*/         for (mx=1;mx<=M;mx++) {             /* process mixtures */            switch (hsKind){    /* Get wght and mpdf */            case TIEDHS:               m=tmRec->probs[mx].index;               wght=MixLogWeight(hset,ste->spdf.tpdf[m]);               mp=tmRec->mixes[m];               break;            case DISCRETEHS:               if (twoDataFiles)                  m=ot2.vq[s];               else                  m=ot.vq[s];               wght = 0.0; /* This is the log-weight, just for consistency! */               mp=NULL;               break;            case PLAINHS:            case SHAREDHS:/*当前执行这里*/               m = mx;/*当前混合索引*/               me = ste->spdf.cpdf+m;/*当前MixtureElem */               wght = MixLogWeight(hset,me->weight);/*混合权的对数值*/               mp=me->mpdf;/* 当前混合元素的 mixture pdf */               break;            }            if (wght>LMINMIX){/*当前执行这里*/              /* compute mixture likelihood  */              if (!mmix || (hsKind==DISCRETEHS))/*当前mmix=F,所以此判断条件为真*/ /* For DISCRETEHS calcs are*/                 x = aqt[j]+bqt[j]-pr;/* same as single mix*//*计算了HTKBOOK第8页的公式(1.26)*/              else if (fbInfo->twoModels) { /*下面部分不被执行*/     /* note: only SHAREDHS or PLAINHS */                 x = comp_prob[m]+aqt[j]+bqt[j]-pr-norm;              }              else {                 c_jm=wght;                 x = initx+c_jm;                 switch(hsKind) {                 case TIEDHS :                    tmp = tmRec->probs[mx].prob;                    prob = (tmp>=MINLARG)?log(tmp)+tmRec->maxP:LZERO;                    break;                 case PLAINHS :                  case SHAREDHS:		            if (S==1)		              prob = outprob[0][mx];		            else		              prob = outprob[s][mx];                    break;                 default:                    x=LZERO;                    break;                 }                 x += prob;                 if (S>1)      /* adjust for parallel streams */                    x += outprob[s][0];              }/*以上部分不被执行, c_jm=wght;之上的else分支结束*/              if (twoDataFiles){ /*当前此判断条件为假*/ /* switch to new data for mu & var est */                 otvs = ot2.fv[s];              }              if (-x<pruneSetting.minFrwdP) {		         if (twoDataFiles){  /* switch to new data for mu & var est */		            otvs = ApplyCompFXForm(mp,ot2.fv[s],fbInfo->paXForm,&det,t);				 } else {/*执行这里*/		         otvs = ApplyCompFXForm(mp,ot.fv[s],fbInfo->paXForm,&det,t);/*det=0; return fv[s],otvs为从调用参数传过来的观察的特征向量*/				 }                 Lr = exp(x);/*将对数概率转换成了原始概率,计算了HTKBOOK第8页的公式(1.26)*/                  /* More diagnostics */                  /* if (Lr>0.000001 && ab->occt[j]>0.000001 &&                     (Lr/ab->occt[j])>1.00001)                     printf("Too big %d %d %s : %5.3f %10.2f %8.2f (%4.2f)\n",t,q,                     ab->qIds[q]->name,Lr/ab->occt[j],Lr,ab->occt[j],prob); */                              /* update occupation counts */                  steSumLr += Lr;                  /* update the adaptation statistic counts */                  if (fbInfo->uFlags&UPXFORM)/*当前不执行此处*/                     AccAdaptFrame(Lr, otvs, mp, t);                  /* update mean counts */                  if ((fbInfo->uFlags&UPMEANS) || (fbInfo->uFlags&UPVARS))/*当前执行此处*/                     mean = mp->mean;                   if ((fbInfo->uFlags&UPMEANS) && (fbInfo->uFlags&UPVARS)) {/*当前执行此处*/                     ma = (MuAcc *) GetHook(mean);                     va = (VaAcc *) GetHook(mp->cov.var);                     ma->occ += Lr;/* HTKbook第7页第(1.13)公式的分母累加单项,共享这个混合密度函数的状态占有数occ for states sharing this mpdf */                     va->occ += Lr; /* HTKbook第7页第(1.14)公式的分母累加单项,共享这个混合密度函数的状态占有数occ for states sharing this mpdf */                     mu_jm = ma->mu;/* mean vector counts */                     if ((mp->ckind==DIAGC)||(mp->ckind==INVDIAGC)){/*当前执行此处*/                       /*
						ste为从调用参数中传递过来的HMM的第j个状态元素的状态信息的流元素
                        otvs为从调用参数传过来的观察的特征向量
                        mp为为从调用参数中传递过来的HMM的第j个状态元素的状态信息的流元素的第m个混合的pdf 
						 用新的观察更新方差
						*/ 
						var = va->cov.var;                        for (k=1;k<=vSize;k++) {/*更新方差,计算HTKBOOK第7页公式(1.14)中分子的求和单项*/                           zmean=otvs[k]-mean[k];/*当前观察-均值*/                           zmeanlr=zmean*Lr;/*将上面的差乘以权值L*//* 当前时刻t,当前状态j的均值累加,HTKbook第7页第(1.13)公式的分子累加单项*/                           mu_jm[k] += zmeanlr;                           var[k] += zmean*zmeanlr;;/*计算HTKBOOK第7页公式(1.14)中分子的求和单项,即当前时刻t,当前状态j的方差累加*/                        }/*k循环结束*/                     } else {/*当前不执行此分之*/                        inv = va->cov.inv;                        for (k=1;k<=vSize;k++) {                           invk = inv[k];                           zmean=otvs[k]-mean[k];                           zmeanlr=zmean*Lr;                           mu_jm[k] += zmeanlr;                           for (kk=1;kk<=k;kk++) {                              zmean2 = otvs[kk]-mean[kk];                              invk[kk] += zmean2*zmeanlr;                           }/*kk循环结束*/                        }/*k循环结束*/                     }/*inv = va->cov.inv;之上的else分支结束*/                  }/*ma = (MuAcc *) GetHook(mean);之上的if分支结束*/                  else if (fbInfo->uFlags&UPMEANS){/*当前不执行这里*/                     ma = (MuAcc *) GetHook(mean);                     mu_jm = ma->mu;                     ma->occ += Lr;                     for (k=1;k<=vSize;k++)     /* sum zero mean */                        mu_jm[k] += (otvs[k]-mean[k])*Lr;                  }                  else if (fbInfo->uFlags&UPVARS){/*当前不执行这里*/                     /* update covariance counts */                     va = (VaAcc *) GetHook(mp->cov.var);                     va->occ += Lr;                     if ((mp->ckind==DIAGC)||(mp->ckind==INVDIAGC)){                        var = va->cov.var;                        for (k=1;k<=vSize;k++) {                           zmean=otvs[k]-mean[k];                           var[k] += zmean*zmean*Lr;                        }                     } else {                        inv = va->cov.inv;                        for (k=1;k<=vSize;k++) {                           invk = inv[k];                           zmean=otvs[k]-mean[k];                                          for (kk=1;kk<=k;kk++) {                              zmean2 = otvs[kk]-mean[kk];                              invk[kk] += zmean*zmean2*Lr;                           }                        }                     }                  }                              /* update mixture weight counts */                  if (fbInfo->uFlags&UPMIXES) {/*当前执行这里*/                     wa->c[m] +=Lr;                     if (trace&T_MIX && NonSkipRegion(fbInfo->skipstart,fbInfo->skipend,t))                        printf("%3d. %7.2f",m,wa->c[m]);                  }               }            }            if (twoDataFiles){ /* Switch back to old data for prob calc */               otvs = ot.fv[s]

⌨️ 快捷键说明

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