📄 hinit.c
字号:
segIdx++; } else { /* load segment of parameter file */ MakeFN(fn,labDir,labExt,labfn); trans = LOpen(&transStack,labfn,lff); ncas = NumCases(trans->head,segId); if ( ncas > 0) { for (i=1,nObs=0; i<=ncas; i++) { p = GetCase(trans->head,segId,i); segStIdx = (long)(p->start/info.tgtSampRate); segEnIdx = (long)(p->end/info.tgtSampRate); if (segEnIdx >= ObsInBuffer(pbuf)) segEnIdx = ObsInBuffer(pbuf)-1; if (segEnIdx - segStIdx + 1 >= nStates-2) { LoadSegment(segStore, p->start, p->end, pbuf); if (trace&T_LD1) printf(" loading seg %s %f[%ld]->%f[%ld]\n",segId->name, p->start,segStIdx,p->end,segEnIdx); nObs += SegLength(segStore, segIdx); segIdx++; }else if (trace&T_LD1) printf(" seg %s %f->%f ignored\n",segId->name, p->start,p->end); } } } if (hset.hsKind == DISCRETEHS){ for (k=prevSegIdx; k<segIdx; k++){ segLen = SegLength(segStore, k); for (i=1; i<=segLen; i++){ obs = GetSegObs(segStore, k, i); for (s=1; s<=nStreams; s++){ if( (obs.vq[s] < 1) || (obs.vq[s] > maxMixInS[s])) HError(2150,"LoadFile: Discrete data value [ %d ] out of range in stream [ %d ] in file %s",obs.vq[s],s,fn); } } } prevSegIdx=segIdx; } if (trace&T_LD0) printf(" %d observations loaded from %s\n",nObs,fn); CloseBuffer(pbuf); ResetHeap(&transStack);}/* ---------- Initialise with Uniform Segmentation ------------------- *//* CreateSeqMat: Create a matrix of sequences */Sequence ** CreateSeqMat(void){ int i,j; Sequence **seqMat; seqMat = (Sequence**)New(&sequenceStack,(nStates-2)*sizeof(Sequence*)); seqMat -= 2; /* index is 2, ...,nStates-1 */ for (i=2; i<nStates; i++){ seqMat[i] = (Sequence*)New(&gstack, nStreams*sizeof(Sequence)); --seqMat[i]; for (j=1; j<=nStreams; j++ ){ seqMat[i][j] = CreateSequence(&sequenceStack, 100); } } return seqMat;}/* ShowSeqMat: show number of obs for each state/stream */void ShowSeqMat(Sequence **seqMat){ int j,s; printf("Sequence Matrix\n"); for (j=2; j<nStates; j++) { printf(" state %2d: ",j); for (s=1; s<=nStreams; s++) printf("%5d",seqMat[j][s]->nItems); printf("\n"); }}/* UCollectData: Collect data from segStore for each stream s of each state n and store in seqMat[n][s]*/void UCollectData(Sequence **seqMat){ int i,j,n,s,numSegs,segLen; float obsPerState; Observation obs; Ptr p; numSegs = NumSegs(segStore); for (i=1;i<=numSegs;i++) { segLen=SegLength(segStore,i); obsPerState=((float) segLen)/((float) (nStates-2)); if (obsPerState < 1.0) HError(2122,"UCollectData: segment too short[%d]",segLen); for (j=1;j<=segLen;j++) { obs = GetSegObs(segStore,i,j); n = (int)(((float)(j-1)/obsPerState)+2); for (s=1; s<=nStreams; s++){ if (hset.hsKind==DISCRETEHS){ p = (Ptr)((int)obs.vq[s]); StoreItem(seqMat[n][s],p); }else StoreItem(seqMat[n][s],obs.fv[s]); } } }}/* UniformSegment: and cluster within each state/segment */void UniformSegment(void){ Sequence **seqMat; /* Matrix [2..numStates-1][1..numStreams]*/ Sequence seq; int count,size,i,vqidx,s,n,m,M,j,k; ClusterSet *cset; Cluster *c; StreamElem *ste; Covariance cov; CovKind ck; MixPDF *mp; TMixRec *tmRec = NULL; ShortVec dw; float x,z; Vector floor; if (trace & T_UNI) printf(" Uniform Segmentation\n"); seqMat = CreateSeqMat(); cov.var = NULL; /* dummy */ UCollectData(seqMat); if (trace&T_UNI) ShowSeqMat(seqMat); /* Cluster Each State/Stream and Init HMM Parms */ for (n=2; n<nStates; n++) { if (trace&T_UNI) printf(" state %d ",n); for (s=1; s<=nStreams; s++){ size = hset.swidth[s]; floor = vFloor[s]; ste = hmmLink->svec[n].info->pdf+s; if (hset.hsKind == TIEDHS){ tmRec = &(hset.tmRecs[s]); M = tmRec->nMix; tmRec->topM = tmRec->nMix; } else M = ste->nMix; if (trace&T_UNI) printf(" stream %d\n",s); seq = seqMat[n][s]; switch (hset.hsKind){ case PLAINHS: case SHAREDHS: ck = ste->spdf.cpdf[1].mpdf->ckind; cset = FlatCluster(&clustSetStack,seq,M,NULLC,ck,cov); if (trace&T_UNI) ShowClusterSet(cset); for (m=1; m<=M; m++){ mp = ste->spdf.cpdf[m].mpdf; if (mp->ckind != ck) HError(2123,"UniformSegment: different covkind within a mix\n"); c = cset->cl+m; if (uFlags&UPMIXES) ste->spdf.cpdf[m].weight = (float)c->csize/(float)seq->nItems; if (uFlags&UPMEANS) CopyVector(c->vCtr,mp->mean); if (uFlags&UPVARS) switch(ck){ case DIAGC: for (j=1; j<=size; j++){ z= c->cov.var[j]; mp->cov.var[j] = (z<floor[j])?floor[j]:z; } break; case FULLC: for (j=1; j<=size; j++){ for (k=1; k<j; k++) { mp->cov.inv[j][k] = c->cov.inv[j][k]; } z = c->cov.inv[j][j]; mp->cov.inv[j][j] = (z<floor[j])?floor[j]:z; } break; default: HError(2124,"UniformSegment: bad cov kind %d\n",ck); } } break; case DISCRETEHS: count = 0; dw = ste->spdf.dpdf; ZeroShortVec(dw); for (i=1; i<=seq->nItems; i++){ vqidx = (int)GetItem(seq,i); if (vqidx<1 || vqidx>M) HError(2170,"UniformSegment: vqidx out of range[%d]",vqidx); ++dw[vqidx]; ++count; } for (m=1; m<=M; m++){ x = (float)dw[m]/(float)count; if (x<mixWeightFloor) x = mixWeightFloor; dw[m] = DProb2Short(x); } break; case TIEDHS: ck = tmRec->mixes[1]->ckind; cset = FlatCluster(&clustSetStack,seq,M,NULLC,ck,cov); if (trace&T_UNI) ShowClusterSet(cset); for (m=1; m<=M; m++){ mp = tmRec->mixes[m]; if (mp->ckind != ck) HError(2123,"UniformSegment: different covkind within a mix\n"); c = cset->cl+m; if (uFlags&UPMIXES) ste->spdf.tpdf[m] = (float)c->csize/(float)seq->nItems; if (uFlags&UPMEANS) CopyVector(c->vCtr,mp->mean); if (uFlags&UPVARS) switch(ck){ case DIAGC: for (j=1; j<=size; j++){ z= c->cov.var[j]; mp->cov.var[j] = (z<floor[j])?floor[j]:z; } break; case FULLC: for (j=1; j<=size; j++){ for (k=1; k<j; k++) { mp->cov.inv[j][k] = c->cov.inv[j][k]; } z = c->cov.inv[j][j]; mp->cov.inv[j][j] = (z<floor[j])?floor[j]:z; } break; default: HError(2124,"UniformSegment: bad cov kind %d\n",ck); } } break; } ResetHeap(&clustSetStack); } if ((hset.hsKind == PLAINHS) || (hset.hsKind == SHAREDHS)) FixGConsts(hmmLink); } ResetHeap(&sequenceStack);}/* ----------------- Viterbi Segmentation Routines ------------------- *//* ShowTraceBack: print the Viterbi traceBack matrix */void ShowTraceBack(int len, short **tB){ int i,state; printf(" traceback matrix\n"); for (state=2; state<nStates; state++) { printf(" %d ",state); for (i=1;i<=len;i++) printf("%3d",tB[i][state]); printf("\n"); } fflush(stdout);}/* ShowP: print current column of log probabilites */void ShowP(int col, Vector colVec){ int state; printf(" %d ",col); for (state=2; state<nStates; state++) { if (colVec[state]<=LSMALL) printf(" ---- "); else printf("%8.2f",colVec[state]); } printf("\n"); fflush(stdout);}/* ShowAlignment: print states and mixes arrays */void ShowAlignment(int segNum, int segLen, IntVec states, IntVec *mixes){ int s; printf("Alignment for segment %d [%d obs]\n",segNum,segLen); ShowIntVec(" states ",states,40); if (mixes != NULL) for (s=1; s<=nStreams; s++){ printf("%2d ",s); ShowIntVec("mix",mixes[s],40); }}/* MakeTraceBack: create the traceBack matrix */void MakeTraceBack(int segLen){ int segIdx; short *tmpPtr; traceBack = (short **)New(&traceBackStack, segLen*sizeof(short *)); --traceBack; for (segIdx=1; segIdx<=segLen; segIdx++){ tmpPtr = (short *)New(&traceBackStack, (nStates-2)*sizeof(short)); traceBack[segIdx] = tmpPtr-2; }}/* DoTraceBack: traceBack and set states array */void DoTraceBack(int segLen, IntVec states, int thisState){ int segIdx; for (segIdx=segLen; segIdx>0; segIdx--) { states[segIdx] = thisState; thisState=traceBack[segIdx][thisState]; }}/* FindBestMixes: for each state/obs pair find most likely mix component */void FindBestMixes(int segNum, int segLen, IntVec states, IntVec *mixes){ int i,s,m,bestm,M=0; StreamElem *ste; IntVec smix; Observation obs; Vector v; LogFloat bestP,p; MixtureElem *me; MixPDF *mp; if (trace&T_MIX) printf(" Mixture component alignment\n"); for (i=1; i<=segLen; i++){ ste = hmmLink->svec[states[i]].info->pdf+1; obs = GetSegObs(segStore, segNum, i); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 0.0, 1); for (s=1; s<=nStreams; s++,ste++){ if (hset.hsKind != TIEDHS) M = ste->nMix; smix = mixes[s]; if (hset.hsKind==TIEDHS) /* PrecomputeTMix has already sorted probs */ bestm = hset.tmRecs[s].probs[1].index; else if (M==1) bestm = 1; else{ v = obs.fv[s]; bestP = LZERO; bestm=0; if (trace&T_MIX) printf(" seg %d, stream %d: ",i,s); for (m=1; m<=M; m++){ me = ste->spdf.cpdf+m; mp = me->mpdf; p = MOutP(v,mp); if (p>bestP){ bestP=p; bestm=m; } if (trace&T_MIX) printf(" P(mix[%d])=%.1f",m,p); } if (bestm==0) HError(2125,"FindBestMixes: no best mix"); if (trace&T_MIX) printf(" [best=%d]\n",bestm); } smix[i] = bestm; } }}/* ViterbiAlign: align the segNum'th segment. For each frame k, store aligned state in states and mostly likely mix comp in mixes. Return logP. */LogFloat ViterbiAlign(int segNum,int segLen, IntVec states, IntVec *mixes){ int currState,prevState,bestPrevState; int segIdx; LogFloat bestP,currP,tranP,prevP; Observation obs; if (trace & T_VIT) printf(" Aligning Segment Number %d\n",segNum); MakeTraceBack(segLen); /* From entry state 1: Column 1 */ obs = GetSegObs(segStore, segNum, 1); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); for (currState=2;currState<nStates;currState++) { tranP = hmmLink->transP[1][currState]; if (tranP<LSMALL) lastP[currState] = LZERO; else lastP[currState] = tranP + OutP(&obs,hmmLink,currState); traceBack[1][currState] = 1; } if (trace & T_VIT) ShowP(1,lastP); /* Columns[2] -> Columns[segLen] -- this is the general case */ for (segIdx=2; segIdx<=segLen; segIdx++) { obs = GetSegObs(segStore, segNum, segIdx); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); for (currState=2;currState<nStates;currState++) { bestPrevState=2; tranP = hmmLink->transP[2][currState]; prevP = lastP[2]; bestP = (tranP<LSMALL) ? LZERO : tranP+prevP; for (prevState=3;prevState<nStates;prevState++) { tranP = hmmLink->transP[prevState][currState]; prevP = lastP[prevState]; currP = (tranP<LSMALL) ? LZERO : tranP+prevP; if (currP > bestP) { bestPrevState=prevState; bestP=currP; } } if (bestP<LSMALL) currP = thisP[currState] = LZERO; else { currP = OutP(&obs,hmmLink,currState); thisP[currState] = bestP+currP; } if (trace&T_OBP) printf("OutP[s=%d,t=%d] = %f\n",currState,segIdx,currP); traceBack[segIdx][currState]=bestPrevState;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -