Julius 4.2
libsent/src/anlz/paramselect.c
説明を見る。
00001 
00042 /*
00043  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00044  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00045  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00046  * All rights reserved
00047  */
00048 
00049 #include <sent/stddefs.h>
00050 #include <sent/htk_param.h>
00051 #include <sent/htk_hmm.h>
00052 
00053 
00062 static void
00063 mark_exclude_vector(int loc, int len, int *vmark, int vlen)
00064 {
00065   int i;
00066 #ifdef DEBUG
00067   printf("delmark: %d-%d\n",loc, loc+len-1);
00068 #endif
00069   for (i=0;i<len;i++) {
00070 #ifdef DEBUG
00071     if (loc + i >= vlen) {
00072       printf("delmark buffer exceeded!!\n");
00073       exit(0);
00074     }
00075 #endif
00076     vmark[loc+i] = 1;
00077   }
00078 #ifdef DEBUG
00079   printf("now :");
00080   for (i=0;i<vlen;i++) {
00081     if (vmark[i] == 1) {
00082       printf("-");
00083     } else {
00084       printf("O");
00085     }
00086   }
00087   printf("\n");
00088 #endif
00089 }
00090 
00100 static void
00101 exec_exclude_vectors(HTK_Param *p, int *vmark)
00102 {
00103   int src, dst;
00104   unsigned int t;
00105 
00106   /* shrink */
00107   for(t = 0; t < p->samplenum; t++) {
00108     dst = 0;
00109     for (src = 0; src < p->veclen; src++) {
00110       if (vmark[src] == 0) {
00111         if (dst != src) p->parvec[t][dst] = p->parvec[t][src];
00112         dst++;
00113       }
00114     }
00115   }
00116   p->veclen = dst;
00117 #ifdef DEBUG
00118   printf("new length = %d\n", p->veclen);
00119 #endif
00120 }
00121 
00122 
00132 int
00133 guess_basenum(HTK_Param *p, short qualtype)
00134 {
00135   int size;
00136   int compnum;
00137   
00138   compnum = 1 + ((qualtype & F_DELTA) ? 1 : 0) + ((qualtype & F_ACCL) ? 1 : 0);
00139   
00140   size = p->veclen;
00141   if (p->header.samptype & F_ENERGY_SUP) size += 1;
00142   if ((size % compnum) != 0) {
00143     jlog("Error: paramselect: illegal vector length (should not happen)\n");
00144     return -1;
00145   }
00146   size /= compnum;
00147   if (p->header.samptype & F_ENERGY) size -= 1;
00148   if (p->header.samptype & F_ZEROTH) size -= 1;
00149 
00150   return(size);
00151 }
00152 
00153 /* can add: _N */
00154 /* can sub: _E_D_A_0 */
00155 
00167 static boolean
00168 select_param_vmark(HTK_Param *src, short dst_type_arg, int *vmark, int vlen, short *new_type)
00169 {
00170   short dst_type;
00171   short del_type, add_type;
00172   int basenum, pb[3],pe[3],p0[3]; /* location */
00173   int i, len;
00174   char srcstr[80], dststr[80], buf[80];
00175   short src_type;
00176 
00177   src_type = src->header.samptype & ~(F_COMPRESS | F_CHECKSUM);
00178   src_type &= ~(F_BASEMASK);    /* only qualifier code needed */
00179   srcstr[0] = '\0';
00180   param_qualcode2str(srcstr, src_type, FALSE);
00181   dst_type = dst_type_arg & ~(F_COMPRESS | F_CHECKSUM);
00182   dst_type &= ~(F_BASEMASK);    /* only qualifier code needed */
00183   dststr[0] = '\0';
00184   param_qualcode2str(dststr, dst_type, FALSE);
00185 
00186 #ifdef DEBUG
00187   printf("try to select qualifiers: %s -> %s\n", srcstr, dststr);
00188 #endif
00189 
00190   if (dst_type == F_ERR_INVALID) {
00191     jlog("Error: paramselect: unknown parameter kind for selection: %s\n", dststr);
00192     return(FALSE);
00193   }
00194   
00195   /* guess base coefficient num */
00196   basenum = guess_basenum(src, src_type);
00197   if (basenum < 0) {            /* error */
00198     return(FALSE);
00199   }
00200 #ifdef DEBUG
00201   printf("base num = %d\n", basenum);
00202 #endif
00203 
00204   /* determine which component to use */
00205   del_type = src_type & (~(dst_type));
00206   add_type = (~(src_type)) & dst_type;
00207 
00208   /* vector layout for exclusion*/
00209   pb[0] = 0;
00210   if ((src_type & F_ENERGY) && (src_type & F_ZEROTH)){
00211     p0[0] = basenum;
00212     pe[0] = basenum + 1;
00213     len = basenum + 2;
00214   } else if ((src_type & F_ENERGY) || (src_type & F_ZEROTH)){
00215     p0[0] = pe[0] = basenum;
00216     len = basenum + 1;
00217   } else {
00218     p0[0] = pe[0] = 0;
00219     len = basenum;
00220   }
00221   for (i=1;i<3;i++) {
00222     pb[i] = pb[i-1] + len;
00223     pe[i] = pe[i-1] + len;
00224     p0[i] = p0[i-1] + len;
00225   }
00226   if (src_type & F_ENERGY_SUP) {
00227     pe[0] = 0;
00228     for (i=1;i<3;i++) {
00229       pb[i]--;
00230       pe[i]--;
00231       p0[i]--;
00232     }
00233   }
00234   
00235   /* modification begin */
00236   /* qualifier addition: "_N" */
00237 #ifdef DEBUG
00238   buf[0] = '\0';
00239   printf("try to add: %s\n", param_qualcode2str(buf, add_type, FALSE));
00240 #endif
00241   
00242   if (add_type & F_ENERGY_SUP) {
00243     if (src_type & F_ENERGY) {
00244       mark_exclude_vector(pe[0], 1, vmark, vlen);
00245       src_type = src_type | F_ENERGY_SUP;
00246     } else if (src_type & F_ZEROTH) {
00247       mark_exclude_vector(p0[0], 1, vmark, vlen);
00248       src_type = src_type | F_ENERGY_SUP;
00249     } else {
00250       jlog("Warning: paramselect: \"_N\" needs \"_E\" or \"_0\". ignored\n");
00251     }
00252     add_type = add_type & (~(F_ENERGY_SUP)); /* set to 0 */
00253   }
00254   if (add_type != 0) {          /* others left */
00255     buf[0] = '\0';
00256     jlog("Warning: paramselect: can do only parameter exclusion. qualifiers %s ignored\n", param_qualcode2str(buf, add_type, FALSE));
00257   }
00258   
00259   /* qualifier excludeion: "_D","_A","_0","_E" */
00260 #ifdef DEBUG
00261   buf[0] = '\0';
00262   printf("try to del: %s\n", param_qualcode2str(buf, del_type, FALSE));
00263 #endif
00264 
00265   if (del_type & F_DELTA) del_type |= F_ACCL;
00266   /* mark delete vector */
00267   if (del_type & F_ACCL) {
00268     mark_exclude_vector(pb[2], len, vmark, vlen);
00269     src_type &= ~(F_ACCL);
00270     del_type &= ~(F_ACCL);
00271   }
00272   if (del_type & F_DELTA) {
00273     mark_exclude_vector(pb[1], len, vmark, vlen);
00274     src_type &= ~(F_DELTA);
00275     del_type &= ~(F_DELTA);
00276   }
00277   
00278   if (del_type & F_ENERGY) {
00279     mark_exclude_vector(pe[2], 1, vmark, vlen);
00280     mark_exclude_vector(pe[1], 1, vmark, vlen);
00281     if (!(src_type & F_ENERGY_SUP)) {
00282       mark_exclude_vector(pe[0], 1, vmark, vlen);
00283     }
00284     src_type &= ~(F_ENERGY | F_ENERGY_SUP);
00285     del_type &= ~(F_ENERGY | F_ENERGY_SUP);
00286   }
00287   if (del_type & F_ZEROTH) {
00288     mark_exclude_vector(p0[2], 1, vmark, vlen);
00289     mark_exclude_vector(p0[1], 1, vmark, vlen);
00290     if (!(src_type & F_ENERGY_SUP)) {
00291       mark_exclude_vector(p0[0], 1, vmark, vlen);
00292     }
00293     src_type &= ~(F_ZEROTH | F_ENERGY_SUP);
00294     del_type &= ~(F_ZEROTH | F_ENERGY_SUP);
00295   }
00296   
00297   if (del_type != 0) {          /* left */
00298     buf[0] = '\0';
00299     jlog("Warning: paramselect: cannot exclude qualifiers %s. selection ignored\n", param_qualcode2str(buf, del_type, FALSE));
00300   }
00301 
00302 
00303   *new_type = src_type;
00304 
00305   return(TRUE);
00306 }
00307 
00308 
00318 static boolean
00319 select_param_kind(HTK_Param *p, short dst_type_arg)
00320 {
00321   int *vmark;
00322   int vlen;
00323   int i;
00324   short new_type;
00325 
00326   /* prepare work area */
00327   vmark = (int *)mymalloc(sizeof(int) * p->veclen);
00328   vlen = p->veclen;
00329   for (i=0;i<vlen;i++) {
00330     vmark[i] = 0;
00331   }
00332 
00333   /* mark to determine operation */
00334   if (select_param_vmark(p, dst_type_arg, vmark, vlen, &new_type) == FALSE) return(FALSE);
00335   /* execute deletion (copy needed to new param)*/
00336   exec_exclude_vectors(p, vmark);
00337   
00338   /* copy & set header info */
00339   p->header.sampsize = p->veclen * sizeof(VECT);
00340   p->header.samptype = new_type | (p->header.samptype & F_BASEMASK);
00341   
00342 #ifdef DEBUG
00343  {
00344    char pbuf[80];
00345    printf("new param made: %s\n", param_code2str(pbuf, p->header.samptype, FALSE));
00346  }
00347 #endif
00348   
00349   /* free work area */
00350   free(vmark);
00351 
00352   return(TRUE);
00353 }
00354 
00370 int
00371 param_check_and_adjust(HTK_HMM_INFO *hmminfo, HTK_Param *param, boolean vflag)
00372 {
00373   char pbuf[80],hbuf[80];
00374   
00375   param_code2str(pbuf, (short)(param->header.samptype & ~(F_COMPRESS | F_CHECKSUM)), FALSE);
00376   param_code2str(hbuf, hmminfo->opt.param_type, FALSE);  
00377   if (!check_param_basetype(hmminfo, param)) {
00378     /* error if base type not match */
00379     jlog("Error: paramselect: incompatible parameter type\n");
00380     jlog("Error: paramselect:  HMM   trained   by  %s(%d)\n", hbuf, hmminfo->opt.vec_size);
00381     jlog("Error: paramselect:  input parameter is  %s(%d)\n", pbuf, param->veclen);
00382     return -1;
00383   }
00384   if (!check_param_coherence(hmminfo, param)) {
00385     /* try to select needed parameter vector */
00386     if (vflag) jlog("Stat: paramselect: attaching %s\n", pbuf);
00387     if (select_param_kind(param, hmminfo->opt.param_type) == FALSE) {
00388       if (vflag) jlog("Error: paramselect: failed to attach to %s\n", hbuf);
00389 
00390       jlog("Error: paramselect: incompatible parameter type\n");
00391       jlog("Error: paramselect:  HMM   trained   by  %s(%d)\n", hbuf, hmminfo->opt.vec_size);
00392       jlog("Error: paramselect:  input parameter is  %s(%d)\n", pbuf, param->veclen);
00393       return -1;
00394     }
00395     param_code2str(pbuf, param->header.samptype, FALSE);
00396     if (vflag) jlog("Stat: paramselect: attached to %s\n", pbuf);
00397     return(1);
00398   }
00399   return(0);
00400 }