double SpeechKMeans::Expectation(int utterance_index, int *correctness, vector<vector<vector<DataPoint> > > *sets) { int u = utterance_index; const ClusterProblem &cluster_problem = cluster_problems_.problem(utterance_index); const Utterance &utterance = problems_.utterance(utterance_index); // Duplicate each state for every mode. Viterbi viterbi(cluster_problem.num_states, cluster_problem.num_steps, cluster_problems_.num_modes(), 1); viterbi.Initialize(); // Set the weights based on the current centers. clock_t start = clock(); for (int mode = 0; mode < cluster_problems_.num_modes(); ++mode) { for (int i = 0; i < cluster_problem.num_states; ++i) { // const Gaussian &gaussian = gmms_[mode][cluster_problem.MapState(i)]; // for (int s = 0; s < cluster_problem.num_steps; ++s) { // double score = -gaussian.LogLikelihood(utterance.sequence(s)); // viterbi.set_transition_score(s, i, mode, score); // } const DataPoint ¢er = centers_[mode][cluster_problem.MapState(i)]; for (int s = 0; s < cluster_problem.num_steps; ++s) { double score = 0.0; for (int j = 0; j < utterance.sequence_points(s); ++j) { score += dist(center, utterance.sequence(s, j)); } viterbi.set_transition_score(s, i, mode, score); } } } cerr << "TIME: score setting " << clock() - start << endl; // Run viterbi algorithm. viterbi.ForwardScores(); double score = viterbi.GetBestPath(&path_[u], &mode_centers_[u]); (*correctness) = utterance.ScoreAlignment(path_[u]); cerr << "SCORE: Correctness: " << *correctness << endl; // Make the cluster sets. sets->resize(cluster_problems_.num_modes()); for (int mode = 0; mode < cluster_problems_.num_modes(); ++mode) { (*sets)[mode].resize(num_types_); } problems_.AlignmentClusterSet(utterance_index, path_[u], mode_centers_[u], sets); // collapse to modes. assert(path_[u].size() - 1 == (uint)cluster_problem.num_states); cerr << endl; return score; }
///////////////////////////////////////////////////////////////////////////// // // // // // Decoding // // // // // ///////////////////////////////////////////////////////////////////////////// double decode (Hmm *H) { posterior (H); viterbi (H); dump_model(H); dump_viterbi(H); dump_posterior(H); return H->PP; }
void SimpleHMMExample::run() { SimpleHMMExample::Observation o; o.push_back(0); o.push_back(1); o.push_back(2); o.push_back(3); o.push_back(4); viterbi(o); };
void decode_data(uint8_t raw[RAW_SIZE], uint8_t data[DATA_SIZE], int8_t error[2]) { uint8_t conv[CONV_SIZE]; uint8_t dec_data[RS_SIZE]; uint8_t rs[2][RS_BLOCK_SIZE]; deinterleave(raw, conv); viterbi(conv, dec_data); descramble_and_deinterleave(dec_data, rs); rs_decode(rs, data, error); }
double SpeechKMeans::GMMExpectation(int utterance_index, vector<vector<DataPoint> > &estimators, vector<vector<double> > &counts) { const ClusterProblem &cluster_problem = cluster_problems_.problem(utterance_index); const Utterance &utterance = problems_.utterance(utterance_index); // Duplicate each state for every mode. Viterbi viterbi(cluster_problem.num_states, cluster_problem.num_steps, cluster_problems_.num_modes(), 3); viterbi.Initialize(); // Set the weights based on the current centers. clock_t start = clock(); for (int mode = 0; mode < cluster_problems_.num_modes(); ++mode) { for (int i = 0; i < cluster_problem.num_states; ++i) { const DataPoint ¢er = centers_[mode][cluster_problem.MapState(i)]; for (int s = 0; s < cluster_problem.num_steps; ++s) { double score = dist(center, utterance.sequence(s, 0)); viterbi.set_transition_score(s, i, mode, score); } } } cerr << "score setting " << clock() - start << endl; // Run semimarkov algorithm. //vector<int> path; viterbi.set_use_sum(); viterbi.ForwardScores(); double score = viterbi.GetBestScore(); viterbi.BackwardScores(); vector<vector<vector<double> > > marginals; viterbi.Marginals(&marginals); for (int s = 0; s < cluster_problem.num_steps; ++s) { for (int i = 0; i < cluster_problem.num_states; ++i) { int type = cluster_problem.MapState(i); for (int mode = 0; mode < cluster_problems_.num_modes(); ++mode) { double p = marginals[s][i][mode]; //cerr << p << endl; //assert(p <= 1.0 + 1e-4); //assert(p >= 0.0); if (p > 1.0) p = 1.0; //if (p > 1e-4) { estimators[mode][type] += p * utterance.sequence(s, 0); counts[mode][type] += p; //} } } } return score; }
double TaggerImpl::collins(double *collins) { if (x_.empty()) return 0.0; buildLattice(); viterbi(); // call for finding argmax y* double s = 0.0; // if correct parse, do not run forward + backward { size_t num = 0; for (size_t i = 0; i < x_.size(); ++i) if (answer_[i] == result_[i]) ++num; if (num == x_.size()) return 0.0; } for (size_t i = 0; i < x_.size(); ++i) { // answer { s += node_[i][answer_[i]]->cost; for (int *f = node_[i][answer_[i]]->fvector; *f != -1; ++f) ++collins[*f + answer_[i]]; const std::vector<Path *> &lpath = node_[i][answer_[i]]->lpath; for (const_Path_iterator it = lpath.begin(); it != lpath.end(); ++it) { if ((*it)->lnode->y == answer_[(*it)->lnode->x]) { for (int *f = (*it)->fvector; *f != -1; ++f) ++collins[*f +(*it)->lnode->y * ysize_ +(*it)->rnode->y]; s += (*it)->cost; break; } } } // result { s -= node_[i][result_[i]]->cost; for (int *f = node_[i][result_[i]]->fvector; *f != -1; ++f) --collins[*f + result_[i]]; const std::vector<Path *> &lpath = node_[i][result_[i]]->lpath; for (const_Path_iterator it = lpath.begin(); it != lpath.end(); ++it) { if ((*it)->lnode->y == result_[(*it)->lnode->x]) { for (int *f = (*it)->fvector; *f != -1; ++f) --collins[*f +(*it)->lnode->y * ysize_ +(*it)->rnode->y]; s -= (*it)->cost; break; } } } } return -s; }
bool TaggerImpl::parse() { CHECK_FALSE(feature_index_->buildFeatures(this)) << feature_index_->what(); if (x_.empty()) return true; buildLattice(); if (nbest_ || vlevel_ >= 1) forwardbackward(); viterbi(); if (nbest_) initNbest(); return true; }
void decode_data_debug( uint8_t raw[RAW_SIZE], // Data to be decoded, 5200 byte (soft bit format) uint8_t data[DATA_SIZE], // Decoded data, 256 byte int8_t error[2], // RS decoder modules corrected errors or -1 if unrecoverable error happened uint8_t conv[CONV_SIZE], // Deinterleaved data with SYNC removed (5132 byte, soft bit format) uint8_t dec_data[RS_SIZE], // Viterbi decoder output (320 byte): two RS codeblock interleaved and scrambled(!) uint8_t rs[2][RS_BLOCK_SIZE] // RS codeblocks without the leading padding 95 zeros ) { deinterleave(raw, conv); viterbi(conv, dec_data); descramble_and_deinterleave(dec_data, rs); rs_decode(rs, data, error); }
double SpeechKMeans::UnsupExpectation(int utterance_index, int *correctness, vector<vector<vector<DataPoint> > > *sets) { cerr << "Unsupervised maximization" << endl; int u = utterance_index; const ClusterProblem &cluster_problem = cluster_problems_.problem(utterance_index); const Utterance &utterance = problems_.utterance(utterance_index); // Duplicate each state for every mode. Viterbi viterbi(cluster_problem.num_states, cluster_problem.num_steps, cluster_problems_.num_types(), 1); viterbi.Initialize(); // Set the weights based on the current centers. clock_t start = clock(); for (int type = 0; type < cluster_problems_.num_types(); ++type) { const DataPoint ¢er = centers_[0][type]; for (int s = 0; s < cluster_problem.num_steps; ++s) { double score = dist(center, utterance.sequence(s, 0)); for (int i = 0; i < cluster_problem.num_states; ++i) { viterbi.set_transition_score(s, i, type, score); } } } cerr << "TIME: score setting " << clock() - start << endl; // Run semimarkov algorithm. viterbi.ForwardScores(); double score = viterbi.GetBestPath(&path_[u], &type_centers_[u]); (*correctness) = utterance.ScoreAlignment(path_[u]); cerr << "SCORE: Correctness: " << *correctness << endl; // Make the cluster sets. sets->resize(cluster_problems_.num_modes()); for (int mode = 0; mode < cluster_problems_.num_modes(); ++mode) { (*sets)[mode].resize(num_types_); } problems_.AlignmentClusterSetUnsup(utterance_index, path_[u], type_centers_[u], sets); // collapse to modes. cerr << endl; return score; }
void main_loop(const char** argv) { map<string, string> params; process_cmd_line(argv, params); Lab2VitMain mainObj(params); while (mainObj.init_utt()) { double logProb = viterbi(mainObj.get_graph(), mainObj.get_gmm_probs(), mainObj.get_chart(), mainObj.get_label_list(), mainObj.get_acous_wgt(), mainObj.do_align()); mainObj.finish_utt(logProb); } mainObj.finish(); }
void SpeechKMeans::ClusterSegmentsExpectation(int utterance_index, vector<DataPoint> *points, vector<double> *weights) { const ClusterProblem &cluster_problem = cluster_problems_.problem(utterance_index); // Duplicate each state for every mode. Viterbi viterbi(cluster_problem.num_states, cluster_problem.num_steps, cluster_problem.num_hidden(0), 1); viterbi.Initialize(); // Set the weights based on the current centers. clock_t start = clock(); for (int s = 0; s < cluster_problem.num_steps; ++s) { for (int c = 0; c < cluster_problems_.num_hidden(0); ++c) { double score = distances_[utterance_index]->get_distance(s, c); viterbi.set_score(s, c, score); } } cerr << "TIME: score setting " << clock() - start << endl; // Run semimarkov algorithm. viterbi.ForwardScores(); vector<int> path; vector<int> centers; viterbi.GetBestPath(&path, ¢ers); //double weight = 0.0; int state = 0; for (int s = 0; s < cluster_problem.num_steps; ++s) { points->push_back(problems_.center(centers[state]).point()); // weight += distances_[utterance_index]->get_distance(s, // centers[state]); if (s >= path[state + 1]) { //weights->push_back(weight); points->push_back(problems_.center(centers[state]).point()); ++state; //weight = 0.0; } } }
void run_benchmark( void *vargs ) { struct bench_args_t *args = (struct bench_args_t *)vargs; #ifdef GEM5_HARNESS mapArrayToAccelerator( MACHSUITE_VITERBI_VITERBI, "obs", (void*)&args->obs, sizeof(args->obs)); mapArrayToAccelerator( MACHSUITE_VITERBI_VITERBI, "path", (void*)&args->path, sizeof(args->path)); mapArrayToAccelerator( MACHSUITE_VITERBI_VITERBI, "transition", (void*)&args->transition, sizeof(args->transition)); mapArrayToAccelerator( MACHSUITE_VITERBI_VITERBI, "emission", (void*)&args->emission, sizeof(args->emission)); mapArrayToAccelerator( MACHSUITE_VITERBI_VITERBI, "init", (void*)&args->init, sizeof(args->init)); invokeAcceleratorAndBlock(MACHSUITE_VITERBI_VITERBI); #else viterbi( args->obs, args->init, args->transition, args->emission, args->path ); #endif }
bool Viterbi::analyze(Lattice *lattice) const { if (!lattice || !lattice->sentence()) { return false; } if (!initPartial(lattice)) { return false; } if (lattice->has_request_type(MECAB_NBEST) || lattice->has_request_type(MECAB_MARGINAL_PROB)) { if (!viterbiWithAllPath(lattice)) { return false; } } else { if (!viterbi(lattice)) { return false; } } if (!forwardbackward(lattice)) { return false; } if (!buildBestLattice(lattice)) { return false; } if (!buildAllLattice(lattice)) { return false; } if (!initNBest(lattice)) { return false; } return true; }
int main() { int i, j, k; int Obs[numObs]; float transMat[numStates*numObs], obsLik[numStates*numObs]; int finalState; finalState = 2; srandom(1); for(i=0;i<numObs;i++){ Obs[i] = i; } for(j=0;j<numStates;j++){ for(i=0;i<numObs;i++){ transMat[j*numObs + i] = RR(); obsLik[j*numObs + i] = RR(); } } finalState = viterbi(Obs, transMat, obsLik); printf("final == %d\n", finalState); return 0; }
/****************************************************************************** Checkforminimumduration() : inputs : Observation Space (pointer to all training feature vectors) same as Sequence of Observations, allMixtureMeans of GMMs - pointer to means of gmms, allMixtureVars of GMMs, (*numStates), numMixEachState, Transition matrix (not using currently), Emission probability matrix Bj(Ot), Initial probabilities (Pi) outputs : check for minimum duration and drops any state which has less than MIN_DUR frames ******************************************************************************/ int* CheckMinDuration(VECTOR_OF_F_VECTORS *features, int *hiddenStateSeq, int *numStates, VECTOR_OF_F_VECTORS *allMixtureMeans, VECTOR_OF_F_VECTORS *allMixtureVars, int *numMixEachState, int totalNumFeatures, float **B, int *numElemEachState, float *T1[], int *T2[], float *Pi, float *mixtureWeight){ FindNumberOfElemInEachState(hiddenStateSeq, numStates, totalNumFeatures, numElemEachState, Pi); // check min duration constraint int i = 0, j = 0, s = 0, d= 0, mixCount = 0; for(s = 0; s < *numStates; s++){ if( numElemEachState[s] < MIN_DUR ){ printf("dropping state: %d ....does not contain enough elements...\n", s); //drop the state VECTOR_OF_F_VECTORS *tempAllMixtureMeans, *tempAllMixtureVars; tempAllMixtureMeans = (VECTOR_OF_F_VECTORS *) calloc(MAX_NUM_MIX * (*numStates) , sizeof(VECTOR_OF_F_VECTORS)); tempAllMixtureVars = (VECTOR_OF_F_VECTORS *) calloc(MAX_NUM_MIX * (*numStates) , sizeof(VECTOR_OF_F_VECTORS)); for(i = 0; i < MAX_NUM_MIX * (*numStates); i++){ tempAllMixtureMeans[i] = (F_VECTOR *) AllocFVector(DIM); tempAllMixtureVars[i] = (F_VECTOR *) AllocFVector(DIM); } // COPY ORIGINAL MEANS AND VARS INTO TEMPS int totalMix = 0; for(i = 0; i < *numStates; i++) totalMix += numMixEachState[i]; for(i = 0; i < totalMix; i++){ for(d = 0; d < DIM; d++){ tempAllMixtureMeans[i]->array[d] = allMixtureMeans[i]->array[d]; tempAllMixtureMeans[i]->numElements = DIM; tempAllMixtureVars[i]->array[d] = allMixtureVars[i]->array[d]; tempAllMixtureMeans[i]->numElements = DIM; } } // copy from temp to original means and vars array int mix_s = numMixEachState[s]; for(j = 0; j < *numStates - 1; j++){ if(j >= s) numMixEachState[j] = numMixEachState[j+1]; } for(j = 0; j < *numStates - 1; j++){ if(j < s){ Pi[j] = (float) log((float)numElemEachState[j]/totalNumFeatures); mixCount = 0; for(i = 0; i < j; i++) mixCount += numMixEachState[i]; for(i = mixCount; i < mixCount + numMixEachState[j]; i++){ for(d = 0; d < DIM; d++){ allMixtureMeans[i]->array[d] = tempAllMixtureMeans[i]->array[d]; allMixtureMeans[i]->numElements = DIM; allMixtureVars[i]->array[d] = tempAllMixtureVars[i]->array[d]; allMixtureMeans[i]->numElements = DIM; } } } else if(j >= s){ mixCount = 0; numElemEachState[j] = numElemEachState[j+1]; Pi[j] = (float) log((float)numElemEachState[j]/totalNumFeatures); //printf("Pi[%d] : %f\n", j, Pi[j]); for(i = 0; i < j; i++) mixCount += numMixEachState[i]; for(i = mixCount; i < mixCount + numMixEachState[j]; i++){ for(d = 0; d < DIM; d++){ allMixtureMeans[i]->array[d] = tempAllMixtureMeans[i + mix_s]->array[d]; allMixtureMeans[i]->numElements = DIM; allMixtureVars[i]->array[d] = tempAllMixtureVars[i + mix_s]->array[d]; allMixtureMeans[i]->numElements = DIM; } } } } // FREE TEMP VECTORS for(i = 0; i < MAX_NUM_MIX * (*numStates); i++){ free(tempAllMixtureMeans[i]); free(tempAllMixtureVars[i]); } free(tempAllMixtureMeans); free(tempAllMixtureVars); // change number of states by one *numStates = *numStates - 1; // first compute new posterior probs for each element ComputePosteriorProb(features, B, allMixtureMeans, allMixtureVars, numStates, numMixEachState, totalNumFeatures, mixtureWeight); // Now call viterbi alginment again return viterbi( features, numStates, allMixtureMeans, allMixtureVars, numMixEachState, totalNumFeatures, B, numElemEachState, T1, T2, Pi, mixtureWeight); }//matches if } return hiddenStateSeq; }
int main(int argc, char *argv[]) { if (argc != 3) exit(-1); load_trans_prob(); std::ifstream emissin(argv[1]); std::ofstream fout(argv[2]); std::string line; while (getline(emissin, line)) { int N = 100; std::vector<Phone> seq; size_t pre = 0, next; std::string seq_id; next = line.find(' ', pre); seq_id = line.substr(pre, next - pre); fout << seq_id << " " << N << std::endl; pre = next+1; int cnt = std::stoi(line.substr(pre)); std::cout << seq_id << "\t" << cnt << std::endl; while(cnt--) { Phone tmp; getline(emissin, line); std::istringstream ss(line); for (int i=0; i<48; i++) ss >> tmp.features[i]; seq.push_back(tmp); } std::vector<int> ans(seq.size(), 0); for (int i=0; i<seq.size(); i++) { float max = -1e50; int max_index = 0; for (int j=0; j<48; j++) { if (seq[i].features[j] > max) { max = seq[i].features[j]; max_index = j; } } ans[i] = max_index; } int start, end; for (start=0; start < seq.size(); start++) if (ans[start] != 37) break; for (end = seq.size(); end>0; end--) if (ans[end-1] != 37) break; Phone tmp; for (int i=0; i<48; i++) tmp.features[i] = 0; std::vector<Phone> newseq; cnt = 0; for (int i=start; i<end; i++) { if (i != start && ans[i] != ans[i-1]) { for (int j=0; j<48; j++) tmp.features[j] = std::log(tmp.features[j] / cnt); newseq.push_back(tmp); for (int j=0; j<48; j++) tmp.features[j] = 0; cnt = 0; } for (int j=0; j<48; j++) tmp.features[j] += std::exp(seq[i].features[j]); cnt ++; } viterbi(newseq, N, fout); } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double a_matrix_in[4][4];/* 2 dimensional C array to pass to workFcn() */ double *delta_in_matrix;/* 2 dimensional C array to pass to workFcn() */ double *observation_probs_matrix;/* 2 dimensional C array to pass to workFcn() */ double *psi_matrix;/* 2 dimensional C array to pass to workFcn() */ double duration_sum_in[4];/* 2 dimensional C array to pass to workFcn() */ double duration_probs_matrix[4][150];/* 2 dimensional C array to pass to workFcn() */ int actual_T; int fake_T_extended; int actual_N; int max_duration_D_val; int row,col; /* loop indices */ int m,n; /* temporary array size holders */ /* Step 1: Error Checking Step 1a: is nlhs 1? If not, * generate an error message and exit mexample (mexErrMsgTxt * does this for us!) */ if (nlhs!=3) mexErrMsgTxt("mexample requires 3 output argument."); /* Step 1b: is nrhs 2? */ if (nrhs!=9) mexErrMsgTxt("mexample requires 9 input arguments"); actual_T = mxGetM(observation_probs); actual_N = mxGetN(observation_probs); max_duration_D_val = mxGetScalar(max_duration_D); /* Step 2: Allocate memory for return argument(s) */ delta_out = mxCreateDoubleMatrix((actual_T+max_duration_D_val-1), actual_N, mxREAL); psi_out = mxCreateDoubleMatrix((actual_T+max_duration_D_val-1), actual_N, mxREAL); psi_duration = mxCreateDoubleMatrix((actual_T+max_duration_D_val-1), actual_N, mxREAL); /* Step 3: Convert ARRAY_IN to a 2x2 C array * MATLAB stores a two-dimensional matrix in memory as a one- * dimensional array. If the matrix is size MxN, then the * first M elements of the one-dimensional array correspond to * the first column of the matrix, and the next M elements * correspond to the second column, etc. The following loop * converts from MATLAB format to C format: */ for (col=0; col < mxGetN(a_matrix); col++){ for (row=0; row < mxGetM(a_matrix); row++){ a_matrix_in[row][col] =(mxGetPr(a_matrix))[row+col*mxGetM(a_matrix)]; } } for (col=0; col < mxGetM(duration_sum); col++){ duration_sum_in[col] =(mxGetPr(duration_sum))[col]; } delta_in_matrix = mxGetPr(delta); observation_probs_matrix = mxGetPr(observation_probs); psi_matrix = mxGetPr(psi); /* for (col=0; col < mxGetN(delta); col++){ * // for (row=0; row < mxGetM(delta); row++){ * // * // * // observation_probs_matrix[row][col] =(mxGetPr(observation_probs))[row+col*mxGetM(observation_probs)]; * // psi_matrix[row][col] =(mxGetPr(psi))[row+col*mxGetM(psi)]; * // } * // }*/ for (col=0; col < mxGetN(duration_probs); col++){ for (row=0; row < mxGetM(duration_probs); row++){ duration_probs_matrix[row][col] =(mxGetPr(duration_probs))[row+col*mxGetM(duration_probs)]; } } /* mxGetPr returns a pointer to the real part of the array * ARRAY_IN. In the line above, it is treated as the one- * dimensional array mentioned in the previous comment. */ /* Step 4: Call workFcn function */ viterbi(actual_N,actual_T,a_matrix_in,max_duration_D_val,delta_in_matrix,observation_probs_matrix,duration_probs_matrix,psi_matrix,mxGetPr(psi_duration),duration_sum_in); memcpy ( mxGetPr(delta_out), delta_in_matrix, actual_N*(actual_T+max_duration_D_val-1)*8); memcpy ( mxGetPr(psi_out), psi_matrix, actual_N*(actual_T+max_duration_D_val-1)*8); }
int two_states_coin_toss() { model my_model; state model_states[2]; double symbols_head_state[2]={1.0,0.0}; double trans_prob_head_state[2]={0.5,0.5}; double trans_prob_head_state_rev[2]={0.5,0.5}; int trans_id_head_state[2]={0,1}; double symbols_tail_state[2]={0.0,1.0}; double trans_prob_tail_state[2]={0.5,0.5}; double trans_prob_tail_state_rev[2]={0.5,0.5}; int trans_id_tail_state[2]={0,1}; sequence_t *my_output; double log_p_viterbi, log_p_forward; double **forward_alpha; double forward_scale[10]; int *viterbi_path; int i; /* flags indicating whether a state is silent */ int silent_array[2] = {0,0}; my_model.model_type = 0; /* initialise head state */ model_states[0].pi = 0.5; model_states[0].b=symbols_head_state; model_states[0].out_states=2; model_states[0].out_a=trans_prob_head_state; model_states[0].out_id=trans_id_head_state; model_states[0].in_states=2; model_states[0].in_id=trans_id_head_state; model_states[0].in_a=trans_prob_head_state_rev; model_states[0].fix=1; /* initialise tail state */ model_states[1].pi = 0.5; model_states[1].b=symbols_tail_state; model_states[1].out_states=2; model_states[1].out_id=trans_id_tail_state; model_states[1].out_a=trans_prob_tail_state; model_states[1].in_states=2; model_states[1].in_id=trans_id_tail_state; model_states[1].in_a=trans_prob_tail_state_rev; model_states[1].fix=1; /* initialise model */ my_model.N=2; my_model.M=2; my_model.s=model_states; my_model.prior=-1; my_model.silent = silent_array; fprintf(stdout,"transition matrix:\n"); model_A_print(stdout,&my_model,""," ","\n"); fprintf(stdout,"observation symbol matrix:\n"); model_B_print(stdout,&my_model,""," ","\n"); my_output=model_generate_sequences(&my_model,0,10,10,100); sequence_print(stdout,my_output); /* try viterbi algorithm in a clear situation */ viterbi_path=viterbi(&my_model, my_output->seq[0], my_output->seq_len[0], &log_p_viterbi); if (viterbi_path==NULL) {fprintf(stderr,"viterbi failed!"); return 1;} fprintf(stdout,"viterbi:\n"); for(i=0;i<my_output->seq_len[0];i++){ printf(" %d, ", viterbi_path[i]); } printf("\n"); fprintf(stdout, "log-p of this sequence (viterbi algorithm): %f\n", log_p_viterbi); /* allocate matrix for forward algorithm */ fprintf(stdout,"applying forward algorithm to the sequence..."); forward_alpha=stat_matrix_d_alloc(10,2); if (forward_alpha==NULL) { fprintf(stderr,"\n could not alloc forward_alpha matrix\n"); return 1; } /* run foba_forward */ if (foba_forward(&my_model, my_output->seq[0], my_output->seq_len[0], forward_alpha, forward_scale, &log_p_forward)) { fprintf(stderr,"foba_logp failed!"); stat_matrix_d_free(&forward_alpha); return 1; } /* alpha matrix */ fprintf(stdout,"Done.\nalpha matrix from forward algorithm:\n"); matrix_d_print(stdout,forward_alpha,10,2,""," ","\n"); fprintf(stdout,"log-p of this sequence (forward algorithm): %f\n",log_p_forward); /* clean up */ sequence_free(&my_output); free(viterbi_path); stat_matrix_d_free(&forward_alpha); return 0; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double a_matrix_in[4][4];/* 2 dimensional C array to pass to workFcn() */ double *delta_in_matrix;/* 2 dimensional C array to pass to workFcn() */ double *observation_probs_matrix;/* 2 dimensional C array to pass to workFcn() */ double *psi_matrix;/* 2 dimensional C array to pass to workFcn() */ double duration_probs_matrix[4][150];/* 2 dimensional C array to pass to workFcn() */ int actual_T; int actual_N; int max_duration_D_val; int row,col; /* loop indices */ int m,n; /* temporary array size holders */ /* Step 1: Error Checking Step 1a: is nlhs 1? If not, * generate an error message and exit mexample (mexErrMsgTxt * does this for us!) */ if (nlhs!=3) mexErrMsgTxt("mexample requires 3 output argument."); /* Step 1b: is nrhs 2? */ if (nrhs!=8) mexErrMsgTxt("mexample requires 8 input arguments"); actual_T = mxGetM(observation_probs); actual_N = mxGetN(observation_probs); /* Step 2: Allocate memory for return argument(s) */ delta_out = mxCreateDoubleMatrix(actual_T, actual_N, mxREAL); psi_out = mxCreateDoubleMatrix(actual_T, actual_N, mxREAL); psi_duration = mxCreateDoubleMatrix(actual_T, actual_N, mxREAL); /* Step 3: Convert ARRAY_IN to a 2x2 C array * MATLAB stores a two-dimensional matrix in memory as a one- * dimensional array. If the matrix is size MxN, then the * first M elements of the one-dimensional array correspond to * the first column of the matrix, and the next M elements * correspond to the second column, etc. The following loop * converts from MATLAB format to C format: */ for (col=0; col < mxGetN(a_matrix); col++){ for (row=0; row < mxGetM(a_matrix); row++){ a_matrix_in[row][col] =(mxGetPr(a_matrix))[row+col*mxGetM(a_matrix)]; } } delta_in_matrix = mxGetPr(delta); observation_probs_matrix = mxGetPr(observation_probs); psi_matrix = mxGetPr(psi); for (col=0; col < mxGetN(duration_probs); col++){ for (row=0; row < mxGetM(duration_probs); row++){ duration_probs_matrix[row][col] =(mxGetPr(duration_probs))[row+col*mxGetM(duration_probs)]; } } max_duration_D_val = mxGetScalar(max_duration_D); /* mxGetPr returns a pointer to the real part of the array * ARRAY_IN. In the line above, it is treated as the one- * dimensional array mentioned in the previous comment. */ /* Step 4: Call workFcn function */ viterbi(actual_N,actual_T,a_matrix_in,max_duration_D_val,delta_in_matrix,observation_probs_matrix,duration_probs_matrix,psi_matrix,mxGetPr(psi_duration)); memcpy ( mxGetPr(delta_out), delta_in_matrix, actual_N*actual_T*8); memcpy ( mxGetPr(psi_out), psi_matrix, actual_N*actual_T*8); /* workFcn(twoDarray,mxGetPr(VECTOR_IN), mxGetPr(VECTOR_OUT)); * * workFcn will fill VECTOR_OUT with the return values for * mexample, so the MEX-function is done! To use it, compile * it according to the instructions in the Application Program * Interface Guide. Then, in MATLAB, type * * c=mexample([1 2; 3 4],[1 2]) * * This will return the same as * * c=det([1 2; 3 4]) * [1 2] * */ }
/** * For one network phi and one experiment extracted from the total data matrix X, * for one experiments states Gx use the viterbi algorithm * N: number of nodes * T: number of time points * R: number of replicates * X: data matrix (N x TxR) * GS: optim state matrix (N x TxR), initialised in R and given as argument * G: state matrix (N x sum_s(M_s)); for each stimulus s, there are M_s states * Glen: * TH: theta parameter matrix (N x 4) * tps: timepoint vector (T) * stimgrps: vector containing the stimulus indices * numexperimentsx: number of experiments (equals length of R and Ms) * hmmit: number of hmmiterations * Ms: number of system states for each experiment */ double hmmsearch(int *phi, const int N, const int *Tx, const int *Rx, const double *X, int *GS, int *G, int Glen, double *TH, const int *tps, const int *stimids, const int *stimgrps, const int numexperiments, const int hmmit, int *Ms) { // fixed for the moment, number of iterations in the em-algorithm int ncol_GS=0; int numstims, idstart=0, Gstart=0; for(int i=0; i!=numexperiments; ++i) { ncol_GS += Tx[i]*Rx[i]; } // printf("~~~~~ \n ncol_GS: %d\n",ncol_GS); // init A, TH and L // sort of a hack for getting the - infinity value double temp = 1.0; double infinity = -1 * (temp / (temp - 1.0)); int M = Glen/N; // total number of system states // allocate the transition probability matrix, for all experiments int A_sz = 0; for(int i=0; i!=numexperiments; ++i) { A_sz += pow(Ms[i],2); } // make a vector of doubles, holding the transition probabilities double *A = malloc(A_sz * sizeof(double)); init_A(A, Ms, numexperiments); // init transition probabilities (sparse MxM matrix) /* main loop: for each iteration in hmmiterations: * perform viterbi for each experiment separately * get the parameters TH and updates for A and GS for all experiments combined */ int Mexp, T, R; int startA=0, startX=0, startG=0; double *Aexp = NULL; double *Xexp = NULL; int *Gexp = NULL; int *GSexp = NULL; int allR, allT; double Lik = -1*infinity; double Likold = -1*infinity; int nLikEqual = 0; // keep track of the last 5 likelihood differences // if switching behaviour occurs, it can be seen here // take differences int K = 6; double diff, difftmp; //double *diffvec = calloc(K-1, sizeof(double)); double *diffvec = malloc(K * sizeof(double)); int *toswitch = calloc(N, sizeof(int)); int nsw=0, maxsw=10; // new state matrix object for(int it=0; it!=hmmit; ++it) { allR=0; allT=0; startA=0; startX=0; startG=0; // find switchable rows in TH nsw = find_switchable(TH, N, toswitch); if(nsw>0) { maxsw = min(nsw, maxsw); } /* here the experiment loop * extract each experiment from X according to R and stimgrps and run the hmm * indices of columns of X to be selected: * expind is equivalent to the experiment index * this defines the stimuli to take from stimgrps */ for(int expind=0; expind!=numexperiments; expind++) { //print_intmatrix(toswitch, 1, N); // if inconsistencies occur in the gamma matrix, // try switching the theta parameters upto // maxsw times to reduce the number of inconsitencies //maxsw = min(nsw, N); T = Tx[expind]; R = Rx[expind]; allR += R; allT += T; Mexp = Ms[expind]; for(int swind=0; swind!=maxsw; ++swind) { // extract the sub-transition matrix: Aexp = realloc(Aexp, Mexp*Mexp * sizeof(double)); extract_transitionmatrix(A, Aexp, Mexp, startA); // extract the sub-data matrix Xexp = realloc(Xexp, N*T*R*sizeof(double)); extract_datamatrix(X, Xexp, N, T, R, startX); // extract the sub-state matrix Gexp = realloc(Gexp, N*Mexp*sizeof(int)); extract_statematrix(G, Gexp, N, Mexp, startG); // extract the sub-optimstate matrix GSexp = realloc(GSexp, N*T*R*sizeof(int)); extract_statematrix(GS, GSexp, N, T*R, startX); // run the viterbi viterbi(T, Mexp, Xexp, Gexp, TH, N, R, Aexp, GSexp); // consitency check int inc = is_consistent(phi, GSexp, Gexp, N, T, R); if(inc>0 && nsw>0) { //printf("Inconsitensies in state series. Repeat HMM with modified thetaprime.\n"); // select a row to switch randomly int rnum = rand() % nsw; // a random number between 1 and nsw int hit = 0, ii=0; for(ii=0; ii!=N; ++ii) { if(toswitch[ii]!=0) { if(hit==rnum) { break; } hit++; } } switch_theta_row(TH, ii, N); // remove node as possible switch node toswitch[ii] = 0; nsw--; } else { // update the GSnew matrix update_statematrix(GS, GSexp, startX, N, T, R); // update the new transition prob matrix update_transitionmatrix(A, Aexp, Mexp, startA); break; } } // switch loop end // increment the experiment start indices startA += pow(Mexp, 2); startX += N*T*R; startG += N*Mexp; } // experiment loop end // number of replicates are the same in each experiment, since // pad-columns containing NAs were added allR = allR/numexperiments; // M-step // update the theta matrix estimate_theta(X, GS, TH, N, allT, allR); // calculate the new likelihood Lik = calculate_likelihood(X, GS, TH, N, allT, allR); //Liktmp$L diff = fabs((fabs(Lik) - fabs(Likold))); // count number of equal differences in the last 10 likelihoods // if all 5 differences are equal, then stop int stopit=0, count = 0; // if all diffs are equal, stopit remains 1 and the loop is aborted // check if diffvec is filled if(it>=K) { // check elements in diffvec for(int k=0; k!=(K-1); ++k) { if(k>0) { if(fabs(diffvec[k]-difftmp)<=0.001) { count++; //stopit = 0; } } // remember the original value at current position difftmp = diffvec[k]; // shift next value left one position if(k<K) { diffvec[k] = diffvec[k+1]; } else { // update the new difference at last position diffvec[k] = diff; } } if(count==(K-1)) { stopit = 1; // make sure that the higher likelihood is taken // if switching occurs if(Likold>Lik) { stopit = 0; } } } else { // if not filled then add elements diffvec[it] = diff; } // another termination criterion: count if liklihood terms do not change if(Lik==Likold) { nLikEqual++; } else { nLikEqual = 0; Likold = Lik; } // abort baum-welch, if Lik does not change anymore if(nLikEqual>=10 || stopit==1) { break; } } free(toswitch); free(diffvec); free(GSexp); free(Gexp); free(Xexp); free(Aexp); free(A); return Lik; }
int main(int argc, char *argv[]) { char *configfile = NULL; FILE *fin, *bin; char *linebuf = NULL; size_t buflen = 0; int iterations = 3; int mode = 3; int c; float d; float *loglik; float p; int i, j, k; opterr = 0; while ((c = getopt(argc, argv, "c:n:hp:")) != -1) { switch (c) { case 'c': configfile = optarg; break; case 'h': usage(); exit(EXIT_SUCCESS); case 'n': iterations = atoi(optarg); break; case 'p': mode = atoi(optarg); if (mode != 1 && mode != 2 && mode != 3) { fprintf(stderr, "illegal mode: %d\n", mode); exit(EXIT_FAILURE); } break; case '?': fprintf(stderr, "illegal options\n"); exit(EXIT_FAILURE); default: abort(); } } if (configfile == NULL) { fin = stdin; } else { fin = fopen(configfile, "r"); if (fin == NULL) { handle_error("fopen"); } } i = 0; while ((c = getline(&linebuf, &buflen, fin)) != -1) { if (c <= 1 || linebuf[0] == '#') continue; if (i == 0) { if (sscanf(linebuf, "%d", &nstates) != 1) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } prior = (float *) malloc(sizeof(float) * nstates); if (prior == NULL) handle_error("malloc"); trans = (float *) malloc(sizeof(float) * nstates * nstates); if (trans == NULL) handle_error("malloc"); xi = (float *) malloc(sizeof(float) * nstates * nstates); if (xi == NULL) handle_error("malloc"); pi = (float *) malloc(sizeof(float) * nstates); if (pi == NULL) handle_error("malloc"); } else if (i == 1) { if (sscanf(linebuf, "%d", &nobvs) != 1) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } obvs = (float *) malloc(sizeof(float) * nstates * nobvs); if (obvs == NULL) handle_error("malloc"); gmm = (float *) malloc(sizeof(float) * nstates * nobvs); if (gmm == NULL) handle_error("malloc"); } else if (i == 2) { /* read initial state probabilities */ bin = fmemopen(linebuf, buflen, "r"); if (bin == NULL) handle_error("fmemopen"); for (j = 0; j < nstates; j++) { if (fscanf(bin, "%f", &d) != 1) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } prior[j] = logf(d); } fclose(bin); } else if (i <= 2 + nstates) { /* read state transition probabilities */ bin = fmemopen(linebuf, buflen, "r"); if (bin == NULL) handle_error("fmemopen"); for (j = 0; j < nstates; j++) { if (fscanf(bin, "%f", &d) != 1) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } trans[IDX((i - 3),j,nstates)] = logf(d); } fclose(bin); } else if (i <= 2 + nstates * 2) { /* read output probabilities */ bin = fmemopen(linebuf, buflen, "r"); if (bin == NULL) handle_error("fmemopen"); for (j = 0; j < nobvs; j++) { if (fscanf(bin, "%f", &d) != 1) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } obvs[IDX((i - 3 - nstates),j,nobvs)] = logf(d); } fclose(bin); } else if (i == 3 + nstates * 2) { if (sscanf(linebuf, "%d %d", &nseq, &length) != 2) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } data = (int *) malloc (sizeof(int) * nseq * length); if (data == NULL) handle_error("malloc"); } else if (i <= 3 + nstates * 2 + nseq) { /* read data */ bin = fmemopen(linebuf, buflen, "r"); if (bin == NULL) handle_error("fmemopen"); for (j = 0; j < length; j++) { if (fscanf(bin, "%d", &k) != 1 || k < 0 || k >= nobvs) { fprintf(stderr, "config file format error: %d\n", i); freeall(); exit(EXIT_FAILURE); } data[(i - 4 - nstates * 2) * length + j] = k; } fclose(bin); } i++; } fclose(fin); if (linebuf) free(linebuf); if (i < 4 + nstates * 2 + nseq) { fprintf(stderr, "configuration incomplete.\n"); freeall(); exit(EXIT_FAILURE); } if (mode == 3) { loglik = (float *) malloc(sizeof(float) * nseq); if (loglik == NULL) handle_error("malloc"); for (i = 0; i < iterations; i++) { init_count(); for (j = 0; j < nseq; j++) { loglik[j] = forward_backward(data + length * j, length, 1); } p = sumf(loglik, nseq); update_prob(); printf("iteration %d log-likelihood: %.4f\n", i + 1, p); printf("updated parameters:\n"); printf("# initial state probability\n"); for (j = 0; j < nstates; j++) { printf(" %.4f", exp(prior[j])); } printf("\n"); printf("# state transition probability\n"); for (j = 0; j < nstates; j++) { for (k = 0; k < nstates; k++) { printf(" %.4f", exp(trans[IDX(j,k,nstates)])); } printf("\n"); } printf("# state output probility\n"); for (j = 0; j < nstates; j++) { for (k = 0; k < nobvs; k++) { printf(" %.4f", exp(obvs[IDX(j,k,nobvs)])); } printf("\n"); } printf("\n"); } free(loglik); } else if (mode == 2) { for (i = 0; i < nseq; i++) { viterbi(data + length * i, length); } } else if (mode == 1) { loglik = (float *) malloc(sizeof(float) * nseq); if (loglik == NULL) handle_error("malloc"); for (i = 0; i < nseq; i++) { loglik[i] = forward_backward(data + length * i, length, 0); } p = sumf(loglik, nseq); for (i = 0; i < nseq; i++) printf("%.4f\n", loglik[i]); printf("total: %.4f\n", p); free(loglik); } freeall(); return 0; }
bool CTrigramModel::adjusting_homonyms_coef(string FileName) const { FILE* fp = fopen(FileName.c_str(), "r"); if (!fp) { fprintf (stderr, "cannot open %s\n", FileName.c_str()); return false; }; char buffer[10000]; int pos=0, neg=0, not_amb=0; int SentNo = 0; while (fgets(buffer, 10000, fp)) { SentNo++; vector<string> words; vector<CWordIntepretation> tags; vector<WORD> refs; StringTokenizer tok(buffer, " \t\r\n"); for (size_t i=0; tok(); i++) { string t = tok.val(); if (i%2==0) { words.push_back(t); } else { WORD ti=find_tag(t); if (ti == UnknownTag) { fprintf (stderr, "unknown tag \"%s\" LineNo=%i\n", t.c_str(), SentNo); return false; } refs.push_back(ti); } } if (words.empty()) continue; if ( (SentNo%100)== 0) printf ("\r%i ", SentNo); if (!viterbi(words, tags)) return false; for (size_t i=0; i<words.size(); i++) { WORD ref = refs[i]; if (tags[i].m_TagId2 == UnknownTag) not_amb++; if ( (tags[i].m_TagId1==ref) || (tags[i].m_TagId2==ref) ) pos++; else { string gs = m_RegisteredTags[tags[i].m_TagId1]; if (tags[i].m_TagId2 != UnknownTag) gs += "["+m_RegisteredTags[tags[i].m_TagId2]+"]"; string rs = m_RegisteredTags[ref]; for (int j=(int)i-5; j<(int)min(i+5, words.size()); j++) { if (j<0) { continue; } if (j != i) fprintf(stderr, "%s ", words[j].c_str()); else fprintf(stderr, "*%s* [guess %s ref %s] ", words[i].c_str(), gs.c_str(), rs.c_str() ); } fprintf(stderr, "\n"); neg++; } } //fprintf (stderr, "dump %d\n",pos+neg); } printf ("\n"); fprintf (stderr, "%d (%d+%d) words tagged, accuracy %7.3f%%, recall %7.3f%%\n", pos+neg, pos, neg, 100.0*(prob_t)pos/(prob_t)(pos+neg), 100.0*(prob_t)not_amb/(prob_t)(pos+neg)); fclose (fp); return true; }
void testBaumwelch(){ int i, error, tl,z,z1,z2; double log_p,first_prob1,first_prob2, first_prob; double *proba; int *path; int* real_path; int *path1; int* real_path1; int *path2; int* real_path2; model *mo = NULL; sequence_t *my_output, *your_output; int seqlen = 1000; tl = 150; mo = malloc(sizeof(model)); if (mo==NULL) {fprintf(stderr,"Null Pointer in malloc(model).\n");} real_path = malloc(seqlen*sizeof(double)); if(!real_path){ printf("real_path hat kein platz gekriegt\n");} real_path1 = malloc(seqlen*sizeof(double)); if(!real_path1){ printf("real_path hat kein platz gekriegt\n");} real_path2 = malloc(seqlen*sizeof(double)); if(!real_path2){ printf("real_path hat kein platz gekriegt\n");} /* generate a model with variable number of states*/ generateModel(mo, 5); /*generate a random sequence*/ my_output = model_label_generate_sequences(mo, 0, seqlen, 10, seqlen); for (i=0; i<seqlen; i++){ printf("%d", my_output->state_labels[0][i]); } printf("\n"); /*viterbi*/ path = viterbi(mo, my_output->seq[0], my_output->seq_len[0], &first_prob); path1 = viterbi(mo, my_output->seq[1], my_output->seq_len[1], &first_prob1); path2 = viterbi(mo, my_output->seq[2], my_output->seq_len[2], &first_prob2); printf("\n viterbi-path\n"); z=0; z1=0; z2=0; for (i=0; i<my_output->seq_len[0]; i++){ if (path1[i] != -1) { real_path1[z1]=path1[i]; z1++; printf("%d", path1[i]); } else printf("hallo"); if (path2[i] != -1) { real_path2[z2]=path2[i]; z2++; printf("%d", path2[i]); } else printf("hallo"); if (path[i] != -1) { real_path[z]=path[i]; z++; printf("%d", path[i]); } } printf("\n"); printf("log-prob: %g\n",first_prob); my_output->state_labels[0]=real_path; my_output->state_labels[1]=real_path1; my_output->state_labels[2]=real_path2; for (i=0;i<seqlen;i++) printf("realpath[%i]=%i",i,real_path[i]); proba = malloc(sizeof(double)*tl); printf("No of Sequences = %d", my_output->seq_number); your_output = model_label_generate_sequences(mo, 0, seqlen, 1, seqlen); error = gradient_descent(&mo, your_output, .02, i); path = viterbi(mo, my_output->seq[0], my_output->seq_len[0], &log_p); free(path); /*reestimate_baum_welch_label(mo, my_output);*/ /*reestimate_baum_welch(mo, my_output);*/ /*reruns viterbi to check the training*/ printf("run viterbi second\n"); path = viterbi(mo, my_output->seq[0], my_output->seq_len[0], &log_p); for (i=0; i<(my_output->seq_len[0]*mo->N); i++){ if (path[i] != -1) {printf("%d", path[i]);} } printf("\n"); printf("log-prob: %g\n",log_p); /* freeing memory */ model_free(&mo); free(path); /*printf("sequence_free success: %d\n", */sequence_free(&my_output)/*)*/; free(my_output); }
// viterbi algorithm LABEL viterbi_loss(PATTERN x, LABEL y, STRUCTMODEL *sm, STRUCT_LEARN_PARM *sparm, int loss_bool) { /* // record the path (end in last state) points to this state will make max value int viterbi_table[x.frame_num][STATE_TYPES]; // t from 1 to x.frame_num float max_val_now[STATE_TYPES]; float max_val_last[STATE_TYPES]; //initial table int w; int j; for (j = 0; j < x.frame_num; j++){ for (w = 0; w < STATE_TYPES; ++w) viterbi_table[j][w] = 0; } for (w = 0; w < STATE_TYPES; ++w){ max_val_now[w] = 0; max_val_last[w] = 0; } double* Wobserve = & ( sm->w[1] ); double* Wtrans = & ( sm->w[OBSERVE_ELEMENT_DIM*STATE_TYPES + 1] ); // + OBSERVE_ELEMENT_DIM : add dummy hint //printf(" w[OBSERVE_ELEMENT_DIM*STATE_TYPES + 1] : %lf \n", sm->w[OBSERVE_ELEMENT_DIM*STATE_TYPES + 2]); int t; for (t = 0; t < x.frame_num; ++t){ int s; // observation element in time t if (t == 0){ for (s = 0; s < STATE_TYPES; ++s){ // for each state type s // Wobserve*psi int i; for (i = 0; i < OBSERVE_ELEMENT_DIM; ++i) max_val_now[s] += Wobserve[s*OBSERVE_ELEMENT_DIM + i]*x.observe_object[t][i]; if (loss_bool) { if (s != y.state_object[t]) // max_val_now[s] += 1.0/(double)(y.frame_num); max_val_now[s] ++; } } } else{ for (s = 0; s < STATE_TYPES; ++s){ // for each state type s double temp_max_value = -1000000; int max_path_index = 0; int p; // for every path p cal max_value(p) last time + Wtrans*psi@[a -> b] for (p = 0; p < STATE_TYPES; ++p){ double path_value = 0; path_value = max_val_last[p] + Wtrans[p*STATE_TYPES + s]*1.0 ; // ex : a->b if (path_value > temp_max_value){ temp_max_value = path_value; max_path_index = p; } } // build viterbi table viterbi_table[t][s] = max_path_index; max_val_now[s] = temp_max_value; // add Wobserve*psi @ time t int i; for (i = 0; i < OBSERVE_ELEMENT_DIM; ++i) max_val_now[s] += Wobserve[s*OBSERVE_ELEMENT_DIM + i]*x.observe_object[t][i]; if (loss_bool){ if (s != y.state_object[t]) // max_val_now[s] += 1.0/(double)(y.frame_num); max_val_now[s]++; } } } //printf("time %d:\n",t); for (w = 0; w < STATE_TYPES; ++w) { //printf(" %d %d \n",w, max_val_now[w]); max_val_last[w] = max_val_now[w]; } } // find max path int max_end_index = 0; float max = -1000000; int s; for (s = 0; s < STATE_TYPES; ++s){ if (max_val_now[s] > max) { max = max_val_now[s]; max_end_index = s; } } //printf("max : %f \n", max); // back trace max path and build y_max LABEL y_max; y_max.state_object = (int *)malloc(sizeof(int)*MAX_ELEMENT_IN_OBSERVE); y_max.speaker = (char *)malloc(sizeof(char)*20); y_max.frame_num = x.frame_num; y_max.state_object[y_max.frame_num - 1] = max_end_index; int predict_state = max_end_index; for (t = x.frame_num - 1; t > 0; --t){ predict_state = viterbi_table[t][predict_state]; y_max.state_object[t-1] = predict_state; }*/ double** emit = new double*[x.frame_num]; for (int i = 0; i < x.frame_num; i++){ emit[i] = new double[STATE_TYPES]; } double** trans = new double*[STATE_TYPES]; for (int i = 0; i < STATE_TYPES; i++){ trans[i] = new double[STATE_TYPES]; } for (int i = 0; i < x.frame_num; i++){ for (int j = 0; j < STATE_TYPES; j++){ int sum = 0; for (int k = 0; k < OBSERVE_ELEMENT_DIM; k++){ sum += sm->w[j*OBSERVE_ELEMENT_DIM+k] * x.observe_object[i][k]; } emit[i][j] = exp(sum); } } for (int i = 0; i < STATE_TYPES; i++){ for (int j = 0; j < STATE_TYPES; j++){ trans[i][j] = exp(sm->w[STATE_TYPES * OBSERVE_ELEMENT_DIM + i * STATE_TYPES + j]); } } double* start = new double[STATE_TYPES]; for (int i = 0; i < STATE_TYPES; i++){ start[i] = sparm->start_probability[i]; } double* end = new double[STATE_TYPES]; for (int i = 0; i < STATE_TYPES; i++){ end[i] = sparm->end_probability[i]; } auto ret = viterbi(x.frame_num, STATE_TYPES, emit, trans, start, end); LABEL y_max; y_max.state_object = new int[MAX_ELEMENT_IN_OBSERVE]; y_max.frame_num = ret.size(); y_max.speaker = (char*)malloc(sizeof(char)*20);; int i = 0; //cout << "addr of sizePsi:" << &sm->sizePsi <<endl; for (auto it = ret.begin(); it != ret.end(); it++){ //cerr << i << ":" << *it << " addr of state_object:" << &(y_max.state_object[i]) <<endl; y_max.state_object[i] = *it; /*if (sm->sizePsi != OBSERVE_ELEMENT_DIM*STATE_TYPES + STATE_TYPES*STATE_TYPES){ cout << "missmatch:" <<i << endl; cout << &(y_max->state_object[i]) << endl; break; }*/ i++; } /*for (int i = 0; i < y_max.frame_num; i++){ cout << y_max.state_object[i] << " "; }*/ //cout << "\nviterbi_8\n"; //sm->sizePsi = OBSERVE_ELEMENT_DIM*STATE_TYPES + STATE_TYPES*STATE_TYPES ; //cout << endl; return (y_max); }
void MP1:: viterbi(CorpusCache& cache){ double& alpha=alpha_; for(auto& sp: cache){ vector<vector<double>> target_probs(sp.m,vector<double>(sp.l,0.0)); vector<vector<pair<int,int>>> target_best(sp.m, vector<pair<int,int>>(sp.m)); alpha/=sp.n*sp.l; for(int j=0;j<sp.m;j++){ for(int jlen=0;jlen<sp.l;jlen++){ for(int i=0;i<sp.n;i++){ for(int ilen=0;ilen<sp.l;ilen++){ if(sp(i,ilen,j,jlen)!=(void*)0){ if(target_probs[j][jlen]< sp(i,ilen,j,jlen)->prob*alpha){ target_probs[j][jlen]= sp(i,ilen,j,jlen)->prob*alpha; target_best[j][jlen]=make_pair(i,ilen); } if(sp(i,ilen,j,jlen)->prob>1){ cerr<<"wth prob>1 : " <<sp(i,ilen,j,jlen)->prob<<endl; } } } } //cout<<target_probs[j][jlen]<<" "; } //cout<<endl; } //cout<<endl; for(int j=0;j<sp.m;j++){ for(int jlen=0;jlen<sp.l;jlen++){ cerr<<"("<<j<<","<<jlen<<")=>(" <<target_best[j][jlen].first <<" "<<target_best[j][jlen].second<<") "; } cerr<<endl; } //viterbi vector<pair<double,int> > viterbi(sp.m,pair<double,int>(0.0,0)); for(int i=0;i<sp.l&&i<sp.m;i++){ viterbi[i]=pair<double,int>(target_probs[0][i],-1); } for(int i=1;i<(int)viterbi.size();i++){ for(int j=1;j<=sp.l&&i-j>=0;j++){ if(viterbi[i-j].first*target_probs[i-j+1][j-1]>viterbi[i].first) viterbi[i]= make_pair(viterbi[i-j].first*target_probs[i-j+1][j-1],i-j); } } int pos=sp.m-1; string sequence=""; string source=""; while(pos>=0){ sequence=to_string(viterbi[pos].second+1)+","+to_string(pos) +" "+sequence; cout<<viterbi[pos].second+1<<","<<pos-viterbi[pos].second<<endl; pair<int,int> srcpair= target_best[viterbi[pos].second+1][pos-viterbi[pos].second]; source=to_string(srcpair.first)+","+ to_string(srcpair.second) +" "+source; pos=viterbi[pos].second; } cout<<"best seg:"<<sequence<<endl; cout<<" src:"<<source<<endl; } }
void MP1:: expectation(CorpusCache& cache){ double& alpha=alpha_; double alphaCount=0; for(auto& sp: cache){ vector<vector<double>> target_probs(sp.m,vector<double>(sp.l,0.0)); alpha/=sp.n*sp.l; for(int j=0;j<sp.m;j++){ for(int jlen=0;jlen<sp.l;jlen++){ for(int i=0;i<sp.n;i++){ for(int ilen=0;ilen<sp.l;ilen++){ if(sp(i,ilen,j,jlen)!=(void*)0){ target_probs[j][jlen]+= (sp(i,ilen,j,jlen)->prob*alpha); if(sp(i,ilen,j,jlen)->prob>1){ cerr<<"wth prob>1 : " <<sp(i,ilen,j,jlen)->prob<<endl; } } } } //cout<<target_probs[j][jlen]<<" "; } //cout<<endl; } //cout<<endl; for(int j=0;j<sp.m;j++){ for(int jlen=0;jlen<sp.l;jlen++){ if(target_probs[j][jlen]>1) cerr<<"error :"<<target_probs[j][jlen]<<endl; if(target_probs[j][0]==0){ target_probs[j][0]=1E-7; //cerr<<"reset error target["<<j<<",0]"<<endl; } } } vector<LogProb> forward(sp.m,0.0),backward(sp.m,0.0); if(specs.logEM){ for(auto& i:forward)i=-1E10; for(auto& i:backward)i=-1E10; } //forward[i] is the posterior probability of target words of 1...i+1 for(int i=0;i<sp.l&&i<sp.m;i++) forward[i]=target_probs[0][i]; for(int i=1;i<(int)forward.size();i++){ for(int j=1;j<=sp.l&&i-j>=0;j++){ forward[i]+=forward[i-j]*(LogProb)target_probs[i-j+1][j-1]; } } //backward[i] is the posterior probability of target words of i+1...m for(int i=0;i<sp.l&&i<sp.m;i++) backward[sp.m-i-1]=target_probs[sp.m-i-1][i]; for(int i=sp.m-2;i>=0;i--){ for(int j=1;j<=sp.l&&i+j<sp.m;j++){ backward[i]+=(LogProb)target_probs[i][j-1]*backward[i+j]; } } //viterbi vector<pair<double,int> > viterbi(sp.m,pair<double,int>(0.0,0)); for(int i=0;i<sp.l&&i<sp.m;i++) viterbi[i]=pair<double,int>(target_probs[0][i],-1); for(int i=1;i<(int)forward.size();i++){ for(int j=1;j<=sp.l&&i-j>=0;j++){ if(viterbi[i-j].first*target_probs[i-j+1][j-1]>viterbi[i].first) viterbi[i]= make_pair(viterbi[i-j].first*target_probs[i-j+1][j-1],i-j); } } int pos=sp.m-1; string sequence=""; while(pos>=0){ sequence=to_string(pos)+" "+sequence; pos=viterbi[pos].second; } //cout<<"best seg:"<<sequence<<endl; //make sure forward[sp.m-1]==backward[0]; assert(backward[0]>(LogProb)0); if(abs(forward[sp.m-1]-backward[0])>=(LogProb)1e-5*backward[0]) cerr<<forward[sp.m-1]<<", "<<backward[0]<<endl; assert(abs(forward[sp.m-1]-backward[0])<(LogProb)1e-5*backward[0]); //cerr<<"backward[0]:"<<backward[0]<<endl; //collect fractional count for each phrase pair //fraccount=forward[j]*backward[j+jlen]*p(t|s)/backward[0]; for(int j=0;j<sp.m;j++){ for(int jlen=0;jlen<sp.l&&j+jlen+1<=sp.m;jlen++){ double segprob=0; LogProb before=1; LogProb after=1; if(j>0)before=forward[j-1]; if(j+jlen+1<sp.m)after=backward[j+jlen+1]; segprob=before*after*(LogProb)target_probs[j][jlen] /backward[0]; if(segprob>1||segprob<=0){ //cerr<<"segprob "<<segprob<<","<<j<<","<<jlen<<endl; } if(segprob<=0)continue; for(int i=0;i<sp.n;i++){ for(int ilen=0;ilen<sp.l&&ilen+i+1<=sp.n;ilen++){ if(sp(i,ilen,j,jlen)!=(void*)0){ double count=sp(i,ilen,j,jlen)->prob*segprob*alpha /target_probs[j][jlen]; sp(i,ilen,j,jlen)->count+=count; //cerr<<"before update"<<endl; //sp(i,ilen,j,jlen)->fractype.print(cerr); sp(i,ilen,j,jlen)->fractype.updateLog(count); //cerr<<"after update"<<endl; //sp(i,ilen,j,jlen)->fractype.print(cerr); alphaCount+=count; if(count>1+1e-5) cerr<<i<<","<<ilen<<","<<j <<","<<jlen<<" ["<<sp.m<<","<<sp.n<<"]" <<",count "<<count <<", target probs " <<target_probs[j][jlen]<<endl; } } } } } alpha*=sp.n*sp.l; } //cerr<<alphaCount<<","<<cache.size()<<endl; alpha=alphaCount/(alphaCount+cache.size()); }
/****************************************************************************** mergingAndClustering() : Clustering of GMMs and Realignment; Merging of states inputs : features - pointer to all feature vectors, allMixtureMeans, allMixtureVars numstates, numMixEachState, totalNumFeatures, posterior - posterior probability matrix, mixtureElemCount - Element count in each mixture outputs : Perform viterbi realignment, clustering and merging of states or GMMs ******************************************************************************/ void ClusteringAndMerging(VECTOR_OF_F_VECTORS *features, VECTOR_OF_F_VECTORS *allMixtureMeans, VECTOR_OF_F_VECTORS *allMixtureVars, int *numStates, int *numMixEachState, int totalNumFeatures, float **posterior, float **mixtureElemCount, int *numElemEachState, float *Pi, float *mixtureWeight) { // local Variable declaration int VQIter = 7, GMMIter = 23, mergeIter=0, maxMergeIter = 16; int viterbiIter = 5; int i = 0, j = 0, k = 0,s= 0, flag = 1; float *T1[MAX_NUM_STATES]; int *T2[MAX_NUM_STATES]; int *newStateSeq; float *deltaBIC[MAX_NUM_STATES]; for(i = 0; i < (*numStates); i++){ deltaBIC[i] = (float *)calloc((*numStates), sizeof(float)); } for(i = 0; i < (*numStates); i++){ T1[i] = (float *)calloc(totalNumFeatures, sizeof(float)); T2[i] = (int *)calloc(totalNumFeatures, sizeof(int)); } // Merge two GMM States or two mixture models //perform the steps repeatedly till there are no more states to be merged while(flag && mergeIter < maxMergeIter){ printf("\nClustering and Merging Iteration: %d...........\n", mergeIter); printf("starting with, States: %d \n", *numStates); mergeIter++; for(s = 0; s < *numStates; s++) printf("state[%d] : %d \n", s, numElemEachState[s]); for(i = 0; i < viterbiIter; i++){ //perform Viterbi Realignment printf("performing viterbi realignment....\n"); newStateSeq = viterbi( features , numStates, allMixtureMeans, allMixtureVars, numMixEachState, totalNumFeatures, posterior, numElemEachState, T1, T2, Pi, mixtureWeight); printf("Viterbi realignment has successfully completed...\n"); //find number of elements in each state //FindNumberOfElemInEachState(newStateSeq, numStates, totalNumFeatures, numElemEachState, Pi); //perform GMM clustering for all states for(s = 0; s < (*numStates); s++){ // find all elements present in state s using viterbi_realignment int count = 0, d = 0; // to count number of features in a state for(j = 0; j < totalNumFeatures; j++){ if(newStateSeq[j] == s){ for(d = 0; d < DIM; d++){ featuresForClustering[count]->array[d] = features[j]->array[d]; featuresForClustering[count]->numElements = DIM; } count++;//increment count } } extern VECTOR_OF_F_VECTORS *mixtureMeans, *mixtureVars; extern float probScaleFactor; extern int varianceNormalize, ditherMean; int numFeatures = count; //printf("count: %d num: %d\n", count, numElemEachState[s]); int numMix = numMixEachState[s]; // Cluster using GMM ComputeGMM(featuresForClustering, numFeatures, mixtureMeans, mixtureVars, mixtureElemCount[s], numMix , VQIter, GMMIter, probScaleFactor, ditherMean, varianceNormalize, time(NULL)); int mixCount = 0, k=0; //store current mean and variance into all means and variance for(j = 0; j < s; j++) mixCount += numMixEachState[j]; for(j = mixCount; j < mixCount + numMixEachState[s]; j++){ for(k = 0; k < DIM; k++){ allMixtureMeans[j]->array[k] = mixtureMeans[j-mixCount]->array[k]; allMixtureVars[j]->array[k] = mixtureVars[j-mixCount]->array[k]; } float mix_wt = mixtureElemCount[s][j-mixCount] / numElemEachState[s]; mixtureWeight[j] = mix_wt; } }//GMM Clustering for each state has completed //calculate posterior probabilities PrintAllDetails(numStates, numMixEachState, numElemEachState, mixtureElemCount, allMixtureMeans, mixtureWeight); ComputePosteriorProb(features, posterior, allMixtureMeans, allMixtureVars, numStates, numMixEachState, totalNumFeatures, mixtureWeight); } // PrintAllDetails(numStates, numMixEachState, numElemEachState, // mixtureElemCount, allMixtureMeans, mixtureWeight); // Calculate BIC Value between Each state CalculateBIC(deltaBIC, features , allMixtureMeans, allMixtureVars, numStates, totalNumFeatures, newStateSeq, numMixEachState , numElemEachState, posterior); int min_i =0, min_j = 0; float min = 99999999; // find minimum delta BIC states for(j = 0; j < *numStates; j++){ for(k = j+1; k < *numStates; k++){ if(deltaBIC[j][k] < min){ min = deltaBIC[j][k]; min_i = j; min_j = k; } } } printf("min_i: %d min_j: %d minDBIC: %f\n", min_i, min_j, deltaBIC[min_i][min_j]); // if no two states can be merged set the flag to False to terminate process if(deltaBIC[min_i][min_j] >= 0){ printf("We need to stop now ..... Final no of states: %d\n", *numStates); flag = 0; } // Merge two states if(flag) MergeTwoStates( min_i, min_j, allMixtureMeans, allMixtureVars, numStates, numMixEachState, numElemEachState, Pi, totalNumFeatures, features, newStateSeq, mixtureWeight); /*printf("Means after Merging of two states.................\n"); PrintAllDetails(numStates, numMixEachState, numElemEachState, mixtureElemCount, allMixtureMeans);*/ for(i = 0; i < *numStates; i++) printf("mix[%d]: %d\n", i, numMixEachState[i]); } //WRITE PLOT_File to plot distribution of each data point writePlotFile(posterior, totalNumFeatures, numStates); //WRITE RTTM FILE writeRTTMFile(newStateSeq, numStates, totalNumFeatures, numElemEachState); }
// process the given utterance // - handles multiple pronunciations // - handles optional symbols (typically silence+fillers) Alignment *ViterbiX::processUtterance(VLexUnit &vLexUnitTranscription, bool bMultiplePronunciations, VLexUnit &vLexUnitOptional, MatrixBase<float> &mFeatures, double *dUtteranceLikelihood, int &iErrorCode) { //double dTimeBegin = TimeUtils::getTimeMilliseconds(); // make sure there is at least one lexical unit to align to if (vLexUnitTranscription.empty()) { iErrorCode = ERROR_CODE_EMPTY_TRANSCRIPTION; return NULL; } // create the HMM-graph int iNodes = -1; int iEdges = -1; FBNodeHMM *nodeInitial = NULL; FBNodeHMM *nodeFinal = NULL; HMMGraph *hmmGraph = new HMMGraph(m_phoneSet,m_lexiconManager, m_hmmManager,m_hmmManager,bMultiplePronunciations,vLexUnitOptional); FBNodeHMM **nodes = hmmGraph->create(vLexUnitTranscription,&iNodes,&iEdges,&nodeInitial,&nodeFinal); if (nodes == NULL) { delete hmmGraph; iErrorCode = ERROR_CODE_UNABLE_TO_CREATE_HMM_GRAPH; return NULL; } delete hmmGraph; assert(nodeInitial->iDistanceEnd % NUMBER_HMM_STATES == 0); // there can't be fewer feature vectors than HMM-states in the composite int iFeatures = mFeatures.getRows(); if (iFeatures < nodeInitial->iDistanceEnd) { HMMGraph::destroy(nodes,iNodes); iErrorCode = ERROR_CODE_INSUFFICIENT_NUMBER_FEATURE_VECTORS; return NULL; } // reset the emission probability computation (to avoid using cached computations that are outdated) VHMMStateDecoding vHMMState; for(int i=0 ; i < iNodes ; ++i) { for(FBEdgeHMM *edge = nodes[i]->edgeNext ; edge != NULL ; edge = edge->edgePrev) { assert(edge->hmmStateEstimation != NULL); vHMMState.push_back((HMMStateDecoding*)edge->hmmStateEstimation); } } m_hmmManager->resetHMMEmissionProbabilityComputation(vHMMState); // do the actual Viterbi pass int iErrorCodeFB = -1; VTrellisNode *trellis = viterbi(mFeatures,iNodes,nodes,iEdges, nodeInitial,nodeFinal,m_fPruningBeam,&iErrorCodeFB); if (trellis == NULL) { HMMGraph::destroy(nodes,iNodes); iErrorCode = iErrorCodeFB; return NULL; } // get the maximum viterbi score from the terminal edges double dViterbiBest = -DBL_MAX; FBEdgeHMM *edgeBest = NULL; for(FBEdgeHMM *edge = nodeFinal->edgePrev ; edge != NULL ; edge = edge->edgeNext) { if (trellis[(iFeatures-1)*iEdges+edge->iEdge].dViterbi > dViterbiBest) { edgeBest = edge; dViterbiBest = trellis[(iFeatures-1)*iEdges+edge->iEdge].dViterbi; } } assert(edgeBest != NULL); // utterance likelihood assert(dViterbiBest != -DBL_MAX); assert(edgeBest != NULL); double dLikelihoodUtterance = dViterbiBest; //countUnusedPositions(trellis,iFeatures,iNodes); Alignment *alignment = new Alignment(ALIGNMENT_TYPE_VITERBI); FBEdgeHMM *edgeTmp = edgeBest; int iState = 0; int iFrameEnd = -1; int iStatesLeft = 1; LexUnit *lexUnit = NULL; for(int t = iFeatures-1 ; t >= 0 ; --t) { FBEdgeHMM *edgePrevBest = NULL; double dViterbiPrevBest = -DBL_MAX; // self-transition if (trellis[t*iEdges+edgeTmp->iEdge].dViterbi > dViterbiPrevBest) { dViterbiPrevBest = trellis[t*iEdges+edgeTmp->iEdge].dViterbi; edgePrevBest = edgeTmp; } // previous nodes for(FBEdgeHMM *edge = edgeTmp->nodePrev->edgePrev ; edge != NULL ; edge = edge->edgeNext) { if (trellis[t*iEdges+edge->iEdge].dViterbi != -DBL_MAX) { if (trellis[t*iEdges+edge->iEdge].dViterbi > dViterbiPrevBest) { dViterbiPrevBest = trellis[t*iEdges+edge->iEdge].dViterbi; edgePrevBest = edge; } } } HMMStateDecoding *hmmStateDecoding = (HMMStateDecoding*)edgePrevBest->hmmStateUpdate; // state-level alignment VStateOcc *vStateOcc = new VStateOcc; vStateOcc->push_back(Alignment::newStateOcc(hmmStateDecoding->getId(),1.0)); alignment->addFrameAlignmentFront(vStateOcc); // word-level alignment if (hmmStateDecoding->getState() != iState) { --iStatesLeft; } iState = hmmStateDecoding->getState(); if (iStatesLeft == 0) { iStatesLeft = (int)(edgePrevBest->lexUnit->vPhones.size()*NUMBER_HMM_STATES); if (lexUnit != NULL) { alignment->addLexUnitAlignmentFront(t+1,iFrameEnd,lexUnit); } iFrameEnd = t; lexUnit = edgePrevBest->lexUnit; } edgeTmp = edgePrevBest; } if ((iStatesLeft == 1) && (lexUnit != NULL)) { alignment->addLexUnitAlignmentFront(0,iFrameEnd,lexUnit); } // TODO if multiple pronunciations are allowed the alternatives at each edge might be wrong due to the // path recombination in HMMGraph, this needs to be addressed //double dTimeEnd = TimeUtils::getTimeMilliseconds(); //double dTimeSeconds = (dTimeEnd-dTimeBegin)/1000.0; //printf("alignment: %12.4f (%12.4f seconds)\n",dViterbiBest,dTimeSeconds); // clean-up deleteTrellis(trellis); HMMGraph::destroy(nodes,iNodes); *dUtteranceLikelihood = dLikelihoodUtterance; iErrorCode = UTTERANCE_PROCESSED_SUCCESSFULLY; return alignment; }