EstimateDMatrix.cpp

Go to the documentation of this file.
00001 // EstimateDMatrix.cpp
00002 // 
00003 // This file is a part of Mistral Package and LIA Software 
00004 // LIA_SpkDet, based on Mistral_Ral toolkit 
00005 // LIA_SpkDet is a free, open tool for speaker recognition
00006 // LIA_SpkDet is a development project initiated and funded by the LIA lab.
00007 //
00008 // See mistral.univ-avignon.fr 
00009 // 
00010 // ALIZE is needed for LIA_SpkDet
00011 // for more information about ALIZE, see http://alize.univ-avignon.fr
00012 //
00013 // Copyright (C) 2004 - 2005 - 2006 - 2007 -2008
00014 //  Laboratoire d'informatique d'Avignon [www.lia.univ-avignon.fr]
00015 //  Jean-Francois Bonastre [jean-francois.bonastre@univ-avignon.fr]
00016 //      
00017 // Mistral is free software; you can redistribute it and/or
00018 // modify it under the terms of the GNU General Public
00019 // License as published by the Free Software Foundation; either
00020 // version 2.1 of the License, or (at your option) any later version.
00021 // This software is distributed in the hope that it will be useful,
00022 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024 // General Public License for more details.
00025 // You should have received a copy of the GNU General Public
00026 // License along with this library; if not, write to the Free Software
00027 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //
00029 // The LIA team as well as the ALIZE project want to highlight the limits of voice authentication
00030 // in a forensic context. 
00031 // The following paper proposes a good overview of this point:
00032 // [Bonastre J.F., Bimbot F., Boe L.J., Campbell J.P., Douglas D.A., Magrin-chagnolleau I.,
00033 //  Person  Authentification by Voice: A Need of Caution,
00034 //  Eurospeech 2003, Genova]
00035 // The conclusion of the paper of the paper is proposed bellow:
00036 // [Currently, it is not possible to completely determine whether the
00037 //  similarity between two recordings is due to the speaker or to other
00038 //  factors, especially when: (a) the speaker does not cooperate, (b) there
00039 //  is no control over recording equipment, (c) recording conditions are not 
00040 //  known, (d) one does not know whether the voice was disguised and, to a
00041 //  lesser extent, (e) the linguistic content of the message is not
00042 //  controlled. Caution and judgment must be exercised when applying speaker
00043 //  recognition techniques, whether human or automatic, to account for these
00044 //  uncontrolled factors. Under more constrained or calibrated situations,
00045 //  or as an aid for investigative purposes, judicious application of these
00046 //  techniques may be suitable, provided they are not considered as infallible.
00047 //  At the present time, there is no scientific process that enables one to
00048 //  uniquely characterize a person=92s voice or to identify with absolute
00049 //  certainty an individual from his or her voice.]
00050 //
00051 // Contact Jean-Francois Bonastre (jean-francois.bonastre@lia.univ-avignon.fr) for
00052 // more information about the licence or the use of LIA_SpkDet
00053 // First version 15/07/2004
00054 // New version 23/02/2005
00055 // 
00056 // Last review 4 nov 2008
00057 //
00058 
00059 #if !defined(ALIZE_EstimateDMatrix_cpp)
00060 #define ALIZE_EstimateDMatrix_cpp
00061 
00062 #include <fstream>
00063 #include <cstdio>               
00064 #include <cassert>
00065 #include <cmath>
00066 #include "liatools.h"
00067 #include <EstimateDMatrix.h>
00068 #include <AccumulateJFAStat.h>
00069 
00070 using namespace alize;
00071 using namespace std;
00072 
00073 
00074 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00075 /*void verifyEMLK(JFAAcc & JFA,XList &ndx,Config &config) {
00076 
00077         XLine *pline; String *pFile; ndx.rewind();      
00078         double total=0.0;
00079         unsigned long maxLLKcomputed=1;
00080         maxLLKcomputed=config.getParam("computeLLK").toLong();  
00081         bool JFALLK=false;
00082         if (config.existsParam("JFALLK")) {JFALLK=true;if(verbose) cout<<"(EigenVoice) Computing Joint Factor Analysis Likelihoods"<<endl;}
00083         unsigned long cnt=0;
00084         while((pline=ndx.getLine())!=NULL && cnt < maxLLKcomputed) { 
00085                 while((pFile=pline->getElement())!=NULL && cnt < maxLLKcomputed) {
00087                         MixtureServer ms(config);
00088                         MixtureGD &model=ms.loadMixtureGD(config.getParam("inputWorldFilename"));
00089                         if (JFALLK) JFA.getJFAModel(model,*pFile);
00090                         else JFA.getSpeakerModel(model,*pFile);
00091                         
00093                         FeatureServer fs(config,*pFile);
00094                         SegServer segmentsServer;
00095                         LabelServer labelServer;
00096                         initializeClusters(*pFile,segmentsServer,labelServer,config);
00097                         verifyClusterFile(segmentsServer,fs,config);
00098                         unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(config.getParam("labelSelectedFrames"));
00099                         SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);  
00100                         double llk=FA.getLLK(selectedSegments,model,fs,config); 
00101                         if (verbose) cout << "(EigenVoice) LLK["<<*pFile<<"]="<<llk<<endl;
00102                         cnt++;
00103                         total+=llk;
00104                 }
00105         }
00106         if (verbose) cout << "(EigenVoice) Total LLK="<<total<<endl;
00107 }*/
00108 
00109 //-----------------------------------------------------------------------------------------------------------------------------------------------------------
00110 int EstimateDMatrix(Config & config){
00111         
00112         //Read the NDX file
00113         String ndxFilename = config.getParam("ndxFilename");
00114         
00115         //Create and initialise the accumulator
00116         JFAAcc jfaAcc(ndxFilename, config);
00117 
00118         //Statistics
00119         if((config.existsParam("loadAccs")) && config.getParam("loadAccs").toBool()){   //load pre-computed statistics
00120                 jfaAcc.loadN(config);
00121                 jfaAcc.loadN_h(config);
00122                 jfaAcc.loadF_X(config);
00123                 jfaAcc.loadF_X_h(config);
00124         }
00125         else{                                                                                                                   //Compute statistics if they don't exists
00126                 jfaAcc.computeAndAccumulateJFAStat(config);
00127                 jfaAcc.saveAccs(config);
00128         }
00129 
00130         //Initialise the D Matrix
00131         if(config.existsParam("initDMatrix")){  //Load the D matrix when existing
00132                 jfaAcc.loadD(config.getParam("initDMatrix"), config);
00133         }
00134         else{   //Initialise the D matrix randomly if does not exists
00135                 jfaAcc.initD(config);
00136         }
00137 
00138         //Save the initial D matrix to be able restart the process with the same initialisation
00139         if(config.existsParam("saveInitD") && config.getParam("saveInitD").toBool()){
00140                 String saveFilename = config.getParam("DMatrix") + "_init";
00141                 jfaAcc.saveD(saveFilename, config);
00142                 cout<<" (EstimateDMatrix) Save the initial D Matrix in "<<saveFilename<<endl;
00143         }
00144         
00145         //Initialise the EV Matrix
00146         //if(config.existsParam("eigenVoiceMatrix")){   //Load the EV matrix when existing
00147         //      jfaAcc.loadEV(config.getParam("eigenVoiceMatrix"), config);
00148         //}
00149         //else{ //Initialise the EV matrix to zero if does not exist
00150         //      jfaAcc.getV().setAllValues(0.0);
00151         //      cout<<"(EstimateDMatrix) Initialise NULL EigenVoice Matrix"<<endl;
00152         //}
00153         //
00155         //jfaAcc.storeAccs();
00156         //jfaAcc.estimateVEVT(config);
00157         //jfaAcc.estimateAndInverseL_EV(config);
00158         //jfaAcc.substractMplusDZ(config);
00159         //jfaAcc.substractUX(config);
00160         //jfaAcc.estimateY(config);
00162         //jfaAcc.restoreAccs();
00163 
00165         //if(config.existsParam("eigenChannelMatrix")){ //Load the EC matrix when existing
00166         //      jfaAcc.loadEC(config.getParam("eigenChannelMatrix"), config);
00167         //}
00168         //else{ //Initialise the EC matrix to zero if does not exist
00169         //      jfaAcc.getU().setAllValues(0.0);
00170         //      cout<<" (EstimateDMatrix) Initialise NULL EigenChannel Matrix"<<endl;
00171         //}
00172 
00174         //jfaAcc.storeAccs();
00175         //jfaAcc.estimateUEUT(config);
00176         //jfaAcc.estimateAndInverseL_EC(config);
00177         //jfaAcc.substractMplusVYplusDZ(config);
00178         //jfaAcc.estimateX(config);
00180         //jfaAcc.restoreAccs(); 
00181 
00183         //unsigned long nbIt = config.getParam("nbIt").toULong();
00184 
00185         //jfaAcc.storeAccs();
00186         //for(unsigned long it=0; it<nbIt; it++){
00187 
00188         //      cout<<" (EstimateDMatrix) --------- start iteration "<<it<<" --------"<<endl;
00189 
00190         //      //Substract speaker statistics M + VY
00191         //      jfaAcc.substractMplusVY(config);
00192         //      
00193         //      //Substract channel statistics UX
00194         //      jfaAcc.substractUX(config);
00195         //
00196         //      //Estimate Z for each speaker
00197         //      jfaAcc.estimateZandD();
00198 
00199         //      //Reinitialise the accumulators
00200         //      jfaAcc.resetTmpAcc();
00201         //      jfaAcc.restoreAccs();
00202         //      
00203         //      //Save the D matrix at the end of the iteration
00204         //      if(config.getParam("saveAllDMatrices").toBool()){
00205         //              String s;
00206         //              String output = config.getParam("DMatrix") + s.valueOf(it);
00207         //              jfaAcc.saveD(output, config);
00208         //      }
00209         //}
00210 
00211         cout<<" (EstimateDMatrix) --------- save D Matrix --------"<<endl;
00212         jfaAcc.saveD(config.getParam("DMatrix"), config);
00213         cout<<" (EstimateDMatrix) --------- end of process --------"<<endl;
00214         
00215 return 0;
00216 }
00217 #endif