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
1.7.2