00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #if !defined(ALIZE_FactorAnalysis_cpp)
00056 #define ALIZE_FactorAnalysis_cpp
00057
00058 #include<FactorAnalysis.h>
00059 #include<iostream>
00060 #include<fstream>
00061 #include<cstdio>
00062 #include<cassert>
00063 #include<cmath>
00064 #include "SuperVectors.h"
00065 #include "RealVector.h"
00066 #if defined(THREAD)
00067 #include <pthread.h>
00068 #endif
00069
00070 using namespace alize;
00071 using namespace std;
00072
00073 FactorAnalysisStat::FactorAnalysisStat(String & featFilename,FeatureServer & fs,Config & config):_ms(config),_ss(config){
00074 XList faNdx;
00075 XLine featLine;
00076 featLine.addElement(featFilename);
00077 faNdx.addLine()=featLine;
00078 _init(faNdx,fs,config);
00079 }
00080
00081 FactorAnalysisStat::FactorAnalysisStat(XList & ndx,FeatureServer & fs,Config & config):_ms(config),_ss(config){
00082 _init(ndx,fs,config);
00083 }
00084
00085 void FactorAnalysisStat::_init(XList & ndx,FeatureServer & fs,Config & config){
00086 fileList=ndx;
00087 _nb_speakers=fileList.getLineCount();
00088 _nb_sent=fileList.getAllElements().getElementCount();
00089
00090 _ndxTable=Translate(ndx);
00091 _topGauss=config.existsParam("topGauss");
00092 if (verbose) cout << "(FactorAnalysisStat) Estimate FA stats on "<<_nb_sent<< " example(s) with "<<_nb_speakers<<" speaker(s)"<<endl;
00093
00094 _ms.loadMixtureGD(config.getParam("inputWorldFilename"));
00095 _ms.loadMixtureGD(config.getParam("inputWorldFilename"));
00096
00097 MixtureGD & UBM=_ms.getMixtureGD((unsigned long) 0);
00098
00099 if (verbose) cout <<"(FactorAnalysisStat) Model parameter Dim:" <<UBM.getVectSize()<<"___nbC:" <<UBM.getDistribCount()<<endl;
00100
00101 _vsize=UBM.getVectSize();
00102 _mixsize=UBM.getDistribCount();
00103 _supervsize=_vsize*_mixsize;
00104 _D.setSize(_supervsize);
00105
00106
00107 _matU=Matrix<double>();
00108 if (config.existsParam("initChannelMatrix")) {
00109 _matU.load(config.getParam("initChannelMatrix"),config);
00110 if (_matU.cols()>_matU.rows()) _matU.transpose();
00111 if (verbose) cout << "(FactorAnalysisStat) Init for Channel Matrix: "<< config.getParam("initChannelMatrix")<< ", rank: ["<<_matU.cols() << "] sv size: [" << _matU.rows() <<"]"<<endl;
00112 _rang=_matU.cols();
00113 if (UBM.getDistribCount()*UBM.getVectSize()!=_matU.rows()) throw Exception("Supervector size does not match with UBM model",__FILE__,__LINE__);
00114 }
00115 else {
00116 _rang=config.getParam("channelMatrixRank").toLong();
00117 _matU.setDimensions(_supervsize,_rang);
00118 srand48(_supervsize*_rang);
00119 _matU.randomInit();
00120 if (verbose) cout << "(FactorAnalysisStat) Random Init for Channel Matrix: "<<", rank: ["<<_matU.cols() << "] sv size: [" << _matU.rows() <<"]"<<endl;
00121 }
00122
00123
00124 _matY=Matrix<double>(_nb_speakers,_supervsize);
00125 _matX=Matrix<double>(_nb_sent,_rang);
00126 _matS_X=Matrix<double>(_nb_speakers,_supervsize);
00127 _matS_X_h=Matrix<double>(_nb_sent,_supervsize);
00128 _matN_h=Matrix<double>(_nb_sent,_mixsize);
00129 _matN=Matrix<double>(_nb_speakers,_mixsize);
00130
00131 _matY.setAllValues(0.0);
00132 _matX.setAllValues(0.0);
00133 _matS_X.setAllValues(0.0);
00134 _matS_X_h.setAllValues(0.0);
00135 _matN_h.setAllValues(0.0);
00136 _matN.setAllValues(0.0);
00137
00138 _super_mean.setSize(_supervsize);
00139 _super_invvar.setSize(_supervsize);
00140 _tau=config.getParam("regulationFactor").toDouble();
00141 if (verbose) cout << "(FactorAnalysisStat) Regulation Factor ["<<_tau<<"]"<<endl;
00142
00143 for(unsigned long i=0;i<_mixsize;i++){
00144 DistribGD & aux=UBM.getDistrib(i);
00145 RealVector <double> & v=aux.getCovInvVect();
00146 RealVector <double> & u=aux.getMeanVect();
00147 for(unsigned long j=0;j<_vsize;j++){
00148 _D[i*_vsize+j]=sqrt(1.0/(v[j]*_tau));
00149 _super_mean[i*_vsize+j]=u[j];
00150 _super_invvar[i*_vsize+j]=v[j];
00151 }
00152 }
00153
00154
00155 if (verboseLevel > 1) cout <<"(FactorAnalysisStat) Number of examples " << _nb_sent << endl;
00156 for(unsigned long i=0;i<_nb_sent;i++) {
00157 _l_h_inv.addObject(*(new DoubleSquareMatrix()),i);
00158 _l_h_inv[i].setSize(_rang);
00159 }
00160 if (verboseLevel >1) cout << "(FactorAnalysisStat) Y dimensions are: " << _matY.rows() <<","<<_matY.cols()<<"__ X dimensions are: "<< _matX.rows() <<","<< _matX.cols() <<endl << "(FactorAnalysisStat) FA Accumator Built"<<endl;
00161 };
00162
00163 void FactorAnalysisStat::computeAndAccumulateGeneralFAStats(FeatureServer &fs,Config & config){
00164 SegServer segmentsServer;
00165 LabelServer labelServer;
00166 initializeClusters(fileList,segmentsServer,labelServer,config);
00167 verifyClusterFile(segmentsServer,fs,config);
00168 unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
00169 SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);
00170 this->computeAndAccumulateGeneralFAStats(selectedSegments,fs,config);
00171 };
00172
00173 void FactorAnalysisStat::computeAndAccumulateGeneralFAStats(SegCluster &selectedSegments,FeatureServer &fs,Config & config){
00174 if (verbose) cout <<"(FactorAnalysisStat) Compute General FA Stats (Complete)" << endl;
00175 double *N_h, *N, *S_X_h, *S_X,*ff;
00176 _matN_h.setAllValues(0.0);
00177 _matN.setAllValues(0.0);
00178 _matS_X_h.setAllValues(0.0);
00179 _matS_X.setAllValues(0.0);
00180 N_h=_matN_h.getArray(); N=_matN.getArray(); S_X_h=_matS_X_h.getArray();S_X=_matS_X.getArray();
00181
00182 MixtureGD & UBM=_ms.getMixtureGD((unsigned long) 1);
00183 MixtureGDStat &acc=_ss.createAndStoreMixtureStat(UBM);
00184
00185
00186 acc.resetOcc();
00187 Seg *seg;
00188 selectedSegments.rewind();
00189 String currentSource="";unsigned long loc=0;unsigned long sent=0;
00190 while((seg=selectedSegments.getSeg())!=NULL){
00191 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());
00192 if (currentSource!=seg->sourceName()) {
00193 currentSource=seg->sourceName();
00194 loc=_ndxTable.locNb(currentSource);
00195 sent=_ndxTable.sessionNb(currentSource);
00196 if (verbose)cout << "Processing speaker["<<currentSource<<"]"<< endl;
00197 }
00198
00199 fs.seekFeature(begin);
00200 Feature f;
00201 if (!_topGauss) {
00202 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
00203 fs.readFeature(f);
00204 acc.computeAndAccumulateOcc(f);
00205 RealVector <double> aPost=acc.getOccVect();
00206 ff=f.getDataVector();
00207 for(unsigned long k=0;k<_mixsize;k++) {
00208 N_h[sent*_mixsize+k]+=aPost[k];
00209 N[loc*_mixsize+k] +=aPost[k];
00210 for (unsigned long i=0;i<_vsize;i++) {
00211 S_X_h[sent*_supervsize+(k*_vsize+i)]+=aPost[k]*ff[i];
00212 S_X[loc*_supervsize+(k*_vsize+i)] +=aPost[k]*ff[i];
00213 }
00214 }
00215 }
00216 }
00217 else throw Exception("ComputeGeneralStats TopGauss not done at this level",__FILE__,__LINE__);
00218 }
00219 };
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 void FactorAnalysisStat::substractSpeakerStats(){
00323 if (verbose) cout <<"(FactorAnalysisStat) Compute and Substract Speaker FA Stats... " << endl;
00324 RealVector <double> AUX1;AUX1.setSize(_supervsize); AUX1.setAllValues(0.0); double *aux1=AUX1.getArray();
00325
00326
00327 unsigned long loc=0;
00328 unsigned long sent=0;
00329 XLine *pline; String *pFile; fileList.rewind();
00330
00331 double *N_h=_matN_h.getArray();
00332 double *S_X_h=_matS_X_h.getArray();
00333
00334 while((pline=fileList.getLine())!=NULL) {
00335 while((pFile=pline->getElement())!=NULL) {
00336 this->getMplusDY(AUX1,*pFile);
00337 for(unsigned long k=0;k<_mixsize;k++)
00338 for (unsigned long i=0;i<_vsize;i++)
00339 S_X_h[sent*_supervsize+(k*_vsize+i)]-= N_h[sent*_mixsize+k]*aux1[i+k*_vsize];
00340 sent++;
00341 }
00342 loc++;
00343 }
00344 if (verboseLevel >1) cout << "(FactorAnalysisStat) Done "<<endl;
00345 };
00346
00347 void FactorAnalysisStat::substractChannelStats(){
00348 if (verbose) cout <<"(FactorAnalysisStat) Compute and Substract Channel FA Stats... "<<endl;
00349 RealVector <double> UX;UX.setSize(_supervsize); UX.setAllValues(0.0);double* ux=UX.getArray();
00350
00351
00352 unsigned long loc=0;
00353 unsigned long sent=0;
00354 XLine *pline; String *pFile;
00355 fileList.rewind();
00356
00357 double *super_mean=_super_mean.getArray();
00358 double *N_h=_matN_h.getArray();
00359 double *S_X=_matS_X.getArray();
00360
00361 while((pline=fileList.getLine())!=NULL) {
00362 while((pFile=pline->getElement())!=NULL) {
00363 this->getUX(UX,*pFile);
00364 for(unsigned long k=0;k<_supervsize;k++)
00365 ux[k]+=super_mean[k];
00366
00367 for(unsigned long k=0;k<_mixsize;k++)
00368 for (unsigned long i=0;i<_vsize;i++)
00369 S_X[loc*_supervsize+(k*_vsize+i)]-= N_h[sent*_mixsize+k]*ux[i+k*_vsize];
00370 sent++;
00371 }
00372 loc++;
00373 }
00374 };
00375
00376
00377 void FactorAnalysisStat::getXEstimate(){
00378 if (verbose) cout << "(FactorAnalysisStat) Compute X Estimate "<<endl;
00379 RealVector <double> AUX;
00380 AUX.setSize(_rang);
00381 XLine *pline;
00382 String *pFile;
00383
00384 _matX.setAllValues(0.0);
00385
00386 double *X=_matX.getArray();
00387 double *U=_matU.getArray();
00388 double *S_X_h=_matS_X_h.getArray();
00389 double *aux=AUX.getArray();
00390 double *super_invvar=_super_invvar.getArray();
00391
00392 fileList.rewind();
00393 while((pline=fileList.getLine())!=NULL) {
00394 while((pFile=pline->getElement())!=NULL) {
00395 unsigned long sent=_ndxTable.sessionNb(*pFile);
00396 AUX.setAllValues(0.0);
00397 for(unsigned long i=0;i<_rang;i++)
00398 for(unsigned long k=0;k<_supervsize;k++)
00399 aux[i]+= U[k*_rang+i]*super_invvar[k]*S_X_h[sent*_supervsize+k];
00400 double *l_h_inv=_l_h_inv[sent].getArray();
00401 for(unsigned long i=0;i<_rang;i++)
00402 for(unsigned long k=0;k<_rang;k++)
00403 X[sent*_rang+i]+=l_h_inv[i*_rang+k]*aux[k];
00404 sent++;
00405 }
00406 }
00407 };
00408
00409 void FactorAnalysisStat::estimateAndInverseL(Config & config){
00410 #if defined(THREAD)
00411 if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0) estimateAndInverseLThreaded(config.getParam("numThread").toLong());
00412 else estimateAndInverseLUnThreaded();
00413 #else
00414 estimateAndInverseLUnThreaded();
00415 #endif
00416 };
00417
00418 void FactorAnalysisStat::estimateAndInverseLUnThreaded(){
00419 if (verbose) cout << "(FactorAnalysisStat) Inverse L Matrix ... "<<endl;
00420 unsigned long mk;
00421 DoubleSquareMatrix L(_rang);
00422 L.setAllValues(0.0);
00423 RealVector <double> AUX;
00424 AUX.setSize(_rang);
00425 unsigned long sent=0;
00426 XLine *pline;
00427 String *pFile;
00428 fileList.rewind();
00429
00430 double *N_h=_matN_h.getArray();
00431 double *U=_matU.getArray();
00432 double *LV=L.getArray();
00433 double *super_invvar=_super_invvar.getArray();
00434
00435 while((pline=fileList.getLine())!=NULL) {
00436 while((pFile=pline->getElement())!=NULL) {
00437 L.setAllValues(0.0);
00438 AUX.setAllValues(0.0);
00439 for(unsigned long i=0;i<_rang;i++){
00440 for(unsigned long j=0;j<=i;j++){
00441 for(unsigned long k=0;k<_supervsize;k++){
00442 mk=k/_vsize;
00443 LV[i*_rang+j]+=N_h[sent*_mixsize+mk]*super_invvar[k]*U[k*_rang+i]*U[k*_rang+j];
00444 }
00445 }
00446 }
00447 for(unsigned long i=0;i<_rang;i++)
00448 for(unsigned long j=i+1;j<_rang;j++)
00449 LV[i*_rang+j]=LV[j*_rang+i];
00450
00451 for(unsigned long i=0;i<_rang;i++)
00452 LV[i*_rang+i]+=1.0;
00453 L.invert(_l_h_inv[sent]);
00454 sent++;
00455 }
00456 }
00457 };
00458
00459
00460
00461
00462 #if defined(THREAD)
00463 struct Lthread_data{
00464 double *N_h;
00465 double *U;
00466 double *super_invvar;
00467 unsigned long sentBottom;
00468 unsigned long sentUp;
00469 unsigned long rang;
00470 unsigned long sv;
00471 unsigned long vsize;
00472 unsigned long mixsize;
00473 RefVector <DoubleSquareMatrix>* linv;
00474 };
00475
00476 void *Lthread(void *threadarg) {
00477 struct Lthread_data *my_data;
00478 my_data = (struct Lthread_data *) threadarg;
00479 double *U = my_data->U;
00480 unsigned long sentBottom = my_data->sentBottom;
00481 unsigned long sentUp = my_data->sentUp;
00482 double *N_h=my_data->N_h;
00483 double *super_invvar=my_data->super_invvar;
00484 unsigned long _rang=my_data->rang;
00485 unsigned long _supervsize=my_data->sv;
00486 unsigned long _vsize=my_data->vsize;
00487 unsigned long _mixsize=my_data->mixsize;
00488 for (unsigned long sent=sentBottom;sent <sentUp;sent++) {
00489 DoubleSquareMatrix L(_rang);
00490 L.setAllValues(0.0);
00491 double *LV=L.getArray();
00492 unsigned long mk;
00493 RealVector <double> AUX;
00494 AUX.setSize(_rang);
00495 AUX.setAllValues(0.0);
00496 for(unsigned long i=0;i<_rang;i++){
00497 for(unsigned long j=0;j<=i;j++){
00498 for(unsigned long k=0;k<_supervsize;k++){
00499 mk=k/_vsize;
00500 LV[i*_rang+j]+=N_h[sent*_mixsize+mk]*super_invvar[k]*U[k*_rang+i]*U[k*_rang+j];
00501 }
00502 }
00503 }
00504 for(unsigned long i=0;i<_rang;i++)
00505 for(unsigned long j=i+1;j<_rang;j++)
00506 LV[i*_rang+j]=LV[j*_rang+i];
00507
00508 for(unsigned long i=0;i<_rang;i++)
00509 LV[i*_rang+i]+=1.0;
00510 DoubleSquareMatrix &linv=(*(my_data->linv))[sent];
00511 L.invert(linv);
00512 }
00513 pthread_exit((void*) 0);
00514 }
00515
00516 void FactorAnalysisStat::estimateAndInverseLThreaded(unsigned long NUM_THREADS){
00517 if (verbose) cout << "(FactorAnalysisStat) Inverse L Matrix Threads ... "<<endl;
00518 if (NUM_THREADS==0) throw Exception("Num threads can be 0",__FILE__,__LINE__);
00519 double *N_h=_matN_h.getArray();
00520 double *U=_matU.getArray();
00521 double *super_invvar=_super_invvar.getArray();
00522
00523 int rc, status;
00524 if (NUM_THREADS > _nb_sent) NUM_THREADS=_nb_sent;
00525 struct Lthread_data thread_data_array[NUM_THREADS];
00526 pthread_t threads[NUM_THREADS];
00527 pthread_attr_t attr;
00528 pthread_attr_init(&attr);
00529 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00530 unsigned long offset=_nb_sent/NUM_THREADS;
00531 for(unsigned long t=0, sentBottom=0; t<NUM_THREADS; t++,sentBottom+=offset){
00532 thread_data_array[t].N_h=N_h;
00533 thread_data_array[t].U=U;
00534 thread_data_array[t].super_invvar=super_invvar;
00535 thread_data_array[t].sentBottom=sentBottom;
00536 unsigned long sentUp=sentBottom+offset;
00537 if (_nb_sent%NUM_THREADS!=0) sentUp++;
00538 thread_data_array[t].sentUp=sentUp;
00539 thread_data_array[t].rang=_rang;
00540 thread_data_array[t].sv=_supervsize;
00541 thread_data_array[t].vsize=_vsize;
00542 thread_data_array[t].mixsize=_mixsize;
00543 thread_data_array[t].linv=&(_l_h_inv);
00544
00545 if (verbose) cout<<"(FactorAnalysisStat) Creating thread n["<< t<< "] for sessions["<<sentBottom<<"-->"<<sentUp<<"]"<<endl;
00546 rc = pthread_create(&threads[t], &attr, Lthread, (void *)&thread_data_array[t]);
00547 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
00548 }
00549 pthread_attr_destroy(&attr);
00550 for(unsigned long t=0; t<NUM_THREADS; t++) {
00551 rc = pthread_join(threads[t], (void **)&status);
00552 if (rc) throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
00553 if (verbose) cout <<"(FactorAnalysisStat) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
00554 }
00555 if (verboseLevel > 1) cout << "(FactorAnalysisStat) Done " << endl;
00556 };
00557 #endif
00558
00559
00560 void FactorAnalysisStat::getYEstimate(){
00561 if (verbose) cout << "(FactorAnalysisStat) Compute Y Estimate "<<endl;
00562 _matY.setAllValues(0.0);
00563
00564 double *N=_matN.getArray();
00565 double *Y=_matY.getArray();
00566 double *S_X=_matS_X.getArray();
00567 double *D=_D.getArray();
00568 double *super_invvar=_super_invvar.getArray();
00569
00570 for(unsigned long loc=0;loc<_nb_speakers;loc++) {
00571 for(unsigned long i=0;i<_supervsize;i++){
00572 unsigned long mi=i/_vsize;
00573 Y[loc*_supervsize+i]= (_tau/(_tau+N[loc*_mixsize+mi]))*D[i]*super_invvar[i]*S_X[loc*_supervsize+i];
00574 }
00575 }
00576 };
00577
00578 void FactorAnalysisStat::getUEstimate(Config & config){
00579 #if defined(THREAD)
00580 if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0) getUEstimateThreaded(config.getParam("numThread").toLong());
00581 else getUEstimateUnThreaded();
00582 #else
00583 getUEstimateUnThreaded();
00584 #endif
00585 };
00586
00587 void FactorAnalysisStat::getUEstimateUnThreaded(){
00588 if (verbose) cout << "(FactorAnalysisStat) Compute U Estimate "<<endl;
00589 DoubleSquareMatrix L(_rang);
00590 DoubleSquareMatrix L_Inv(_rang);
00591 RealVector <double> R;
00592 R.setSize(_rang);
00593
00594 double *N_h=_matN_h.getArray();
00595 double *X=_matX.getArray();
00596 double *S_X_h=_matS_X_h.getArray();
00597 double *U=_matU.getArray();
00598 double *RV=R.getArray();
00599 double *LV=L.getArray();
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 _matU.setAllValues(0.0);
00622 for(unsigned long g=0;g<_mixsize;g++){
00623 L.setAllValues(0.0);
00624
00625 for(unsigned long j=0;j<_nb_sent;j++){
00626 double *l_h_inv=_l_h_inv[j].getArray();
00627 for(unsigned long k=0;k<_rang;k++)
00628 for(unsigned long l=0;l<_rang;l++)
00629 LV[k*_rang+l]+=(l_h_inv[k*_rang+l]+X[j*_rang+k]*X[j*_rang+l])*N_h[j*_mixsize+g];
00630 }
00631 L.invert(L_Inv);
00632 double *L_InvV=L_Inv.getArray();
00633
00634
00635 for (unsigned long i=0;i<_vsize;i++) {
00636 unsigned long lineNum=_vsize*g+i;
00637
00638 R.setAllValues(0.0);
00639 for(unsigned long j=0;j<_nb_sent;j++)
00640 for(unsigned long k=0;k<_rang;k++)
00641 RV[k]+=S_X_h[j*_supervsize+lineNum]*X[j*_rang+k];
00642
00643 for(unsigned long j=0;j<_rang;j++)
00644 for(unsigned long k=0;k<_rang;k++)
00645 U[lineNum*_rang+j]+=L_InvV[j*_rang+k]*RV[k];
00646 }
00647 }
00648 };
00649
00650
00651
00652
00653 #if defined(THREAD)
00654 struct Uthread_data{
00655 double *N_h;
00656 double *U;
00657 double *S_X_h;
00658 double *X;
00659 unsigned long rang;
00660 unsigned long sv;
00661 unsigned long vsize;
00662 unsigned long mixsize;
00663 unsigned long nbsent;
00664 unsigned long idxBottom;
00665 unsigned long idxUp;
00666 RefVector <DoubleSquareMatrix>* L;
00667 };
00668
00669 void *Uthread(void *threadarg) {
00670 struct Uthread_data *my_data;
00671 my_data = (struct Uthread_data *) threadarg;
00672
00673 double *U = my_data->U;
00674 double *N_h=my_data->N_h;
00675 double *S_X_h=my_data->S_X_h;
00676 double *X=my_data->X;
00677 unsigned long _rang=my_data->rang;
00678 unsigned long _supervsize=my_data->sv;
00679 unsigned long _nb_sent=my_data->nbsent;
00680 unsigned long _vsize=my_data->vsize;
00681 unsigned long _mixsize=my_data->mixsize;
00682 unsigned long idxBottom=my_data->idxBottom;
00683 unsigned long idxUp=my_data->idxUp;
00684 RefVector <DoubleSquareMatrix>& _l_h_inv=*(my_data->L);
00685
00686
00687 DoubleSquareMatrix L(_rang);
00688 DoubleSquareMatrix L_Inv(_rang);
00689 RealVector <double> R;
00690 R.setSize(_rang);
00691 double *RV=R.getArray();
00692 double *LV=L.getArray();
00693 for (unsigned long g=idxBottom;g<idxUp;g++) {
00694 L.setAllValues(0.0);
00695
00696 for(unsigned long j=0;j<_nb_sent;j++){
00697 double *l_h_inv=_l_h_inv[j].getArray();
00698 for(unsigned long k=0;k<_rang;k++)
00699 for(unsigned long l=0;l<_rang;l++)
00700 LV[k*_rang+l]+=(l_h_inv[k*_rang+l]+X[j*_rang+k]*X[j*_rang+l])*N_h[j*_mixsize+g];
00701 }
00702 L.invert(L_Inv);
00703 double *L_InvV=L_Inv.getArray();
00704
00705
00706 for (unsigned long i=0;i<_vsize;i++) {
00707 unsigned long lineNum=_vsize*g+i;
00708
00709 R.setAllValues(0.0);
00710 for(unsigned long j=0;j<_nb_sent;j++)
00711 for(unsigned long k=0;k<_rang;k++)
00712 RV[k]+=S_X_h[j*_supervsize+lineNum]*X[j*_rang+k];
00713
00714 for(unsigned long j=0;j<_rang;j++)
00715 for(unsigned long k=0;k<_rang;k++)
00716 U[lineNum*_rang+j]+=L_InvV[j*_rang+k]*RV[k];
00717 }
00718 }
00719
00720 pthread_exit((void*) 0);
00721 }
00722
00723
00724 void FactorAnalysisStat::getUEstimateThreaded(unsigned long NUM_THREADS){
00725 if (verbose) cout << "(FactorAnalysisStat) Compute U Estimate Threaded "<<endl;
00726 double *N_h=_matN_h.getArray();
00727 double *X=_matX.getArray();
00728 double *S_X_h=_matS_X_h.getArray();
00729 double *U=_matU.getArray();
00730 _matU.setAllValues(0.0);
00731 if (NUM_THREADS==0) throw Exception("Num threads can not be 0",__FILE__,__LINE__);
00732 int rc, status;
00733 if (NUM_THREADS > _mixsize) NUM_THREADS=_mixsize;
00734 struct Uthread_data thread_data_array[NUM_THREADS];
00735 unsigned long offset=_mixsize/NUM_THREADS;
00736 pthread_t threads[NUM_THREADS];
00737 pthread_attr_t attr;
00738 pthread_attr_init(&attr);
00739 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00740 for(unsigned long t=0, idxBottom=0; t<NUM_THREADS; t++,idxBottom+=offset){
00741 thread_data_array[t].N_h=N_h;
00742 thread_data_array[t].U=U;
00743 thread_data_array[t].S_X_h=S_X_h;
00744 thread_data_array[t].X=X;
00745 thread_data_array[t].rang=_rang;
00746 thread_data_array[t].sv=_supervsize;
00747 thread_data_array[t].vsize=_vsize;
00748 thread_data_array[t].mixsize=_mixsize;
00749 thread_data_array[t].nbsent=_nb_sent;
00750 thread_data_array[t].idxBottom=idxBottom;
00751 unsigned long idxUp=idxBottom+offset;
00752 if (_supervsize%NUM_THREADS!=0) idxUp++;
00753 thread_data_array[t].idxUp=idxUp;
00754 thread_data_array[t].L=&(_l_h_inv);
00755 if (verbose) cout<<"(FactorAnalysisStat) Creating thread n["<< t<< "] for U, Gaussian ["<<idxBottom<<"-->"<<idxUp<<"]"<<endl;
00756 rc = pthread_create(&threads[t], &attr, Uthread, (void *)&thread_data_array[t]);
00757 if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
00758 }
00759 pthread_attr_destroy(&attr);
00760 for(unsigned long t=0; t<NUM_THREADS; t++) {
00761 rc = pthread_join(threads[t], (void **)&status);
00762 if (rc) throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
00763 if (verboseLevel >1) cout <<"(FactorAnalysisStat)Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
00764 }
00765 if (verboseLevel >1) cout << "(FactorAnalysisStat) Done " << endl;
00766 };
00767 #endif
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00835 void FactorAnalysisStat::getFactorAnalysisModel(MixtureGD& FA,String& file) {
00836 if (verbose) cout << "(FactorAnalysisStat) Compute Variance adapted Speaker Model"<<endl;
00837 this->getTrueSpeakerModel(FA,file);
00838 unsigned long loc=_ndxTable.locNb(file);
00839
00841 RealVector <double> sigma_s;
00842 sigma_s.setSize(_supervsize);
00843 for (unsigned long i=0;i<_mixsize;i++)
00844 for (unsigned long j=0;j<_vsize;j++)
00845 sigma_s[i*_vsize+j]=FA.getDistrib(i).getCov(j)/(_tau+_matN(loc,i));
00846
00848 RealVector <double> sum,prod;
00849 sum.setSize(_supervsize);prod.setSize(_supervsize);
00850 for (unsigned long i=0;i<_mixsize;i++) {
00851 for (unsigned long j=0;j<_vsize;j++) {
00852 sum[i*_vsize+j]=sigma_s[i*_vsize+j]+FA.getDistrib(i).getCov(j);
00853
00854 }
00855 }
00856
00857 for (unsigned long i=0;i<_mixsize;i++)
00858 for (unsigned long j=0;j<_vsize;j++)
00859 FA.getDistrib(i).setCov(sum[i*_vsize+j],j);
00860 FA.computeAll();
00861 }
00862
00864 double FactorAnalysisStat::getLLK(SegCluster &selectedSegments,MixtureGD &model,FeatureServer&fs,Config & config){
00865 if (verbose) cout << "(FactorAnalysisStat) Compute Likelihood" << endl;
00866 double llk=0.0;
00867 MixtureGDStat &acc=_ss.createAndStoreMixtureStat(model);
00868 Seg *seg;
00869 selectedSegments.rewind();
00870 while((seg=selectedSegments.getSeg())!=NULL){
00871 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());
00872 fs.seekFeature(begin);
00873 Feature f;
00874 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
00875 fs.readFeature(f);
00876 acc.computeAndAccumulateLLK(f,1.0,TOP_DISTRIBS_NO_ACTION);
00877 }
00878 }
00879 llk= acc.getMeanLLK();
00880 _ss.deleteMixtureStat(acc);
00881 return llk;
00882 };
00883
00884
00885 void FactorAnalysisStat::setYFromModel(MixtureGD& M,String & file){
00886 if (verbose) cout << "(FactorAnalysisStat) Set Y from Model" << endl;
00887 unsigned long loc=_ndxTable.locNb(file);
00888 RealVector<double> v(_supervsize,_supervsize);
00889 modelToSv(M,v);
00890 RealVector<double> w(_supervsize,_supervsize);
00891 modelToSv(_ms.getMixtureGD(0),w);
00892 for (unsigned long i=0;i<v.size();i++)
00893 _matY(loc,i)=(v[i]-w[i])/_D[i];
00894 };
00895
00896 void FactorAnalysisStat::estimateXForKnownSpeaker(MixtureGD & M,String & file,Config &config) {
00897 RealVector <double> v(_supervsize,_supervsize);
00898 modelToSv(M,v);
00899 this->resetXY();
00900 this->setYFromModel(M,file);
00901 for(int i=0;i<config.getParam("nbTrainIt").toLong();i++){
00902 if (verbose) cout << "(FactorAnalysisStat) ------ Iteration ["<<i<<"] ------"<<endl;
00903 this->substractSpeakerStats();
00904 this->getXEstimate();
00905 }
00906 double * X=_matX.getArray();
00907 for (unsigned long i=0;i<_supervsize;i++) {
00908 double ux=0.0;
00909 for (unsigned long j=0;j<_rang;j++) {
00910 ux+=_matU(i,j)*X[j];
00911 }
00912 v[i]+=ux;
00913 }
00914 svToModel(v,M);
00915 };
00916
00917 void FactorAnalysisStat::getUX(RealVector <double> &ux,String& file) {
00918 ux.setAllValues(0.0);
00919 unsigned long idx=_ndxTable.sessionNb(file);
00920 for (unsigned long i=0;i<_supervsize;i++)
00921 for (unsigned long j=0;j<_rang;j++)
00922 ux[i]+=_matU(i,j)*_matX(idx,j);
00923 };
00924
00925
00926 void FactorAnalysisStat::getTrueSpeakerModel(MixtureGD & M,String &file) {
00927 if (verbose) cout << "(FactorAnalysisStat) Compute True Speaker Model"<<endl;
00928 RealVector <double> Sp(_supervsize,_supervsize);
00929 getMplusDY(Sp,file);
00930 svToModel(Sp,M);
00931 };
00932
00933
00934 void FactorAnalysisStat::getSessionModel(MixtureGD & M,String &file) {
00935 if (verbose) cout << "(FactorAnalysisStat) Compute Channel Model"<<endl;
00936 RealVector <double> Sp(_supervsize,_supervsize);
00937 getUX(Sp,file);
00938 for (unsigned long i=0;i<_supervsize;i++)
00939 Sp[i]+=_super_mean[i];
00940 svToModel(Sp,M);
00941 };
00942
00943
00944 void FactorAnalysisStat::getMplusDY(RealVector <double> &Sp, String& file) {
00945 Sp.setAllValues(0.0);
00946 unsigned long loc=_ndxTable.locNb(file);
00947 for (unsigned long i=0;i<_supervsize;i++)
00948 Sp[i]=_super_mean[i]+_D[i]*_matY(loc,i);
00949 };
00950
00951
00952 void FactorAnalysisStat::getSpeakerModel(MixtureGD & M,String& file) {
00953 RealVector <double> Sp;Sp.setSize(_supervsize);
00954 RealVector <double> ux;ux.setSize(_supervsize);
00955 this->getUX(ux,file);
00956 this->getMplusDY(Sp,file);
00957 for (unsigned long i=0;i<_supervsize;i++)
00958 Sp[i]+=ux[i];
00959 svToModel(Sp,M);
00960 };
00961
00963 void FactorAnalysisStat::normalizeFeatures(SegCluster &selectedSegments,FeatureServer &fs,Config & config){
00964 if (verbose) cout << "(FactorAnalysisStat) Normalize Features" << endl;
00965 MixtureGD & clientMixture=_ms.getMixtureGD(1);
00966 unsigned long nt=0;
00967 RealVector <double> m_xh_1; m_xh_1.setSize(_supervsize);
00968 double *_m_xh_1=m_xh_1.getArray();
00969 Seg *seg;
00970 selectedSegments.rewind();
00971 String currentSource="";
00972 while((seg=selectedSegments.getSeg())!=NULL){
00973 unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());
00974 if (currentSource!=seg->sourceName()) {
00975 currentSource=seg->sourceName();
00976 this->getUX(m_xh_1,currentSource);
00977 this->getSpeakerModel(clientMixture,currentSource);
00978 if (verbose)cout << "Processing speaker["<<currentSource<<"]"<< endl;
00979 }
00980 fs.seekFeature(begin);
00981 Feature f;
00982 if (!_topGauss) {
00983 for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
00984 fs.readFeature(f,0);
00985 double *ff=f.getDataVector();
00986 double sum=0.0;
00987 RealVector <double> P;
00988 P.setSize(_mixsize);
00989 double *Prob=P.getArray();
00990 for(unsigned long k=0;k<_mixsize;k++) {
00991 Prob[k]=clientMixture.weight(k)*clientMixture.getDistrib(k).computeLK(f);
00992 sum+=Prob[k];
00993 }
00994 for(unsigned long k=0;k<_mixsize;k++)
00995 Prob[k]/=sum;
00996 for(unsigned long k=0;k<_mixsize;k++) {
00997 for (unsigned long i=0;i<_vsize;i++)
00998 ff[i]-= Prob[k]*_m_xh_1[k*_vsize+i];
00999 }
01000 fs.writeFeature(f);
01001 nt++;
01002 }
01003 }
01004 else {
01005 throw Exception("no topgauss yet",__FILE__,__LINE__);
01006 }
01007 }
01008 };
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053 void FactorAnalysisStat::normalizeFeatures(FeatureServer &fs,Config & config){
01054 SegServer segmentsServer;
01055 LabelServer labelServer;
01056 initializeClusters(fileList,segmentsServer,labelServer,config);
01057 verifyClusterFile(segmentsServer,fs,config);
01058 unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
01059 SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);
01060 normalizeFeatures(selectedSegments,fs,config);
01061 };
01062
01063 void FactorAnalysisStat::estimateXYAndNorm(FeatureServer &fs,Config &config) {
01064 this->resetXY();
01065
01066 for(int i=0;i<config.getParam("nbTrainIt").toLong();i++){
01067 if (verbose) cout << "------ Iteration ["<<i<<"] ------"<<endl;
01068 this->computeAndAccumulateGeneralFAStats(fs,config);
01069 this->substractSpeakerStats();
01070 this->substractChannelStats();
01071 this->estimateAndInverseL(config);
01072 this->getXEstimate();
01073 this->getYEstimate();
01074 }
01075 this->normalizeFeatures(fs,config);
01076 };
01077
01078 void FactorAnalysisStat::estimateXYAndNorm(SegCluster &selectedSegments,FeatureServer &fs,Config &config) {
01079 this->resetXY();
01080 for(int i=0;i<config.getParam("nbTrainIt").toLong();i++){
01081 if (verbose) cout << "------ Iteration ["<<i<<"] ------"<<endl;
01082 this->computeAndAccumulateGeneralFAStats(selectedSegments,fs,config);
01083 this->substractSpeakerStats();
01084 this->substractChannelStats();
01085 this->estimateAndInverseL(config);
01086 this->getXEstimate();
01087 this->getYEstimate();
01088 }
01089 this->normalizeFeatures(selectedSegments,fs,config);
01090 };
01091 #endif