// print the features (debugging) void FeatureFile::print(MatrixBase<float> &mFeatures, unsigned int iDelta) { assert((mFeatures.getCols()%iDelta) == 0); cout << endl; for(unsigned int i=0 ; i < mFeatures.getRows() ; ++i) { for(unsigned int j=0 ; j < iDelta ; ++j) { for(unsigned int h=0 ; h < mFeatures.getCols()/iDelta ; ++h) { cout << " " << FLT(9,6) << mFeatures(i,h+j*(mFeatures.getCols()/iDelta)); } cout << endl; } cout << endl; } }
// feed adaptation data from an alignment void MLLRManager::feedAdaptationData(MatrixBase<float> &mFeatures, Alignment *alignment, double *dLikelihood) { // sanity check unsigned int iFeatures = mFeatures.getRows(); assert(iFeatures == alignment->getFrames()); m_iAdaptationFrames += iFeatures; *dLikelihood = 0.0; for(unsigned int t=0 ; t<iFeatures ; ++t) { FrameAlignment *frameAlignment = alignment->getFrameAlignment(t); VectorStatic<float> vFeatureVector = mFeatures.getRow(t); for(FrameAlignment::iterator it = frameAlignment->begin() ; it != frameAlignment->end() ; ++it) { HMMStateDecoding *hmmStateDecoding = m_hmmManager->getHMMStateDecoding((*it)->iHMMState); // compute the contribution of each Gaussian // (case 1) all the frame-level adaptation data goes to the best scoring Gaussian component (faster) if (m_bBestComponentOnly) { float fLikelihood = -FLT_MAX; GaussianDecoding *gaussian = hmmStateDecoding->getBestScoringGaussian(vFeatureVector.getData(),&fLikelihood); *dLikelihood += std::max<float>(fLikelihood,LOG_LIKELIHOOD_FLOOR); GaussianStats *gaussianStats = NULL; if (m_gaussianStats[gaussian->iId] == NULL) { gaussianStats = new GaussianStats; gaussianStats->gaussian = gaussian; gaussianStats->dOccupation = 0.0; gaussianStats->vObservation = new Vector<double>(m_iDim); gaussianStats->vObservation->zero(); m_gaussianStats[gaussian->iId] = gaussianStats; } else { gaussianStats = m_gaussianStats[gaussian->iId]; } gaussianStats->dOccupation += 1.0; gaussianStats->vObservation->add(1.0,vFeatureVector); m_regressionTree->accumulateStatistics(vFeatureVector.getData(),1.0,gaussianStats); } // (case 2) adaptation data is shared across all components (slightly more accurate) else { double *dProbGaussian = new double[hmmStateDecoding->getGaussianComponents()]; double dProbTotal = 0.0; for(int g=0 ; g < hmmStateDecoding->getGaussianComponents() ; ++g) { dProbGaussian[g] = exp(hmmStateDecoding->computeGaussianProbability(g,vFeatureVector.getData())); dProbTotal += dProbGaussian[g]; assert((finite(dProbGaussian[g])) && (finite(dProbTotal))); } *dLikelihood += max(log(dProbTotal),LOG_LIKELIHOOD_FLOOR); for(int g=0 ; g < hmmStateDecoding->getGaussianComponents() ; ++g) { dProbGaussian[g] /= dProbTotal; double dOccupation = dProbGaussian[g]*1.0; GaussianDecoding *gaussian = hmmStateDecoding->getGaussian(g); GaussianStats *gaussianStats = NULL; if (m_gaussianStats[gaussian->iId] == NULL) { gaussianStats = new GaussianStats; gaussianStats->gaussian = gaussian; gaussianStats->dOccupation = 0.0; gaussianStats->vObservation = new Vector<double>(m_iDim); gaussianStats->vObservation->zero(); m_gaussianStats[gaussian->iId] = gaussianStats; } else { gaussianStats = m_gaussianStats[gaussian->iId]; } gaussianStats->dOccupation += dOccupation; gaussianStats->vObservation->add(dOccupation,vFeatureVector); m_regressionTree->accumulateStatistics(vFeatureVector.getData(),dOccupation,gaussianStats); } delete [] dProbGaussian; } } } }
// feed adaptation data from an alignment into the adaptation process // note: it is possible to accumulate statistics at the Gaussian component or at the transform level // - Gaussian component level: O(n^2) per Gaussian component // - Transform level: O(n^3) per transform + O(n) per Gaussian component void FMLLREstimator::feedAdaptationData(MatrixBase<float> &mFeatures, Alignment *alignment, double *dLikelihood) { // sanity check assert((unsigned int)mFeatures.getRows() == alignment->getFrames()); m_fOccupancyTotal += mFeatures.getRows(); *dLikelihood = 0.0; for(unsigned int t=0 ; t<mFeatures.getRows() ; ++t) { VectorStatic<float> vFeatureVector = mFeatures.getRow(t); // extended observation vector Vector<double> vObsEx(vFeatureVector); vObsEx.appendFront(1.0); // for each HMM-state the observation is assigned to FrameAlignment *frameAlignment = alignment->getFrameAlignment(t); for(FrameAlignment::iterator it = frameAlignment->begin() ; it != frameAlignment->end() ; ++it) { HMMStateDecoding *hmmStateDecoding = m_hmmManager->getHMMStateDecoding((*it)->iHMMState); // compute the contribution of each Gaussian // (case 1) all the frame-level adaptation data goes to the best scoring Gaussian component (faster) if (m_bBestComponentOnly) { float fLikelihood = -FLT_MAX; GaussianDecoding *gaussian = hmmStateDecoding->getBestScoringGaussian(vFeatureVector.getData(),&fLikelihood); *dLikelihood += std::max<float>(fLikelihood,LOG_LIKELIHOOD_FLOOR); Vector<float> vCovariance(VectorStatic<float>(gaussian->fCovariance,m_iDim)); #ifdef OPTIMIZED_COMPUTATION vCovariance.mul(2.0); vCovariance.invertElements(); #endif // accumulate data for each G(i) m_matrixAux->zero(); m_matrixAux->addVecMul(1.0,vObsEx,vObsEx); for(int i=0 ; i < m_iDim; ++i) { double dCovInv = 1.0/vCovariance(i); m_matrixG[i]->add(dCovInv*1.0,*m_matrixAux); } // accumulate data for each k(i) for(int i=0 ; i < m_iDim ; ++i) { double dConstant = (gaussian->fMean[i]/vCovariance(i))*1.0; m_matrixK->getRow(i).add(dConstant,vObsEx); } } // (case 2) adaptation data is shared across all components (slightly more accurate) else { double *dProbGaussian = new double[hmmStateDecoding->getGaussianComponents()]; double dProbTotal = 0.0; for(int g=0 ; g < hmmStateDecoding->getGaussianComponents() ; ++g) { dProbGaussian[g] = exp(hmmStateDecoding->computeGaussianProbability(g,vFeatureVector.getData())); dProbTotal += dProbGaussian[g]; assert((finite(dProbGaussian[g])) && (finite(dProbTotal))); } *dLikelihood += max(log(dProbTotal),LOG_LIKELIHOOD_FLOOR); for(unsigned int iGaussian = 0 ; iGaussian < hmmStateDecoding->getMixtureSize() ; ++iGaussian) { GaussianDecoding *gaussian = hmmStateDecoding->getGaussian(iGaussian); double dGaussianOccupation = dProbGaussian[iGaussian]/dProbTotal; Vector<float> vCovariance(VectorStatic<float>(gaussian->fCovariance,m_iDim)); #ifdef OPTIMIZED_COMPUTATION vCovariance.mul(2.0); vCovariance.invertElements(); #endif // accumulate data for each G(i) m_matrixAux->zero(); m_matrixAux->addVecMul(1.0,vObsEx,vObsEx); for(int i=0 ; i < m_iDim; ++i) { double dCovInv = 1.0/vCovariance(i); m_matrixG[i]->add(dCovInv*dGaussianOccupation,*m_matrixAux); } // accumulate data for each k(i) for(int i=0 ; i < m_iDim ; ++i) { double dConstant = (gaussian->fMean[i]/vCovariance(i))*dGaussianOccupation; m_matrixK->getRow(i).add(dConstant,vObsEx); } } delete [] dProbGaussian; } } } }