示例#1
0
文件: _gmm.c 项目: 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);
}
示例#2
0
文件: _gmm.c 项目: EQ4/SPTK
int load_GMM(GMM * gmm, FILE * fp)
{
   int m, l;

   freadf(gmm->weight, sizeof(*(gmm->weight)), gmm->nmix, fp);
   for (m = 0; m < gmm->nmix; m++) {
      freadf(gmm->gauss[m].mean, sizeof(*(gmm->gauss[m].mean)), gmm->dim, fp);

      if (gmm->full != TR) {
         freadf(gmm->gauss[m].var, sizeof(*(gmm->gauss[m].var)), gmm->dim, fp);
         gmm->gauss[m].gconst = cal_gconst(gmm->gauss[m].var, gmm->dim);
      } else {
         for (l = 0; l < gmm->dim; l++) {
            freadf(gmm->gauss[m].cov[l],
                   sizeof(*(gmm->gauss[m].cov[l])), gmm->dim, fp);
         }
      }
   }

   return (0);
}
示例#3
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);
}