// Copyright (C) 1998-1999 Jean-Marc Valin #include "gmm.h" #include #include #include "vec.h" #ifdef HAVE_VALUES_H #include #endif #ifdef HAVE_FLOAT_H #include #endif using namespace std; namespace FD { DECLARE_TYPE(GMM) //@implements GMM //@require DGMM void GMM::init(vector frames) { for (unsigned int i=0;ireset_to_accum_mode(); apriori[i]=0; } mode = accum; } void GMM::kmeans2(vector frames, GMM *gmm) { vector scores; scores = gmm->minDistance(frames); //scores = gmm->score(frames); reset_to_accum_mode(); unsigned int i; for (i=0;iget_accum_count()==0) { //cerr << "accum zero\n"; accum_to_gaussian(i, (frames[rand()%frames.size()])); } to_real(); } void GMM::adaptMAP(vector frames, GMM *gmm) { /*dimensions = gmm->dimensions; apriori = gmm->apriori; //(vector(nb_gauss,0.0)) nb_gaussians = gmm->nb_gaussians; mode = real; nb_frames_aligned=0; using_gaussianIDs = false; //for (int i=0;i (new Gaussian(dimensions, NewDiagonalCovariance))); */ vector scores; //scores = gmm->minDistance(frames); scores = gmm->score(frames); //reset_to_accum_mode(); for (int i=0;i adaptMean(dimensions, 0); for (int j=0;j 1) weight = 1; #else float weight = float(adaptCount)/(float(adaptCount)+15); #endif //weight=0; Vector &mean = *gaussians[i]->mean; for (int j=0;j (new Gaussian(*(gaussians[i]))); //gaussians[i]. //perform adaptation } } void GMM::kmeans1(vector frames, int nb_iterations) { for (int i=0;iget_accum_count(); gaussians.resize(nb_gaussians+1); apriori.resize(nb_gaussians+1); for (int i=1;iget_accum_count(); if (accum>max_accum) { max_gauss=i; max_accum=accum; } } //cout << "spliting " << max_gauss << endl; gaussians[nb_gaussians]= RCPtr (new Gaussian(*(gaussians[max_gauss]))); Vector &mean = gaussians[nb_gaussians]->getMean(); for (unsigned int j=0;j (new Gaussian(*(gaussians[i]))); Vector &mean = gaussians[i+old_size]->getMean(); for (unsigned int j=0;jto_real(); } for (int j=0;j (&_cov); if (!cov) throw new GeneralException("Covariance not diagonal in GMM::createDiagGMM()", __FILE__, __LINE__); /* Covariance normalization float norm = 0; for (int i=0;i GMM::minDistance(vector fr) const { unsigned int i,j; Covariance *cov = new DiagonalCovariance (dimensions); for (j=0;jget_accum_count()/(*(gaussians[i]->covariance))[j]; cov_count += gaussians[i]->get_accum_count(); } for (j=0;jmode = (Covariance::inverted); vector scores(fr.size()); for (i=0;i GMM::score(vector fr) const { vector scores(fr.size()); for (unsigned int i=0;ieuclidian(fr); float dist = gaussians[j]->mahalanobis(fr,cov); if (dist < min_dist) { min_dist=dist; min_gauss = j; } //cerr << "mean " << j << ": " << dist << endl; } frame_score.score = min_dist; frame_score.gaussian_id = min_gauss; frame_score.gmm = this; frame_score.frame = fr; return frame_score; } Score GMM::score(float * fr) const { float min_dist = FLT_MAX ; int min_gauss = 0; Score frame_score; for (int j=0;j (&_cov); if (!cov) throw new GeneralException("Covariance not diagonal in GMM::createDiagGMM()", __FILE__, __LINE__); float norm = 0; for (int i=0;imahalanobis(fr)-apriori[j]-norm; */ float dist = gaussians[j]->mahalanobis(fr)-apriori[j]; //cerr << "apriori[j]: " << apriori[j] << endl; if (dist < min_dist) { min_dist=dist; min_gauss = j; } //cerr << "mean " << j << ": " << dist << " " << apriori[j] << endl; } frame_score.score = min_dist; frame_score.gaussian_id = min_gauss; frame_score.gmm = this; frame_score.frame = fr; return frame_score; } void GMM::toIDsUsing (GaussianSet &gauss) { if (using_gaussianIDs) return; gaussianIDs.resize(nb_gaussians); using_gaussianIDs=true; for (int i=0;idim = dimensions; dg->nbGauss = nb_gaussians; dg->augDim = (dimensions+4)&0xfffffffc; int allocSize = 2 * dg->augDim * dg->nbGauss * sizeof(float) + CACHE_LINES; //allocSize += dg->augDim * sizeof(float); dg->ptr = new char [allocSize]; dg->base = (float *) (((unsigned long)(dg->ptr) + (CACHE_LINES-1))&CACHE_MASK); float *ptr = dg->base; for (int k=0;k (&_cov); if (!cov) throw new GeneralException("Covariance not diagonal in GMM::createDiagGMM()", __FILE__, __LINE__); for (int i=0;iaugDim;i++) ptr[i]=0; ptr += dg->augDim; float norm = 0; for (int i=0;iaugDim;i++) ptr[i]=0; ptr += dg->augDim; } return dg; } void GMM::printOn(ostream &out) const { out << "" << endl; out << "" << endl; out << "" << endl; out << "" << endl; out << "" << endl; if (using_gaussianIDs) out << "" << endl; else out << "" << endl; out << ">\n"; } void GMM::readFrom (istream &in) { string tag; while (1) { char ch; in >> ch; if (ch == '>') break; else if (ch != '<') throw new ParsingException ("GMM::readFrom : Parse error: '<' expected"); in >> tag; if (tag == "nb_gaussians") in >> nb_gaussians; else if (tag == "apriori") in >> apriori; else if (tag == "dimensions") in >> dimensions; else if (tag == "gaussians") { in >> gaussians; using_gaussianIDs = false; } else if (tag == "gaussianIDs") { in >> gaussianIDs; using_gaussianIDs = true; } else if (tag == "mode") in >> mode; else if (tag == "nb_frames_aligned") in >> nb_frames_aligned; else throw new ParsingException ("GMM::readFrom : unknown argument: " + tag); if (!in) throw new ParsingException ("GMM::readFrom : Parse error trying to build " + tag); in >> tag; if (tag != ">") throw new ParsingException ("GMM::readFrom : Parse error: '>' expected "); } } istream &operator >> (istream &in, GMM &gmm) { if (!isValidType(in, "GMM")) return in; gmm.readFrom(in); return in; } }//namespace FD