Esempio n. 1
0
File: _gmm.c Progetto: EQ4/SPTK
int prepareGconst_GMM(GMM * gmm)
{
   int m;

   for (m = 0; m < gmm->nmix; m++) {
      if (gmm->full == FA) {
         gmm->gauss[m].gconst = cal_gconst(gmm->gauss[m].var, gmm->dim);
      } else {
         gmm->gauss[m].gconst = cal_gconstf(gmm->gauss[m].cov, gmm->dim);
      }
      if (gmm->gauss[m].gconst == 0) {
         return -1;
      }
   }

   return (0);
}
Esempio n. 2
0
int main(int argc, char **argv)
{
   FILE *fp = stdin;
   GMM gmm, tgmm, floor;
   double E = DEF_E, V = DEF_V, W = DEF_W,
       *dat, *pd, *cb, *icb, *logwgd, logb, *sum, *sum_m, **sum_v, diff, sum_w,
       ave_logp0, ave_logp1, change = MAXVALUE, tmp1, tmp2;
   int ispipe, l, ll, L = DEF_L, m, M = DEF_M, N, t, T = DEF_T, S =
       DEF_S, full = FULL, n1, i, j, Imin = DEF_IMIN, Imax =
       DEF_IMAX, *tindex, *cntcb;


   if ((cmnd = strrchr(argv[0], '/')) == NULL)
      cmnd = argv[0];
   else
      cmnd++;

   /* --  Check options -- */
   while (--argc)
      if (**++argv == '-') {
         switch (*(*argv + 1)) {
         case 'h':
            usage(0);
            break;
         case 'l':
            L = atoi(*++argv);
            --argc;
            break;
         case 'm':
            M = atoi(*++argv);
            --argc;
            break;
         case 't':
            T = atoi(*++argv);
            --argc;
            break;
         case 's':
            S = atoi(*++argv);
            --argc;
            break;
         case 'a':
            Imin = atoi(*++argv);
            --argc;
            break;
         case 'b':
            Imax = atoi(*++argv);
            --argc;
            break;
         case 'e':
            E = atof(*++argv);
            --argc;
            break;
         case 'v':
            V = atof(*++argv);
            --argc;
            break;
         case 'w':
            W = atof(*++argv);
            --argc;
            break;
         case 'f':
            full = 1 - full;
            break;
         default:
            fprintf(stderr, "%s: Illegal option \"%s\".\n", cmnd, *argv);
            usage(1);
         }
      } else
         fp = getfp(*argv, "rb");


   /* -- Count number of training vectors -- */
   if (T == -1) {
      ispipe = fseek(fp, 0L, SEEK_END);
      T = (int) (ftell(fp) / (double) L / (double) sizeof(float));
      rewind(fp);

      if (ispipe == -1) {       /* training data is from standard input via pipe */
         fprintf(stderr,
                 "\n %s (Error) -t option must be specified for the standard input via pipe.\n",
                 cmnd);
         usage(1);
      }
   }

   /* Memory allocation */
   /* Training data */
   dat = dgetmem(T * L);

   /* for VQ */
   N = 1;
   while (N < M)
      N *= 2;
   cb = dgetmem(N * L);
   icb = dgetmem(L);
   tindex = (int *) getmem(T, sizeof(int));
   cntcb = (int *) getmem(M, sizeof(int));

   /* GMM */
   gmm.weight = dgetmem(M);
   gmm.gauss = (Gauss *) getmem(M, sizeof(Gauss));

   for (m = 0; m < M; m++) {
      gmm.gauss[m].mean = dgetmem(L);
      gmm.gauss[m].var = dgetmem(L);

      if (full == 1) {
         gmm.gauss[m].cov = (double **) malloc(sizeof(double *) * L);
         gmm.gauss[m].inv = (double **) malloc(sizeof(double *) * L);
         for (l = 0; l < L; l++) {
            gmm.gauss[m].cov[l] = dgetmem(L);
            gmm.gauss[m].inv[l] = dgetmem(L);
         }
      }
   }

   if (full == 1) {
      floor.gauss = (Gauss *) getmem(1, sizeof(Gauss));
      floor.gauss[0].cov = (double **) malloc(sizeof(double *) * L);
      for (l = 0; l < L; l++)
         floor.gauss[0].cov[l] = dgetmem(L);
      sum_m = dgetmem(L);
      sum_v = (double **) malloc(sizeof(double *) * L);
   }
   /* temporary */
   tgmm.weight = dgetmem(M);
   tgmm.gauss = (Gauss *) getmem(M, sizeof(Gauss));

   for (m = 0; m < M; m++) {
      tgmm.gauss[m].mean = dgetmem(L);
      tgmm.gauss[m].var = dgetmem(L);

      if (full == 1) {
         tgmm.gauss[m].cov = (double **) malloc(sizeof(double *) * L);
         tgmm.gauss[m].inv = (double **) malloc(sizeof(double *) * L);
         for (l = 0; l < L; l++) {
            tgmm.gauss[m].cov[l] = dgetmem(L);
            tgmm.gauss[m].inv[l] = dgetmem(L);
         }
      }
   }

   logwgd = dgetmem(M);
   sum = dgetmem(M);

   /*  Read training data */
   freadf(dat, sizeof(*dat), T * L, fp);

   /* Initialization of GMM parameters */
   /* LBG */
   vaverage(dat, L, T, icb);
   lbg(dat, L, T, icb, 1, cb, N, ITER, MINTRAIN, S, CENTUP, DELTA, END);

   for (t = 0, pd = dat; t < T; t++, pd += L) {
      tindex[t] = vq(pd, cb, L, M);
      cntcb[tindex[t]]++;
   }

   for (m = 0; m < M; m++)
      if (cntcb[m] == 0) {
         fprintf(stderr, "Error: No data for mixture No.%d\n", m);
         usage(1);
      }

   fprintf(stderr, "T = %d  L = %d  M = %d\n", T, L, M);

   /* flooring value for weights */
   W = 1.0 / (double) M *(double) W;

   /* weights */
   for (m = 0, sum_w = 0.0; m < M; m++) {
      gmm.weight[m] = (double) cntcb[m] / (double) T;
      if (gmm.weight[m] < W)
         gmm.weight[m] = W;
      sum_w += gmm.weight[m];
   }
   if (sum_w != 1.0)
      for (m = 0; m < M; m++)
         gmm.weight[m] /= sum_w;


   /* mean */
   for (m = 0, pd = cb; m < M; m++, pd += L)
      movem(pd, gmm.gauss[m].mean, sizeof(double), L);


   /* variance */
   if (full != 1) {
      for (t = 0, pd = dat; t < T; t++, pd += L)
         for (l = 0; l < L; l++) {
            diff = gmm.gauss[tindex[t]].mean[l] - pd[l];
            gmm.gauss[tindex[t]].var[l] += sq(diff);
         }

      for (m = 0; m < M; m++)
         for (l = 0; l < L; l++) {
            gmm.gauss[m].var[l] /= (double) cntcb[m];
            if (gmm.gauss[m].var[l] < V)
               gmm.gauss[m].var[l] = V;
         }

      for (m = 0; m < M; m++)
         gmm.gauss[m].gconst = cal_gconst(gmm.gauss[m].var, L);
   }
   /* full covariance */
   else {
      for (t = 0, pd = dat; t < T; t++, pd += L) {
         for (l = 0; l < L; l++) {
            for (i = 0; i <= l; i++) {
               if (l == i) {
                  diff =
                      (gmm.gauss[tindex[t]].mean[l] -
                       pd[l]) * (gmm.gauss[tindex[t]].mean[i] - pd[i]);
                  floor.gauss[0].cov[l][i] += diff;
               }
            }
         }
      }

      for (l = 0; l < L; l++) {
         for (i = 0; i <= l; i++) {
            if (l == i) {
               floor.gauss[0].cov[l][i] /= T;
               floor.gauss[0].cov[l][i] *= V;
            }
         }
      }

      for (t = 0, pd = dat; t < T; t++, pd += L) {
         for (l = 0; l < L; l++) {
            for (i = 0; i <= l; i++) {
               diff =
                   (gmm.gauss[tindex[t]].mean[l] -
                    pd[l]) * (gmm.gauss[tindex[t]].mean[i] - pd[i]);
               gmm.gauss[tindex[t]].cov[l][i] += diff;
            }
         }
      }

      for (m = 0; m < M; m++)
         for (l = 0; l < L; l++)
            for (i = 0; i <= l; i++) {
               gmm.gauss[m].cov[l][i] /= (double) cntcb[m];
            }
   }

   /* EM training of GMM parameters */
   for (i = 0; (i <= Imax) && ((i <= Imin) || (fabs(change) > E)); i++) {
      if (full != 1)
         fillz_gmm(&tgmm, M, L);
      else
         fillz_gmmf(&tgmm, M, L);
      fillz(sum, sizeof(double), M);

      if (full != 1) {
         for (m = 0; m < M; m++)
            gmm.gauss[m].gconst = cal_gconst(gmm.gauss[m].var, L);
      } else {
         for (m = 0, n1 = 0; m < M; m++) {
            gmm.gauss[m].gconst = cal_gconstf(gmm.gauss[m].cov, L);

            if (gmm.gauss[m].gconst == 0) {
               n1++;
               for (l = 0; l < L; l++)
                  gmm.gauss[m].cov[l][l] += floor.gauss[0].cov[l][l];
               gmm.gauss[m].gconst = cal_gconstf(gmm.gauss[m].cov, L);
            }
            if (gmm.gauss[m].gconst == 0) {
               fprintf(stderr, "ERROR : Can't caluculate covdet");
               exit(EXIT_FAILURE);
            }

            /* calculate inv */
            cal_inv(gmm.gauss[m].cov, gmm.gauss[m].inv, L);
         }
      }
      if (full == 1)
         fprintf(stderr, "%d cov can't caluculate covdet\n", n1);

      for (t = 0, ave_logp1 = 0.0, pd = dat; t < T; t++, pd += L) {
         for (m = 0, logb = LZERO; m < M; m++) {
            if (full != 1) {
               logwgd[m] = log_wgd(&gmm, m, pd, L);
               logb = log_add(logb, logwgd[m]);
            }
            /* full */
            else {
               logwgd[m] = log_wgdf(&gmm, m, pd, L);
               logb = log_add(logb, logwgd[m]);
            }
         }
         ave_logp1 += logb;

         for (m = 0; m < M; m++) {
            tmp1 = exp(logwgd[m] - logb);
            sum[m] += tmp1;

            for (l = 0; l < L; l++) {
               tmp2 = tmp1 * pd[l];
               tgmm.gauss[m].mean[l] += tmp2;
               if (full != 1)
                  tgmm.gauss[m].var[l] += tmp2 * pd[l];
               else {
                  for (j = 0; j <= l; j++) {
                     tgmm.gauss[m].cov[l][j] +=
                         tmp1 * (pd[l] - gmm.gauss[m].mean[l]) * (pd[j] -
                                                                  gmm.
                                                                  gauss[m].mean
                                                                  [j]);
                  }
               }
            }
         }
      }

      /* Output average log likelihood at each iteration */
      ave_logp1 /= (double) T;
      if (i == 1 && m == 1)
         ave_logp0 = ave_logp1;

      fprintf(stderr, "iter %3d : ", i);
      fprintf(stderr, "ave_logprob = %g", ave_logp1);
      if (i) {
         change = ave_logp1 - ave_logp0;
         fprintf(stderr, "  change = %g", change);
      }
      fprintf(stderr, "\n");
      ave_logp0 = ave_logp1;

      /* Update perameters */
      /* weights */
      for (m = 0; m < M; m++)
         gmm.weight[m] = sum[m] / (double) T;

      /* mean, variance */
      for (m = 0; m < M; m++) {
         for (l = 0; l < L; l++)
            gmm.gauss[m].mean[l] = tgmm.gauss[m].mean[l] / sum[m];

         if (full != 1) {
            for (l = 0; l < L; l++) {
               gmm.gauss[m].var[l] =
                   tgmm.gauss[m].var[l] / sum[m] - sq(gmm.gauss[m].mean[l]);
               if (gmm.gauss[m].var[l] < V)
                  gmm.gauss[m].var[l] = V;
            }
         }
         /* full */
         else {
            for (l = 0; l < L; l++) {
               for (j = 0; j <= l; j++) {
                  gmm.gauss[m].cov[l][j] = tgmm.gauss[m].cov[l][j] / sum[m];
               }
            }
         }
      }
   }

   /*  Output GMM parameters */
   fwritef(gmm.weight, sizeof(double), M, stdout);
   if (full != 1) {
      for (m = 0; m < M; m++) {
         fwritef(gmm.gauss[m].mean, sizeof(double), L, stdout);
         fwritef(gmm.gauss[m].var, sizeof(double), L, stdout);
      }
   } else {
      for (m = 0; m < M; m++) {
         fwritef(gmm.gauss[m].mean, sizeof(double), L, stdout);
         for (i = 0; i < L; i++)
            for (j = 0; j < i; j++)
               gmm.gauss[m].cov[j][i] = gmm.gauss[m].cov[i][j];
         for (l = 0; l < L; l++)
            fwritef(gmm.gauss[m].cov[l], sizeof(double), L, stdout);
      }
   }
   return (0);
}
Esempio n. 3
0
File: _vc.c Progetto: EQ4/SPTK
/* perform conversion */
int vc(const GMM * gmm, const DELTAWINDOW * window, const size_t total_frame,
       const size_t source_vlen, const size_t target_vlen,
       const double *gv_mean, const double *gv_vari,
       const double *source, double *target)
{
    size_t t, i, j, k, max_num_mix = 0,
                       src_vlen_dyn = source_vlen * window->win_size,
                       tgt_vlen_dyn = target_vlen * window->win_size;
    int m, l, shift;
    double max_post_mix = 0.0, logoutp = LZERO, *input = NULL,
           *src_with_dyn = NULL, *logwgd = NULL,
            **cov_xx_inv = NULL, ***cov_yx_xx = NULL, *gv_weight = NULL,
              ***cond_mean = NULL, ***cond_vari = NULL, **cond_post_mix = NULL;
    GMM gmm_xx;
    HTS_SStreamSet sss;
    HTS_PStreamSet pss;

    /* append dynamic feature */
    src_with_dyn = dgetmem(total_frame * src_vlen_dyn);
    for (t = 0; t < total_frame; t++) {
        for (i = 0; i < window->win_size; i++) {
            j = window->win_size * source_vlen * t + source_vlen * i;
            for (shift = window->win_l_width[i];
                    shift <= window->win_r_width[i]; shift++) {
                l = t + shift;
                if (l < 0) {
                    l = 0;
                }
                if (!(l < (int) total_frame)) {
                    l = total_frame - 1;
                }
                for (k = 0; k < source_vlen; k++) {
                    src_with_dyn[j + k] += window->win_coefficient[i][shift]
                                           * source[source_vlen * l + k];
                }
            }
        }
    }

    /* calculate mean and covariace of conditional distribution
       given source feature and mixture component */
    cond_post_mix = ddgetmem(total_frame, gmm->nmix);
    cond_mean = (double ***) getmem(gmm->nmix, sizeof(*(cond_mean)));
    for (m = 0; m < gmm->nmix; m++) {
        cond_mean[m] = ddgetmem(total_frame, tgt_vlen_dyn);
    }
    cond_vari = (double ***) getmem(gmm->nmix, sizeof(*(cond_vari)));
    for (m = 0; m < gmm->nmix; m++) {
        cond_vari[m] = ddgetmem(tgt_vlen_dyn, tgt_vlen_dyn);
    }
    cov_xx_inv = ddgetmem(src_vlen_dyn, src_vlen_dyn);
    cov_yx_xx = (double ***) getmem(gmm->nmix, sizeof(*(cov_yx_xx)));
    for (m = 0; m < gmm->nmix; m++) {
        cov_yx_xx[m] = ddgetmem(tgt_vlen_dyn, src_vlen_dyn);
    }
    for (m = 0; m < gmm->nmix; m++) {
        invert(gmm->gauss[m].cov, cov_xx_inv, src_vlen_dyn);
        for (i = 0; i < tgt_vlen_dyn; i++) {
            for (j = 0; j < src_vlen_dyn; j++) {
                for (k = 0; k < src_vlen_dyn; k++) {
                    cov_yx_xx[m][i][j] += gmm->gauss[m].cov[src_vlen_dyn + i][k]
                                          * cov_xx_inv[k][j];
                }
            }
        }
    }
    logwgd = dgetmem(gmm->nmix);
    input = dgetmem(src_vlen_dyn);
    alloc_GMM(&gmm_xx, gmm->nmix, src_vlen_dyn, gmm->full);
    for (t = 0; t < total_frame; t++) {
        for (i = 0; i < src_vlen_dyn; i++) {
            input[i] = src_with_dyn[t * src_vlen_dyn + i];
        }
        for (i = 0; i < (size_t) gmm_xx.nmix; i++) {
            gmm_xx.weight[i] = gmm->weight[i];
            for (j = 0; j < (size_t) gmm_xx.dim; j++) {
                gmm_xx.gauss[i].mean[j] = gmm->gauss[i].mean[j];
                if (gmm_xx.full) {
                    for (k = 0; k < (size_t) gmm_xx.dim; k++) {
                        gmm_xx.gauss[i].cov[j][k] = gmm->gauss[i].cov[j][k];
                    }
                } else {
                    gmm_xx.gauss[i].var[j] = gmm->gauss[i].var[j];
                }
            }
        }
        for (i = 0; i < (size_t) gmm_xx.nmix; i++) {
            invert(gmm_xx.gauss[i].cov, gmm_xx.gauss[i].inv, src_vlen_dyn);
            gmm_xx.gauss[i].gconst =
                cal_gconstf(gmm_xx.gauss[i].cov, src_vlen_dyn);
        }
        for (m = 0, logoutp = LZERO; m < gmm->nmix; m++) {
            logwgd[m] = log_wgd(&gmm_xx, m, src_vlen_dyn, input);
            logoutp = log_add(logoutp, logwgd[m]);
        }
        for (m = 0; m < gmm->nmix; m++) {
            /* posterior probability of mixture component given source feature */
            cond_post_mix[t][m] = exp(logwgd[m] - logoutp);
            for (i = 0; i < tgt_vlen_dyn; i++) {
                for (j = 0; j < src_vlen_dyn; j++) {
                    cond_mean[m][t][i] += cov_yx_xx[m][i][j]
                                          * (input[j] - gmm->gauss[m].mean[j]);
                }
                cond_mean[m][t][i] += gmm->gauss[m].mean[src_vlen_dyn + i];
            }
        }
    }
    for (m = 0; m < gmm->nmix; m++) {
        for (i = 0; i < tgt_vlen_dyn; i++) {
            for (j = 0; j < tgt_vlen_dyn; j++) {
                for (k = 0; k < src_vlen_dyn; k++) {
                    cond_vari[m][i][j] += cov_yx_xx[m][i][k]
                                          * gmm->gauss[m].cov[k][src_vlen_dyn + j];
                }
                cond_vari[m][i][j] =
                    gmm->gauss[m].cov[src_vlen_dyn + i][src_vlen_dyn + j]
                    - cond_vari[m][i][j];
            }
        }
    }

    /* initialize parameter set of hts_engine */
    HTS_PStreamSet_initialize(&pss);
    sss.nstream = 1;
    sss.total_state = total_frame;
    sss.total_frame = total_frame;
    sss.duration = (size_t *) getmem(total_frame, sizeof(size_t));
    for (i = 0; i < total_frame; i++) {
        sss.duration[i] = 1;
    }
    sss.sstream = (HTS_SStream *) getmem(1, sizeof(HTS_SStream));
    sss.sstream->vector_length = target_vlen;
    sss.sstream->mean =
        (double **) getmem(sss.total_state, sizeof(*(sss.sstream->mean)));
    sss.sstream->vari =
        (double **) getmem(sss.total_state, sizeof(*(sss.sstream->vari)));
    for (i = 0; i < sss.total_state; i++) {
        sss.sstream->mean[i] = dgetmem(tgt_vlen_dyn);
        sss.sstream->vari[i] = dgetmem(tgt_vlen_dyn);
    }
    sss.sstream->msd = NULL;     /* no MSD */
    sss.sstream->win_size = window->win_size;
    sss.sstream->win_l_width =
        (int *) getmem(window->win_size, sizeof(*(sss.sstream->win_l_width)));
    sss.sstream->win_r_width =
        (int *) getmem(window->win_size, sizeof(*(sss.sstream->win_r_width)));
    sss.sstream->win_coefficient =
        (double **) getmem(window->win_size,
                           sizeof(*(sss.sstream->win_coefficient)));
    for (i = 0; i < window->win_size; i++) {
        sss.sstream->win_l_width[i] = window->win_l_width[i];
        sss.sstream->win_r_width[i] = window->win_r_width[i];
        if (sss.sstream->win_l_width[i] + sss.sstream->win_r_width[i] == 0) {
            sss.sstream->win_coefficient[i] =
                dgetmem(-2 * sss.sstream->win_l_width[i] + 1);
        } else {
            sss.sstream->win_coefficient[i] =
                dgetmem(-2 * sss.sstream->win_l_width[i]);
        }
        sss.sstream->win_coefficient[i] -= sss.sstream->win_l_width[i];
        for (shift = sss.sstream->win_l_width[i];
                shift <= sss.sstream->win_r_width[i]; shift++) {
            sss.sstream->win_coefficient[i][shift] =
                window->win_coefficient[i][shift];
        }
    }
    sss.sstream->win_max_width = window->win_max_width;
    if ((gv_mean != NULL) && (gv_vari != NULL)) {        /* set GV parameters */
        sss.sstream->gv_mean = dgetmem(sss.sstream->vector_length);
        sss.sstream->gv_vari = dgetmem(sss.sstream->vector_length);
        for (i = 0; i < sss.sstream->vector_length; i++) {
            sss.sstream->gv_mean[i] = gv_mean[i];
            sss.sstream->gv_vari[i] = gv_vari[i];
        }
    } else {
        sss.sstream->gv_mean = NULL;
        sss.sstream->gv_vari = NULL;
    }
    sss.sstream->gv_switch =
        (HTS_Boolean *) getmem(total_frame, sizeof(HTS_Boolean));
    for (i = 0; i < total_frame; i++) {
        sss.sstream->gv_switch[i] = TRUE;
    }
    gv_weight = dgetmem(tgt_vlen_dyn);
    for (i = 0; i < tgt_vlen_dyn; i++) {
        gv_weight[i] = 1.0;
    }

    /* initialize pdf sequence */
    for (t = 0; t < total_frame; t++) {
        max_post_mix = cond_post_mix[t][0];
        max_num_mix = 0;
        for (m = 1; m < gmm->nmix; m++) {
            if (max_post_mix < cond_post_mix[t][m]) {
                max_post_mix = cond_post_mix[t][m];
                max_num_mix = m;
            }
        }
        for (i = 0; i < tgt_vlen_dyn; i++) {
            sss.sstream->mean[t][i] = cond_mean[max_num_mix][t][i];
            sss.sstream->vari[t][i] = cond_vari[max_num_mix][i][i];
        }
    }

    /* parameter generation by hts_engine API */
    HTS_PStreamSet_create(&pss, &sss, NULL, gv_weight);
    for (t = 0; t < total_frame; t++) {
        k = t * target_vlen;
        for (i = 0; i < target_vlen; i++) {
            target[k + i] = pss.pstream->par[t][i];
        }
    }

    /* release memory */
    free(src_with_dyn);
    free(input);
    free(logwgd);
    free(cov_xx_inv[0]);
    free(cov_xx_inv);
    for (m = 0; m < gmm->nmix; m++) {
        free(cov_yx_xx[m][0]);
        free(cov_yx_xx[m]);
        free(cond_mean[m][0]);
        free(cond_mean[m]);
        free(cond_vari[m][0]);
        free(cond_vari[m]);
    }
    free(cov_yx_xx);
    free(cond_mean);
    free(cond_vari);
    free(cond_post_mix[0]);
    free(cond_post_mix);
    free(gv_weight);
    free_GMM(&gmm_xx);
    HTS_PStreamSet_clear(&pss);
    HTS_SStreamSet_clear(&sss);

    return (0);
}