int shortemcluster_org(int n,int p,int k,double *pi,double **X,double **Mu, double **LTSigma,int maxiter,double eps,double *llhdval) { int iter; double **gamm,llhd,oldllhd,llh0; /*same as emcluster, only difference being in how convergence is handled, done as per Biernacki et al*/ MAKE_MATRIX(gamm,n,k); llhd=lnlikelihood(n,p,k,pi,X,Mu,LTSigma); llh0=llhd; iter=0; do { oldllhd=llhd; estep(n,p,k,X,gamm,pi,Mu,LTSigma); mstep(X,n,p,k,pi,Mu,LTSigma,gamm); llhd=lnlikelihood(n,p,k,pi,X,Mu,LTSigma); iter++; } while (((oldllhd-llhd)/(llh0-llhd) > eps) && (iter<maxiter)); /* Marked by Wei-Chen Chen on 2009/01/21. This value, (oldllhd-llhd)/(llhd-llh0), is always negative. } while ((((oldllhd-llhd)/(llhd-llh0)) > eps) && (iter<maxiter)); */ (*llhdval)=llhd; FREE_MATRIX(gamm); return iter; }
void mixMarkov(vector< vector<int> >& X, int trainingNum, int numOfState, int K, vector<double>& pi, vector< vector<double> >& thetaInit, vector< vector< vector<double> > >& thetaTrans) { vector < vector< map<int, int> > > sigma; vector<double> ll_variables(3); vector< vector<double> > condProb(trainingNum); initVariable(pi, thetaInit, thetaTrans); setSigma(X, sigma, trainingNum); estep(X, pi, thetaInit, thetaTrans, condProb); ll_variables = computeLL(X, thetaInit, thetaTrans); for (iter = 1; iter<= MAX_ITER; ++iter) { mstep(pi, thetaInit, thetaTrans, condProb); estep(X, pi, thetaInit, thetaTrans, condProb); vector<double> new_ll_variables(3); new_ll_variables = computeLL(X, thetaInit, thetaTrans); //check for convergence if (new_ll_variables[0] + new_ll_variables[1] + new_ll_variables[2] - (ll_variables[0] + ll_variables[1] + ll_variables[2]) >TOL ) { ll_variables = new_ll_variables; } else { break; } } }
int shortemcluster(int n, int p, int k, double *pi, double **X, double **Mu, double **LTSigma, int maxiter, double eps, double *llhdval, int *conv_iter, double *conv_eps){ int iter, i, n_par = p * (p + 1) / 2; double *backup_pi, **backup_Mu, **backup_LTSigma; double **gamm, llhd, oldllhd, llh0; MAKE_VECTOR(backup_pi, k); MAKE_MATRIX(backup_Mu, k, p); MAKE_MATRIX(backup_LTSigma, k, n_par); MAKE_MATRIX(gamm, n, k); estep_gamma(n, p, k, X, gamm, Mu, LTSigma); llhd = lnlikelihood_gamma(n, k, gamm, pi); llh0 = llhd; iter = 0; do{ oldllhd = llhd; norm_gamma(n, k, gamm, pi); for(i = 0; i < k; i++) backup_pi[i] = pi[i]; cpy(Mu, k, p, backup_Mu); cpy(LTSigma, k, n_par, backup_LTSigma); mstep(X, n, p, k, pi, Mu, LTSigma, gamm); estep_gamma(n, p, k, X, gamm, Mu, LTSigma); llhd = lnlikelihood_gamma(n, k, gamm, pi); if(oldllhd > llhd){ for(i = 0; i < k; i++) pi[i] = backup_pi[i]; cpy(backup_Mu, k, p, Mu); cpy(backup_LTSigma, k, n_par, LTSigma); llhd = oldllhd; iter--; break; } iter++; *conv_eps = fabs((oldllhd - llhd) / (llh0 - llhd)); } while((*conv_eps > eps) && (iter < maxiter)); *llhdval = llhd; *conv_iter = iter; FREE_VECTOR(backup_pi); FREE_MATRIX(backup_Mu); FREE_MATRIX(backup_LTSigma); FREE_MATRIX(gamm); return iter; }
bool GaussianMixtureModels::train_(MatrixFloat &data){ trained = false; //Clear any previous training results det.clear(); invSigma.clear(); numTrainingIterationsToConverge = 0; if( data.getNumRows() == 0 ){ errorLog << "train_(MatrixFloat &data) - Training Failed! Training data is empty!" << std::endl; return false; } //Resize the variables numTrainingSamples = data.getNumRows(); numInputDimensions = data.getNumCols(); //Resize mu and resp mu.resize(numClusters,numInputDimensions); resp.resize(numTrainingSamples,numClusters); //Resize sigma sigma.resize(numClusters); for(UINT k=0; k<numClusters; k++){ sigma[k].resize(numInputDimensions,numInputDimensions); } //Resize frac and lndets frac.resize(numClusters); lndets.resize(numClusters); //Scale the data if needed ranges = data.getRanges(); if( useScaling ){ for(UINT i=0; i<numTrainingSamples; i++){ for(UINT j=0; j<numInputDimensions; j++){ data[i][j] = scale(data[i][j],ranges[j].minValue,ranges[j].maxValue,0,1); } } } //Pick K random starting points for the inital guesses of Mu Random random; Vector< UINT > randomIndexs(numTrainingSamples); for(UINT i=0; i<numTrainingSamples; i++) randomIndexs[i] = i; for(UINT i=0; i<numClusters; i++){ SWAP(randomIndexs[ i ],randomIndexs[ random.getRandomNumberInt(0,numTrainingSamples) ]); } for(UINT k=0; k<numClusters; k++){ for(UINT n=0; n<numInputDimensions; n++){ mu[k][n] = data[ randomIndexs[k] ][n]; } } //Setup sigma and the uniform prior on P(k) for(UINT k=0; k<numClusters; k++){ frac[k] = 1.0/Float(numClusters); for(UINT i=0; i<numInputDimensions; i++){ for(UINT j=0; j<numInputDimensions; j++) sigma[k][i][j] = 0; sigma[k][i][i] = 1.0e-2; //Set the diagonal to a small number } } loglike = 0; bool keepGoing = true; Float change = 99.9e99; UINT numIterationsNoChange = 0; VectorFloat u(numInputDimensions); VectorFloat v(numInputDimensions); while( keepGoing ){ //Run the estep if( estep( data, u, v, change ) ){ //Run the mstep mstep( data ); //Check for convergance if( fabs( change ) < minChange ){ if( ++numIterationsNoChange >= minNumEpochs ){ keepGoing = false; } }else numIterationsNoChange = 0; if( ++numTrainingIterationsToConverge >= maxNumEpochs ) keepGoing = false; }else{ errorLog << "train_(MatrixFloat &data) - Estep failed at iteration " << numTrainingIterationsToConverge << std::endl; return false; } } //Compute the inverse of sigma and the determinants for prediction if( !computeInvAndDet() ){ det.clear(); invSigma.clear(); errorLog << "train_(MatrixFloat &data) - Failed to compute inverse and determinat!" << std::endl; return false; } //Flag that the model was trained trained = true; //Setup the cluster labels clusterLabels.resize(numClusters); for(UINT i=0; i<numClusters; i++){ clusterLabels[i] = i+1; } clusterLikelihoods.resize(numClusters,0); clusterDistances.resize(numClusters,0); return true; }
void WalkRel::updateSubTaskList() { //if it's too early to calculate next step, then return Task::updateSubTaskList(); if( false==isSubTaskOfAllLessThanTwo() ) return; //... mIsWalking=true; //... bool isLeft=true; AngDeg preDir=0; shared_ptr<const Step> cStep; //current step if( !mSubTaskList.empty() ) { cStep=shared_dynamic_cast<const Step>( mSubTaskList.front() ); //get the last step if( 0!=cStep.get() ) { isLeft= !cStep->isLeft(); //change foot preDir=cStep->dir(); mPreSize=cStep->size(); // c2PreStep = cStep->getPreStep() ; //ghd // if(c2PreStep.get() !=0) // { // m2PreSize =c2PreStep ->size(); // } } } Vector2f size; //TT, for Walk and WalkRel if(mShouldStop){ return; } else{ size=mTarget*0.5; //NOTE: the real step size is double "size" } switch(FM.getMy().heteroType) { case 0 :mBodyHeight =mBodyHeight0; break; case 1 :mBodyHeight =mBodyHeight1; break; case 2 :mBodyHeight =mBodyHeight2; break; } //cout<<mGoStop<<endl; //std::cout<<size<<std::endl; shared_ptr<Task> mstep( new Step(isLeft, size, mDirection, cStep, mBodyHeight, mGoStop, this ) ); mSubTaskList.push_back(mstep); }
bool GaussianMixtureModels::train(const MatrixDouble &data,const UINT K){ modelTrained = false; failed = false; //Clear any previous training results det.clear(); invSigma.clear(); if( data.getNumRows() == 0 ){ errorLog << "train(const MatrixDouble &trainingData,const unsigned int K) - Training Failed! Training data is empty!" << endl; return false; } //Resize the variables M = data.getNumRows(); N = data.getNumCols(); this->K = K; //Resize mu and resp mu.resize(K,N); resp.resize(M,K); //Resize sigma sigma.resize(K); for(UINT k=0; k<K; k++){ sigma[k].resize(N,N); } //Resize frac and lndets frac.resize(K); lndets.resize(K); //Pick K random starting points for the inital guesses of Mu Random random; vector< UINT > randomIndexs(M); for(UINT i=0; i<M; i++) randomIndexs[i] = i; for(UINT i=0; i<M; i++){ SWAP(randomIndexs[ random.getRandomNumberInt(0,M) ],randomIndexs[ random.getRandomNumberInt(0,M) ]); } for(UINT k=0; k<K; k++){ for(UINT n=0; n<N; n++){ mu[k][n] = data[ randomIndexs[k] ][n]; } } //Setup sigma and the uniform prior on P(k) for(UINT k=0; k<K; k++){ frac[k] = 1.0/double(K); for(UINT i=0; i<N; i++){ for(UINT j=0; j<N; j++) sigma[k][i][j] = 0; sigma[k][i][i] = 1.0e-10; //Set the diagonal to a small number } } loglike = 0; UINT iterCounter = 0; bool keepGoing = true; double change = 99.9e99; while( keepGoing ){ change = estep( data ); mstep( data ); if( fabs( change ) < minChange ) keepGoing = false; if( ++iterCounter >= maxIter ) keepGoing = false; if( failed ) keepGoing = false; } if( failed ){ errorLog << "train(UnlabelledClassificationData &trainingData,unsigned int K) - Training failed!" << endl; return modelTrained; } //Compute the inverse of sigma and the determinants for prediction if( !computeInvAndDet() ){ det.clear(); invSigma.clear(); errorLog << "train(UnlabelledClassificationData &trainingData,unsigned int K) - Failed to compute inverse and determinat!" << endl; return false; } //Flag that the model was trained modelTrained = true; return true; }
bool KMeans::trainModel(MatrixFloat &data){ if( numClusters == 0 ){ errorLog << "trainModel(MatrixFloat &data) - Failed to train model. NumClusters is zero!" << std::endl; return false; } if( clusters.getNumRows() != numClusters ){ errorLog << "trainModel(MatrixFloat &data) - Failed to train model. The number of rows in the cluster matrix does not match the number of clusters! You should need to initalize the clusters matrix first before calling this function!" << std::endl; return false; } if( clusters.getNumCols() != numInputDimensions ){ errorLog << "trainModel(MatrixFloat &data) - Failed to train model. The number of columns in the cluster matrix does not match the number of input dimensions! You should need to initalize the clusters matrix first before calling this function!" << std::endl; return false; } Timer timer; UINT currentIter = 0; UINT numChanged = 0; bool keepTraining = true; Float theta = 0; Float lastTheta = 0; Float delta = 0; Float startTime = 0; thetaTracker.clear(); finalTheta = 0; numTrainingIterationsToConverge = 0; trained = false; converged = false; //Scale the data if needed ranges = data.getRanges(); if( useScaling ){ data.scale(0,1); } //Init the assign and count Vectors //Assign is set to K+1 so that the nChanged values in the eStep at the first iteration will be updated correctly for(UINT m=0; m<numTrainingSamples; m++) assign[m] = numClusters+1; for(UINT k=0; k<numClusters; k++) count[k] = 0; //Run the training loop timer.start(); while( keepTraining ){ startTime = timer.getMilliSeconds(); //Compute the E step numChanged = estep( data ); //Compute the M step mstep( data ); //Update the iteration counter currentIter++; //Compute theta if needed if( computeTheta ){ theta = calculateTheta(data); delta = lastTheta - theta; lastTheta = theta; }else theta = delta = 0; //Check convergance if( numChanged == 0 && currentIter > minNumEpochs ){ converged = true; keepTraining = false; } if( currentIter >= maxNumEpochs ){ keepTraining = false; } if( fabs( delta ) < minChange && computeTheta && currentIter > minNumEpochs ){ converged = true; keepTraining = false; } if( computeTheta ) thetaTracker.push_back( theta ); trainingLog << "Epoch: " << currentIter << "/" << maxNumEpochs; trainingLog << " Epoch time: " << (timer.getMilliSeconds()-startTime)/1000.0 << " seconds"; trainingLog << " Theta: " << theta << " Delta: " << delta << std::endl; } trainingLog << "Model Trained at epoch: " << currentIter << " with a theta value of: " << theta << std::endl; finalTheta = theta; numTrainingIterationsToConverge = currentIter; trained = true; //Setup the cluster labels clusterLabels.resize(numClusters); for(UINT i=0; i<numClusters; i++){ clusterLabels[i] = i+1; } clusterLikelihoods.resize(numClusters,0); clusterDistances.resize(numClusters,0); return true; }
/* This function calls mstep() in "src/emcluster.c" and is called by m.step() using .Call() in "R/fcn_m_step.r". Input: R_x: SEXP[R_n * R_p], data matrix of R_n*R_p. R_n: SEXP[1], number of observations. R_p: SEXP[1], number of dimersions. R_nclass: SEXP[1], number of classes. # k R_Gamma: SEXP[R_n, R_p], posterios matrix of R_n*R_p. Output: ret: a list contains pi: SEXP[R_nclass], proportions of classes. Mu: SEXP[R_nclass, R_p], means of MVNs. LTSigma: SEXP[R_nclass, R_p * (R_p + 1) / 2], lower triangular sigma matrices. */ SEXP R_mstep(SEXP R_x, SEXP R_n, SEXP R_p, SEXP R_nclass, SEXP R_Gamma){ /* Declare variables for calling C. */ double **C_Gamma, **C_x, *C_pi, **C_Mu, **C_LTSigma; int *C_n, *C_p, *C_nclass; /* Declare variables for R's returning. */ SEXP pi, Mu, LTSigma, ret, ret_names; /* Declare variables for processing. */ double *tmp_1, *tmp_2; int i, p_LTSigma; char *names[3] = {"pi", "Mu", "LTSigma"}; /* Set initial values. */ C_n = INTEGER(R_n); C_p = INTEGER(R_p); C_nclass = INTEGER(R_nclass); p_LTSigma = *C_p * (*C_p + 1) / 2; /* Allocate and protate storages. */ PROTECT(pi = allocVector(REALSXP, *C_nclass)); PROTECT(Mu = allocVector(REALSXP, *C_nclass * *C_p)); PROTECT(LTSigma = allocVector(REALSXP, *C_nclass * p_LTSigma)); PROTECT(ret = allocVector(VECSXP, 3)); PROTECT(ret_names = allocVector(STRSXP, 3)); i = 0; SET_VECTOR_ELT(ret, i++, pi); SET_VECTOR_ELT(ret, i++, Mu); SET_VECTOR_ELT(ret, i++, LTSigma); for(i = 0; i < 3; i++){ SET_STRING_ELT(ret_names, i, mkChar(names[i])); } setAttrib(ret, R_NamesSymbol, ret_names); /* Assign data. */ C_Gamma = allocate_double_array(*C_n); C_x = allocate_double_array(*C_n); C_Mu = allocate_double_array(*C_nclass); C_LTSigma = allocate_double_array(*C_nclass); tmp_1 = REAL(R_Gamma); tmp_2 = REAL(R_x); for(i = 0; i < *C_n; i++){ C_Gamma[i] = tmp_1; C_x[i] = tmp_2; tmp_1 += *C_nclass; tmp_2 += *C_p; } tmp_1 = REAL(Mu); tmp_2 = REAL(LTSigma); for(i = 0; i < *C_nclass; i++){ C_Mu[i] = tmp_1; C_LTSigma[i] = tmp_2; tmp_1 += *C_p; tmp_2 += p_LTSigma; } C_pi = REAL(pi); /* Compute. */ mstep(C_x, *C_n, *C_p, *C_nclass, C_pi, C_Mu, C_LTSigma, C_Gamma); /* Free memory and release protectation. */ free(C_Gamma); free(C_x); free(C_Mu); free(C_LTSigma); UNPROTECT(5); return(ret); } /* End of R_mstep(). */