78#ifdef MethodMLP_UseMinuit__ 
   97     fUseRegulator(false), fCalculateErrors(false),
 
   98     fPrior(0.0), fPriorDev(0), fUpdateLimit(0),
 
   99     fTrainingMethod(kBFGS), fTrainMethodS(
"BFGS"),
 
  100     fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
 
  101     fSamplingTraining(false), fSamplingTesting(false),
 
  102     fLastAlpha(0.0), fTau(0.),
 
  103     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
 
  104     fBPMode(kSequential), fBpModeS(
"None"),
 
  105     fBatchSize(0), fTestRate(0), fEpochMon(false),
 
  106     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
 
  107     fGA_SC_rate(0), fGA_SC_factor(0.0),
 
  108     fDeviationsFromTargets(0),
 
  120     fUseRegulator(false), fCalculateErrors(false),
 
  121     fPrior(0.0), fPriorDev(0), fUpdateLimit(0),
 
  122     fTrainingMethod(kBFGS), fTrainMethodS(
"BFGS"),
 
  123     fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
 
  124     fSamplingTraining(false), fSamplingTesting(false),
 
  125     fLastAlpha(0.0), fTau(0.),
 
  126     fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
 
  127     fBPMode(kSequential), fBpModeS(
"None"),
 
  128     fBatchSize(0), fTestRate(0), fEpochMon(false),
 
  129     fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
 
  130     fGA_SC_rate(0), fGA_SC_factor(0.0),
 
  131     fDeviationsFromTargets(0),
 
  169   SetSignalReferenceCut( 0.5 );
 
  170#ifdef MethodMLP_UseMinuit__ 
  199   DeclareOptionRef(fTrainMethodS=
"BP", 
"TrainingMethod",
 
  200                    "Train with Back-Propagation (BP), BFGS Algorithm (BFGS), or Genetic Algorithm (GA - slower and worse)");
 
  205   DeclareOptionRef(fLearnRate=0.02,    
"LearningRate",    
"ANN learning rate parameter");
 
  206   DeclareOptionRef(fDecayRate=0.01,    
"DecayRate",       
"Decay rate for learning parameter");
 
  207   DeclareOptionRef(fTestRate =10,      
"TestRate",        
"Test for overtraining performed at each #th epochs");
 
  208   DeclareOptionRef(fEpochMon = 
kFALSE, 
"EpochMonitoring", 
"Provide epoch-wise monitoring plots according to TestRate (caution: causes big ROOT output file!)" );
 
  210   DeclareOptionRef(fSamplingFraction=1.0, 
"Sampling",
"Only 'Sampling' (randomly selected) events are trained each epoch");
 
  211   DeclareOptionRef(fSamplingEpoch=1.0,    
"SamplingEpoch",
"Sampling is used for the first 'SamplingEpoch' epochs, afterwards, all events are taken for training");
 
  212   DeclareOptionRef(fSamplingWeight=1.0,    
"SamplingImportance",
" The sampling weights of events in epochs which successful (worse estimator than before) are multiplied with SamplingImportance, else they are divided.");
 
  214   DeclareOptionRef(fSamplingTraining=
kTRUE,    
"SamplingTraining",
"The training sample is sampled");
 
  215   DeclareOptionRef(fSamplingTesting= 
kFALSE,    
"SamplingTesting" ,
"The testing sample is sampled");
 
  217   DeclareOptionRef(fResetStep=50,   
"ResetStep",    
"How often BFGS should reset history");
 
  218   DeclareOptionRef(fTau      =3.0,  
"Tau",          
"LineSearch \"size step\"");
 
  220   DeclareOptionRef(fBpModeS=
"sequential", 
"BPMode",
 
  221                    "Back-propagation learning mode: sequential or batch");
 
  222   AddPreDefVal(
TString(
"sequential"));
 
  223   AddPreDefVal(
TString(
"batch"));
 
  225   DeclareOptionRef(fBatchSize=-1, 
"BatchSize",
 
  226                    "Batch size: number of events/batch, only set if in Batch Mode, -1 for BatchSize=number_of_events");
 
  228   DeclareOptionRef(fImprovement=1
e-30, 
"ConvergenceImprove",
 
  229                    "Minimum improvement which counts as improvement (<0 means automatic convergence check is turned off)");
 
  231   DeclareOptionRef(fSteps=-1, 
"ConvergenceTests",
 
  232                    "Number of steps (without improvement) required for convergence (<0 means automatic convergence check is turned off)");
 
  234   DeclareOptionRef(fUseRegulator=
kFALSE, 
"UseRegulator",
 
  235                    "Use regulator to avoid over-training");   
 
  236   DeclareOptionRef(fUpdateLimit=10000, 
"UpdateLimit",
 
  237                    "Maximum times of regulator update");   
 
  238   DeclareOptionRef(fCalculateErrors=
kFALSE, 
"CalculateErrors",
 
  239                    "Calculates inverse Hessian matrix at the end of the training to be able to calculate the uncertainties of an MVA value");   
 
  241   DeclareOptionRef(fWeightRange=1.0, 
"WeightRange",
 
  242                    "Take the events for the estimator calculations from small deviations from the desired value to large deviations only over the weight range");
 
  254   if (IgnoreEventsWithNegWeightsInTraining()) {
 
  256            << 
"Will ignore negative events in training!" 
  261   if      (fTrainMethodS == 
"BP"  ) fTrainingMethod = kBP;
 
  262   else if (fTrainMethodS == 
"BFGS") fTrainingMethod = kBFGS;
 
  263   else if (fTrainMethodS == 
"GA"  ) fTrainingMethod = kGA;
 
  265   if      (fBpModeS == 
"sequential") fBPMode = kSequential;
 
  266   else if (fBpModeS == 
"batch")      fBPMode = kBatch;
 
  270   if (fBPMode == kBatch) {
 
  272      Int_t numEvents = Data()->GetNEvents();
 
  273      if (fBatchSize < 1 || fBatchSize > numEvents) fBatchSize = numEvents;
 
  282   Log() << kDEBUG << 
"Initialize learning rates" << 
Endl;
 
  284   Int_t numSynapses = fSynapses->GetEntriesFast();
 
  285   for (
Int_t i = 0; i < numSynapses; i++) {
 
  286      synapse = (
TSynapse*)fSynapses->At(i);
 
  298      Log() << kFATAL << 
"<CalculateEstimator> fatal error: wrong tree type: " << treeType << 
Endl;
 
  302   Data()->SetCurrentType(treeType);
 
  313   if (fEpochMon && iEpoch >= 0 && !DoRegression()) {
 
  314      histS = 
new TH1F( nameS, nameS, nbin, -limit, limit );
 
  315      histB = 
new TH1F( nameB, nameB, nbin, -limit, limit );
 
  321   Int_t  nEvents  = GetNEvents();
 
  322   UInt_t nClasses = DataInfo().GetNClasses();
 
  323   UInt_t nTgts = DataInfo().GetNTargets();
 
  327   if( fWeightRange < 1.f ){
 
  328      fDeviationsFromTargets = 
new std::vector<std::pair<Float_t,Float_t> >(nEvents);
 
  331   for (
Int_t i = 0; i < nEvents; i++) {
 
  333      const Event* ev = GetEvent(i);
 
  335      if ((ev->
GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
 
  342      ForceNetworkInputs( ev );
 
  343      ForceNetworkCalculations();
 
  346      if (DoRegression()) {
 
  347         for (
UInt_t itgt = 0; itgt < nTgts; itgt++) {
 
  348            v = GetOutputNeuron( itgt )->GetActivationValue();
 
  354      } 
else if (DoMulticlass() ) {
 
  356         if (fEstimator==kCE){
 
  358            for (
UInt_t icls = 0; icls < nClasses; icls++) {
 
  359               Float_t activationValue = GetOutputNeuron( icls )->GetActivationValue();
 
  360               norm += 
exp( activationValue );
 
  362                  d = 
exp( activationValue );
 
  367            for (
UInt_t icls = 0; icls < nClasses; icls++) {
 
  368               Double_t desired = (icls==cls) ? 1.0 : 0.0;
 
  369               v = GetOutputNeuron( icls )->GetActivationValue();
 
  370               d = (desired-
v)*(desired-
v);
 
  375         Double_t desired =  DataInfo().IsSignal(ev)?1.:0.;
 
  376         v = GetOutputNeuron()->GetActivationValue();
 
  377         if (fEstimator==kMSE) 
d = (desired-
v)*(desired-
v);                         
 
  382      if( fDeviationsFromTargets )
 
  383         fDeviationsFromTargets->push_back(std::pair<Float_t,Float_t>(
d,w));
 
  389      if (DataInfo().IsSignal(ev) && histS != 0) histS->
Fill( 
float(
v), float(w) );
 
  390      else if              (histB != 0) histB->
Fill( 
float(
v), float(w) );
 
  394   if( fDeviationsFromTargets ) {
 
  395      std::sort(fDeviationsFromTargets->begin(),fDeviationsFromTargets->end());
 
  397      Float_t sumOfWeightsInRange = fWeightRange*sumOfWeights;
 
  400      Float_t weightRangeCut = fWeightRange*sumOfWeights;
 
  402      for(std::vector<std::pair<Float_t,Float_t> >::iterator itDev = fDeviationsFromTargets->begin(), itDevEnd = fDeviationsFromTargets->end(); itDev != itDevEnd; ++itDev ){
 
  403         float deviation = (*itDev).first;
 
  404         float devWeight = (*itDev).second;
 
  405         weightSum += devWeight; 
 
  406         if( weightSum <= weightRangeCut ) { 
 
  407            estimator += devWeight*deviation;
 
  411      sumOfWeights = sumOfWeightsInRange;
 
  412      delete fDeviationsFromTargets;
 
  415   if (histS != 0) fEpochMonHistS.push_back( histS );
 
  416   if (histB != 0) fEpochMonHistB.push_back( histB );
 
  421   estimator = estimator/
Float_t(sumOfWeights);
 
  426   Data()->SetCurrentType( saveType );
 
  429   if (fEpochMon && iEpoch >= 0 && !DoRegression() && treeType == 
Types::kTraining) {
 
  430      CreateWeightMonitoringHists( 
Form(
"epochmonitoring___epoch_%04i_weights_hist", iEpoch), &fEpochMonHistW );
 
  442      Log() << kFATAL <<
"ANN Network is not initialized, doing it now!"<< 
Endl;
 
  443      SetAnalysisType(GetAnalysisType());
 
  445   Log() << kDEBUG << 
"reinitialize learning rates" << 
Endl;
 
  446   InitializeLearningRates();
 
  448   PrintMessage(
"Training Network");
 
  450   Int_t nEvents=GetNEvents();
 
  451   Int_t nSynapses=fSynapses->GetEntriesFast();
 
  452   if (nSynapses>nEvents)
 
  453      Log()<<kWARNING<<
"ANN too complicated: #events="<<nEvents<<
"\t#synapses="<<nSynapses<<
Endl;
 
  455   fIPyMaxIter = nEpochs;
 
  456   if (fInteractive && fInteractive->NotInitialized()){
 
  457     std::vector<TString> titles = {
"Error on training set", 
"Error on test set"};
 
  458     fInteractive->Init(titles);
 
  461#ifdef MethodMLP_UseMinuit__ 
  462   if (useMinuit) MinuitMinimize();
 
  464   if (fTrainingMethod == kGA)        GeneticMinimize();
 
  465   else if (fTrainingMethod == kBFGS) BFGSMinimize(nEpochs);
 
  466   else                               BackPropagationMinimize(nEpochs);
 
  472      Log()<<kINFO<<
"Finalizing handling of Regulator terms, trainE="<<trainE<<
" testE="<<testE<<
Endl;
 
  474      Log()<<kINFO<<
"Done with handling of Regulator terms"<<
Endl;
 
  477   if( fCalculateErrors || fUseRegulator )
 
  479         Int_t numSynapses=fSynapses->GetEntriesFast();
 
  480         fInvHessian.ResizeTo(numSynapses,numSynapses);
 
  481         GetApproxInvHessian( fInvHessian ,
false);
 
  497       fEstimatorHistTrain = 
new TH1F( 
"estimatorHistTrain", 
"training estimator",
 
  498                                   nbinTest, 
Int_t(fTestRate/2), nbinTest*fTestRate+
Int_t(fTestRate/2) );
 
  499       fEstimatorHistTest  = 
new TH1F( 
"estimatorHistTest", 
"test estimator",
 
  500                                   nbinTest, 
Int_t(fTestRate/2), nbinTest*fTestRate+
Int_t(fTestRate/2) );
 
  503   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  504   Int_t nWeights  = nSynapses;
 
  506   for (
Int_t i=0;i<nSynapses;i++) {
 
  511   std::vector<Double_t> buffer( nWeights );
 
  512   for (
Int_t i=0;i<nWeights;i++) buffer[i] = 0.;
 
  515   TMatrixD Hessian ( nWeights, nWeights );
 
  519   Int_t        RegUpdateTimes=0;               
 
  527   if(fSamplingTraining || fSamplingTesting)
 
  528      Data()->InitSampling(1.0,1.0,fRandomSeed); 
 
  530   if (fSteps > 0) 
Log() << kINFO << 
"Inaccurate progress timing for MLP... " << 
Endl;
 
  534   for (
Int_t i = 0; i < nEpochs; i++) {
 
  536     if (fExitFromTraining) 
break;
 
  538      if (
Float_t(i)/nEpochs < fSamplingEpoch) {
 
  539         if ((i+1)%fTestRate == 0 || (i == 0)) {
 
  540            if (fSamplingTraining) {
 
  542               Data()->InitSampling(fSamplingFraction,fSamplingWeight);
 
  543               Data()->CreateSampling();
 
  545            if (fSamplingTesting) {
 
  547               Data()->InitSampling(fSamplingFraction,fSamplingWeight);
 
  548               Data()->CreateSampling();
 
  554         Data()->InitSampling(1.0,1.0);
 
  556         Data()->InitSampling(1.0,1.0);
 
  567      SetGammaDelta( 
Gamma, Delta, buffer );
 
  569      if (i % fResetStep == 0 && i<0.5*nEpochs) { 
 
  575         if (GetHessian( Hessian, 
Gamma, Delta )) {
 
  580         else SetDir( Hessian, Dir );
 
  584      if (DerivDir( Dir ) > 0) {
 
  589      if (LineSearch( Dir, buffer, &dError )) { 
 
  593         if (LineSearch(Dir, buffer, &dError)) {  
 
  595            Log() << kFATAL << 
"Line search failed! Huge troubles somewhere..." << 
Endl;
 
  600      if (dError<0) 
Log()<<kWARNING<<
"\nnegative dError=" <<dError<<
Endl;
 
  603      if ( fUseRegulator && RegUpdateTimes<fUpdateLimit && RegUpdateCD>=5 && 
fabs(dError)<0.1*AccuError) {
 
  604         Log()<<kDEBUG<<
"\n\nUpdate regulators "<<RegUpdateTimes<<
" on epoch "<<i<<
"\tdError="<<dError<<
Endl;
 
  614      if ((i+1)%fTestRate == 0) {
 
  619         if (fInteractive) fInteractive->AddPoint(i+1, trainE, testE);
 
  622            fEstimatorHistTrain->Fill( i+1, trainE );
 
  623            fEstimatorHistTest ->Fill( i+1, testE );
 
  626         if ((testE < GetCurrentValue()) || (GetCurrentValue()<1
e-100)) {
 
  629         Data()->EventResult( success );
 
  631         SetCurrentValue( testE );
 
  632         if (HasConverged()) {
 
  633            if (
Float_t(i)/nEpochs < fSamplingEpoch) {
 
  634               Int_t newEpoch = 
Int_t(fSamplingEpoch*nEpochs);
 
  636               ResetConvergenceCounter();
 
  643      TString convText = 
Form( 
"<D^2> (train/test/epoch): %.4g/%.4g/%d", trainE, testE,i  ); 
 
  646         if (
Float_t(i)/nEpochs < fSamplingEpoch)
 
  648            progress = Progress()*fSamplingFraction*100*fSamplingEpoch;
 
  652               progress = 100.0*(fSamplingFraction*fSamplingEpoch+(1.0-fSamplingEpoch)*Progress());
 
  654         Float_t progress2= 100.0*RegUpdateTimes/fUpdateLimit; 
 
  655         if (progress2>progress) progress=progress2; 
 
  660         if (progress<i) progress=i; 
 
  676   Int_t nWeights = fSynapses->GetEntriesFast();
 
  679   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  680   for (
Int_t i=0;i<nSynapses;i++) {
 
  685   for (
Int_t i=0;i<nWeights;i++) Delta[i][0] = buffer[i];
 
  690   for (
Int_t i=0;i<nSynapses;i++)
 
  701   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  702   for (
Int_t i=0;i<nSynapses;i++) {
 
  707   Int_t nEvents = GetNEvents();
 
  708   Int_t nPosEvents = nEvents;
 
  709   for (
Int_t i=0;i<nEvents;i++) {
 
  711      const Event* ev = GetEvent(i);
 
  712      if ((ev->
GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
 
  720      for (
Int_t j=0;j<nSynapses;j++) {
 
  726   for (
Int_t i=0;i<nSynapses;i++) {
 
  729      if (fUseRegulator) DEDw+=fPriorDev[i]; 
 
  730      synapse->
SetDEDw( DEDw / nPosEvents );   
 
  740   ForceNetworkInputs( ev );
 
  741   ForceNetworkCalculations();
 
  743   if (DoRegression()) {
 
  744      UInt_t ntgt = DataInfo().GetNTargets();
 
  745      for (
UInt_t itgt = 0; itgt < ntgt; itgt++) {
 
  747         Double_t error = ( GetOutputNeuron( itgt )->GetActivationValue() - desired )*eventWeight;
 
  748         GetOutputNeuron( itgt )->SetError(error);
 
  750   } 
else if (DoMulticlass()) {
 
  751      UInt_t nClasses = DataInfo().GetNClasses();
 
  753      for (
UInt_t icls = 0; icls < nClasses; icls++) {
 
  754         Double_t desired  = ( cls==icls ? 1.0 : 0.0 );
 
  755         Double_t error    = ( GetOutputNeuron( icls )->GetActivationValue() - desired )*eventWeight;
 
  756         GetOutputNeuron( icls )->SetError(error);
 
  759      Double_t desired     = GetDesiredOutput( ev );
 
  761      if (fEstimator==kMSE) error = ( GetOutputNeuron()->GetActivationValue() - desired )*eventWeight;       
 
  762      else if (fEstimator==kCE) error = -eventWeight/(GetOutputNeuron()->GetActivationValue() -1 + desired);  
 
  763      GetOutputNeuron()->SetError(error);
 
  766   CalculateNeuronDeltas();
 
  767   for (
Int_t j=0;j<fSynapses->GetEntriesFast();j++) {
 
  779   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  781   for (
Int_t i=0;i<nSynapses;i++) {
 
  783      Dir[IDX++][0] = -synapse->
GetDEDw();
 
  813   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  816   for (
Int_t i=0;i<nSynapses;i++) {
 
  818      DEDw[IDX++][0] = synapse->
GetDEDw();
 
  821   dir = Hessian * DEDw;
 
  822   for (
Int_t i=0;i<IDX;i++) dir[i][0] = -dir[i][0];
 
  830   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  833   for (
Int_t i=0;i<nSynapses;i++) {
 
  835      Result += Dir[IDX++][0] * synapse->
GetDEDw();
 
  845   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  846   Int_t nWeights = nSynapses;
 
  848   std::vector<Double_t> Origin(nWeights);
 
  849   for (
Int_t i=0;i<nSynapses;i++) {
 
  860   if      (alpha2 < 0.01) alpha2 = 0.01;
 
  861   else if (alpha2 > 2.0)  alpha2 = 2.0;
 
  865   SetDirWeights( Origin, Dir, alpha2 );
 
  873      for (
Int_t i=0;i<100;i++)  {
 
  875         SetDirWeights(Origin, Dir, alpha3);
 
  887         SetDirWeights(Origin, Dir, 0.);
 
  892      for (
Int_t i=0;i<100;i++) {
 
  895            Log() << kWARNING << 
"linesearch, starting to investigate direction opposite of steepestDIR" << 
Endl;
 
  896            alpha2 = -alpha_original;
 
  898         SetDirWeights(Origin, Dir, alpha2);
 
  908         SetDirWeights(Origin, Dir, 0.);
 
  909         Log() << kWARNING << 
"linesearch, failed even in opposite direction of steepestDIR" << 
Endl;
 
  915   if (alpha1>0 && alpha2>0 && alpha3 > 0) {
 
  916      fLastAlpha = 0.5 * (alpha1 + alpha3 -
 
  917                          (err3 - err1) / ((err3 - err2) / ( alpha3 - alpha2 )
 
  918                                           - ( err2 - err1 ) / (alpha2 - alpha1 )));
 
  924   fLastAlpha = fLastAlpha < 10000 ? fLastAlpha : 10000;
 
  926   SetDirWeights(Origin, Dir, fLastAlpha);
 
  933   if (finalError > err1) {
 
  934      Log() << kWARNING << 
"Line search increased error! Something is wrong." 
  935            << 
"fLastAlpha=" << fLastAlpha << 
"al123=" << alpha1 << 
" " 
  936            << alpha2 << 
" " << alpha3 << 
" err1="<< err1 << 
" errfinal=" << finalError << 
Endl;
 
  939   for (
Int_t i=0;i<nSynapses;i++) {
 
  941      buffer[IDX] = synapse->
GetWeight() - Origin[IDX];
 
  945   if (dError) (*dError)=(errOrigin-finalError)/finalError; 
 
  955   Int_t nSynapses = fSynapses->GetEntriesFast();
 
  957   for (
Int_t i=0;i<nSynapses;i++) {
 
  959      synapse->
SetWeight( Origin[IDX] + Dir[IDX][0] * alpha );
 
  962   if (fUseRegulator) UpdatePriors();
 
  970   Int_t nEvents = GetNEvents();
 
  971   UInt_t ntgts = GetNTargets();
 
  974   for (
Int_t i=0;i<nEvents;i++) {
 
  975      const Event* ev = GetEvent(i);
 
  977      if ((ev->
GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
 
  984      if (DoRegression()) {
 
  985         for (
UInt_t itgt = 0; itgt < ntgts; itgt++) {
 
  986            error += GetMSEErr( ev, itgt );
 
  988      } 
else if ( DoMulticlass() ){
 
  989         for( 
UInt_t icls = 0, iclsEnd = DataInfo().GetNClasses(); icls < iclsEnd; icls++ ){
 
  990            error += GetMSEErr( ev, icls );
 
  993         if (fEstimator==kMSE) error = GetMSEErr( ev );  
 
  994         else if (fEstimator==kCE) error= GetCEErr( ev ); 
 
  998   if (fUseRegulator) Result+=fPrior;  
 
  999   if (Result<0) 
Log()<<kWARNING<<
"\nNegative Error!!! :"<<Result-fPrior<<
"+"<<fPrior<<
Endl;
 
 1008   Double_t output = GetOutputNeuron( index )->GetActivationValue();
 
 1010   if      (DoRegression()) target = ev->
GetTarget( index );
 
 1011   else if (DoMulticlass()) target = (ev->
GetClass() == index ? 1.0 : 0.0 );
 
 1012   else                     target = GetDesiredOutput( ev );
 
 1025   Double_t output = GetOutputNeuron( index )->GetActivationValue();
 
 1027   if      (DoRegression()) target = ev->
GetTarget( index );
 
 1028   else if (DoMulticlass()) target = (ev->
GetClass() == index ? 1.0 : 0.0 );
 
 1029   else                     target = GetDesiredOutput( ev );
 
 1049        fEstimatorHistTrain = 
new TH1F( 
"estimatorHistTrain", 
"training estimator",
 
 1050                                        nbinTest, 
Int_t(fTestRate/2), nbinTest*fTestRate+
Int_t(fTestRate/2) );
 
 1051        fEstimatorHistTest  = 
new TH1F( 
"estimatorHistTest", 
"test estimator",
 
 1052                                        nbinTest, 
Int_t(fTestRate/2), nbinTest*fTestRate+
Int_t(fTestRate/2) );
 
 1054   if(fSamplingTraining || fSamplingTesting)
 
 1055      Data()->InitSampling(1.0,1.0,fRandomSeed); 
 
 1057   if (fSteps > 0) 
Log() << kINFO << 
"Inaccurate progress timing for MLP... " << 
Endl;
 
 1065   for (
Int_t i = 0; i < nEpochs; i++) {
 
 1067     if (fExitFromTraining) 
break;
 
 1068     fIPyCurrentIter = i;
 
 1069      if (
Float_t(i)/nEpochs < fSamplingEpoch) {
 
 1070         if ((i+1)%fTestRate == 0 || (i == 0)) {
 
 1071            if (fSamplingTraining) {
 
 1073               Data()->InitSampling(fSamplingFraction,fSamplingWeight);
 
 1074               Data()->CreateSampling();
 
 1076            if (fSamplingTesting) {
 
 1078               Data()->InitSampling(fSamplingFraction,fSamplingWeight);
 
 1079               Data()->CreateSampling();
 
 1085         Data()->InitSampling(1.0,1.0);
 
 1087         Data()->InitSampling(1.0,1.0);
 
 1092      DecaySynapseWeights(i >= lateEpoch);
 
 1095      if ((i+1)%fTestRate == 0) {
 
 1098         if (fInteractive) fInteractive->AddPoint(i+1, trainE, testE);
 
 1101            fEstimatorHistTrain->Fill( i+1, trainE );
 
 1102            fEstimatorHistTest ->Fill( i+1, testE );
 
 1105         if ((testE < GetCurrentValue()) || (GetCurrentValue()<1
e-100)) {
 
 1108         Data()->EventResult( success );
 
 1110         SetCurrentValue( testE );
 
 1111         if (HasConverged()) {
 
 1112            if (
Float_t(i)/nEpochs < fSamplingEpoch) {
 
 1113               Int_t newEpoch = 
Int_t(fSamplingEpoch*nEpochs);
 
 1115               ResetConvergenceCounter();
 
 1118               if (lateEpoch > i) lateEpoch = i;
 
 1125      TString convText = 
Form( 
"<D^2> (train/test): %.4g/%.4g", trainE, testE );
 
 1128         if (
Float_t(i)/nEpochs < fSamplingEpoch)
 
 1129            progress = Progress()*fSamplingEpoch*fSamplingFraction*100;
 
 1131            progress = 100*(fSamplingEpoch*fSamplingFraction+(1.0-fSamplingFraction*fSamplingEpoch)*Progress());
 
 1146   Int_t nEvents = Data()->GetNEvents();
 
 1150   for (
Int_t i = 0; i < nEvents; i++) index[i] = i;
 
 1151   Shuffle(index, nEvents);
 
 1154   for (
Int_t i = 0; i < nEvents; i++) {
 
 1156      const Event * ev = GetEvent(index[i]);
 
 1157      if ((ev->
GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
 
 1162      TrainOneEvent(index[i]);
 
 1165      if (fBPMode == kBatch && (i+1)%fBatchSize == 0) {
 
 1166         AdjustSynapseWeights();
 
 1167         if (fgPRINT_BATCH) {
 
 1196   for (
Int_t i = 0; i < 
n; i++) {
 
 1197      j = (
Int_t) (frgen->Rndm() * 
a);
 
 1200         index[j] = index[i];
 
 1213   Int_t numSynapses = fSynapses->GetEntriesFast();
 
 1214   for (
Int_t i = 0; i < numSynapses; i++) {
 
 1215      synapse = (
TSynapse*)fSynapses->At(i);
 
 1238   if (
type == 0) desired = fOutput->GetMin();  
 
 1239   else           desired = fOutput->GetMax();  
 
 1245   for (
UInt_t j = 0; j < GetNvar(); j++) {
 
 1248      neuron = GetInputNeuron(j);
 
 1252   ForceNetworkCalculations();
 
 1253   UpdateNetwork(desired, eventWeight);
 
 1267   const Event * ev = GetEvent(ievt);
 
 1269   ForceNetworkInputs( ev );
 
 1270   ForceNetworkCalculations();
 
 1271   if (DoRegression()) UpdateNetwork( ev->
GetTargets(),       eventWeight );
 
 1272   if (DoMulticlass()) UpdateNetwork( *DataInfo().GetTargetsForMulticlass( ev ), eventWeight );
 
 1273   else                UpdateNetwork( GetDesiredOutput( ev ), eventWeight );
 
 1281   return DataInfo().IsSignal(ev)?fOutput->GetMax():fOutput->GetMin(); 
 
 1290   Double_t error = GetOutputNeuron()->GetActivationValue() - desired;
 
 1291   if (fEstimator==kMSE)  error = GetOutputNeuron()->GetActivationValue() - desired ;  
 
 1292   else if (fEstimator==kCE)  error = -1./(GetOutputNeuron()->GetActivationValue() -1 + desired); 
 
 1293   else  Log() << kFATAL << 
"Estimator type unspecified!!" << 
Endl;              
 
 1294   error *= eventWeight;
 
 1295   GetOutputNeuron()->SetError(error);
 
 1296   CalculateNeuronDeltas();
 
 1308   for (
UInt_t i = 0, iEnd = desired.size(); i < iEnd; ++i) {
 
 1309      Double_t act = GetOutputNeuron(i)->GetActivationValue();
 
 1314   for (
UInt_t i = 0, iEnd = desired.size(); i < iEnd; ++i) {
 
 1315      Double_t act    = GetOutputNeuron(i)->GetActivationValue();
 
 1318      error *= eventWeight;
 
 1319      GetOutputNeuron(i)->SetError(error);
 
 1323   CalculateNeuronDeltas();
 
 1334   Int_t    numLayers = fNetwork->GetEntriesFast();
 
 1339   for (
Int_t i = numLayers-1; i >= 0; i--) {
 
 1343      for (
Int_t j = 0; j < numNeurons; j++) {
 
 1360   PrintMessage(
"Minimizing Estimator with GA");
 
 1366   fGA_SC_factor = 0.95;
 
 1370   std::vector<Interval*> ranges;
 
 1372   Int_t numWeights = fSynapses->GetEntriesFast();
 
 1373   for (
Int_t ivar=0; ivar< numWeights; ivar++) {
 
 1374      ranges.push_back( 
new Interval( 0, GetXmax(ivar) - GetXmin(ivar) ));
 
 1380   Double_t estimator = CalculateEstimator();
 
 1381   Log() << kINFO << 
"GA: estimator after optimization: " << estimator << 
Endl;
 
 1389   return ComputeEstimator( parameters );
 
 1398   Int_t numSynapses = fSynapses->GetEntriesFast();
 
 1400   for (
Int_t i = 0; i < numSynapses; i++) {
 
 1401      synapse = (
TSynapse*)fSynapses->At(i);
 
 1404   if (fUseRegulator) UpdatePriors(); 
 
 1406   Double_t estimator = CalculateEstimator();
 
 1421   for (
Int_t i = 0; i < numLayers; i++) {
 
 1425      for (
Int_t j = 0; j < numNeurons; j++) {
 
 1443   for (
Int_t i = numLayers-1; i >= 0; i--) {
 
 1447      for (
Int_t j = 0; j < numNeurons; j++) {
 
 1460   Int_t nSynapses = fSynapses->GetEntriesFast();
 
 1461   for (
Int_t i=0;i<nSynapses;i++) {
 
 1463      fPrior+=0.5*fRegulators[fRegulatorIdx[i]]*(synapse->
GetWeight())*(synapse->
GetWeight());
 
 1464      fPriorDev.push_back(fRegulators[fRegulatorIdx[i]]*(synapse->
GetWeight()));
 
 1473   GetApproxInvHessian(InvH);
 
 1474   Int_t numSynapses=fSynapses->GetEntriesFast();
 
 1475   Int_t numRegulators=fRegulators.size();
 
 1478   std::vector<Int_t> nWDP(numRegulators);
 
 1479   std::vector<Double_t> trace(numRegulators),weightSum(numRegulators);
 
 1480   for (
int i=0;i<numSynapses;i++) {
 
 1482      Int_t idx=fRegulatorIdx[i];
 
 1484      trace[idx]+=InvH[i][i];
 
 1485      gamma+=1-fRegulators[idx]*InvH[i][i];
 
 1488   if (fEstimator==kMSE) {
 
 1494   for (
int i=0;i<numRegulators;i++)
 
 1497         fRegulators[i]=variance*nWDP[i]/(weightSum[i]+variance*trace[i]);
 
 1498         if (fRegulators[i]<0) fRegulators[i]=0;
 
 1499         Log()<<kDEBUG<<
"R"<<i<<
":"<<fRegulators[i]<<
"\t";
 
 1504   Log()<<kDEBUG<<
"\n"<<
"trainE:"<<trainE<<
"\ttestE:"<<testE<<
"\tvariance:"<<variance<<
"\tgamma:"<<
gamma<<
Endl;
 
 1512   Int_t numSynapses=fSynapses->GetEntriesFast();
 
 1513   InvHessian.
ResizeTo( numSynapses, numSynapses );
 
 1517   Int_t nEvents = GetNEvents();
 
 1518   for (
Int_t i=0;i<nEvents;i++) {
 
 1520      double outputValue=GetMvaValue(); 
 
 1521      GetOutputNeuron()->SetError(1./fOutput->EvalDerivative(GetOutputNeuron()->GetValue()));
 
 1522      CalculateNeuronDeltas();
 
 1523      for (
Int_t j = 0; j < numSynapses; j++){
 
 1527         sens[j][0]=sensT[0][j]=synapses->
GetDelta();
 
 1529      if (fEstimator==kMSE ) InvHessian+=sens*sensT;
 
 1530      else if (fEstimator==kCE) InvHessian+=(outputValue*(1-outputValue))*sens*sensT;
 
 1535      for (
Int_t i = 0; i < numSynapses; i++){
 
 1536         InvHessian[i][i]+=fRegulators[fRegulatorIdx[i]];
 
 1540      for (
Int_t i = 0; i < numSynapses; i++){
 
 1541         InvHessian[i][i]+=1
e-6; 
 
 1556   if (!fCalculateErrors || errLower==0 || errUpper==0)
 
 1559   Double_t MvaUpper,MvaLower,median,variance;
 
 1560   Int_t numSynapses=fSynapses->GetEntriesFast();
 
 1561   if (fInvHessian.GetNcols()!=numSynapses) {
 
 1562      Log() << kWARNING << 
"inconsistent dimension " << fInvHessian.GetNcols() << 
" vs " << numSynapses << 
Endl;
 
 1566   GetOutputNeuron()->SetError(1./fOutput->EvalDerivative(GetOutputNeuron()->GetValue()));
 
 1568   CalculateNeuronDeltas();
 
 1569   for (
Int_t i = 0; i < numSynapses; i++){
 
 1576   TMatrixD sig=sensT*fInvHessian*sens;
 
 1578   median=GetOutputNeuron()->GetValue();
 
 1581      Log()<<kWARNING<<
"Negative variance!!! median=" << median << 
"\tvariance(sigma^2)=" << variance <<
Endl;
 
 1584   variance=
sqrt(variance);
 
 1587   MvaUpper=fOutput->Eval(median+variance);
 
 1589      *errUpper=MvaUpper-MvaValue;
 
 1592   MvaLower=fOutput->Eval(median-variance);
 
 1594      *errLower=MvaValue-MvaLower;
 
 1600#ifdef MethodMLP_UseMinuit__ 
 1605void TMVA::MethodMLP::MinuitMinimize()
 
 1607   fNumberOfWeights = fSynapses->GetEntriesFast();
 
 1622   for (
Int_t ipar=0; ipar < fNumberOfWeights; ipar++) {
 
 1625                             parName, w[ipar], 0.1, 0, 0 );
 
 1629   tfitter->
SetFCN( &IFCN );
 
 1668   ((MethodMLP*)GetThisPtr())->FCN( npars, grad, 
f, fitPars, iflag );
 
 1671TTHREAD_TLS(
Int_t) nc   = 0;
 
 1672TTHREAD_TLS(
double) minf = 1000000;
 
 1677   for (
Int_t ipar=0; ipar<fNumberOfWeights; ipar++) {
 
 1683   f = CalculateEstimator();
 
 1686   if (
f < minf) minf = 
f;
 
 1687   for (
Int_t ipar=0; ipar<fNumberOfWeights; ipar++) 
Log() << kDEBUG << fitPars[ipar] << 
" ";
 
 1689   Log() << kDEBUG << 
"***** New estimator: " << 
f << 
"  min: " << minf << 
" --> ncalls: " << nc << 
Endl;
 
 1723   Log() << col << 
"--- Short description:" << colres << 
Endl;
 
 1725   Log() << 
"The MLP artificial neural network (ANN) is a traditional feed-" << 
Endl;
 
 1726   Log() << 
"forward multilayer perceptron implementation. The MLP has a user-" << 
Endl;
 
 1727   Log() << 
"defined hidden layer architecture, while the number of input (output)" << 
Endl;
 
 1728   Log() << 
"nodes is determined by the input variables (output classes, i.e., " << 
Endl;
 
 1729   Log() << 
"signal and one background). " << 
Endl;
 
 1731   Log() << col << 
"--- Performance optimisation:" << colres << 
Endl;
 
 1733   Log() << 
"Neural networks are stable and performing for a large variety of " << 
Endl;
 
 1734   Log() << 
"linear and non-linear classification problems. However, in contrast" << 
Endl;
 
 1735   Log() << 
"to (e.g.) boosted decision trees, the user is advised to reduce the " << 
Endl;
 
 1736   Log() << 
"number of input variables that have only little discrimination power. " << 
Endl;
 
 1738   Log() << 
"In the tests we have carried out so far, the MLP and ROOT networks" << 
Endl;
 
 1739   Log() << 
"(TMlpANN, interfaced via TMVA) performed equally well, with however" << 
Endl;
 
 1740   Log() << 
"a clear speed advantage for the MLP. The Clermont-Ferrand neural " << 
Endl;
 
 1741   Log() << 
"net (CFMlpANN) exhibited worse classification performance in these" << 
Endl;
 
 1742   Log() << 
"tests, which is partly due to the slow convergence of its training" << 
Endl;
 
 1743   Log() << 
"(at least 10k training cycles are required to achieve approximately" << 
Endl;
 
 1744   Log() << 
"competitive results)." << 
Endl;
 
 1746   Log() << col << 
"Overtraining: " << colres
 
 1747         << 
"only the TMlpANN performs an explicit separation of the" << 
Endl;
 
 1748   Log() << 
"full training sample into independent training and validation samples." << 
Endl;
 
 1749   Log() << 
"We have found that in most high-energy physics applications the " << 
Endl;
 
 1750   Log() << 
"available degrees of freedom (training events) are sufficient to " << 
Endl;
 
 1751   Log() << 
"constrain the weights of the relatively simple architectures required" << 
Endl;
 
 1752   Log() << 
"to achieve good performance. Hence no overtraining should occur, and " << 
Endl;
 
 1753   Log() << 
"the use of validation samples would only reduce the available training" << 
Endl;
 
 1754   Log() << 
"information. However, if the performance on the training sample is " << 
Endl;
 
 1755   Log() << 
"found to be significantly better than the one found with the inde-" << 
Endl;
 
 1756   Log() << 
"pendent test sample, caution is needed. The results for these samples " << 
Endl;
 
 1757   Log() << 
"are printed to standard output at the end of each training job." << 
Endl;
 
 1759   Log() << col << 
"--- Performance tuning via configuration options:" << colres << 
Endl;
 
 1761   Log() << 
"The hidden layer architecture for all ANNs is defined by the option" << 
Endl;
 
 1762   Log() << 
"\"HiddenLayers=N+1,N,...\", where here the first hidden layer has N+1" << 
Endl;
 
 1763   Log() << 
"neurons and the second N neurons (and so on), and where N is the number  " << 
Endl;
 
 1764   Log() << 
"of input variables. Excessive numbers of hidden layers should be avoided," << 
Endl;
 
 1765   Log() << 
"in favour of more neurons in the first hidden layer." << 
Endl;
 
 1767   Log() << 
"The number of cycles should be above 500. As said, if the number of" << 
Endl;
 
 1768   Log() << 
"adjustable weights is small compared to the training sample size," << 
Endl;
 
 1769   Log() << 
"using a large number of training samples should not lead to overtraining." << 
Endl;
 
#define REGISTER_METHOD(CLASS)
for example
 
TMatrixT< Double_t > TMatrixD
 
char * Form(const char *fmt,...)
 
The ROOT standard fitter based on TMinuit.
 
virtual Int_t SetParameter(Int_t ipar, const char *parname, Double_t value, Double_t verr, Double_t vlow, Double_t vhigh)
set initial values for a parameter
 
virtual Int_t ExecuteCommand(const char *command, Double_t *args, Int_t nargs)
Execute a fitter command; command : command string args : list of nargs command arguments.
 
virtual void SetFCN(void(*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
Specify the address of the fitting algorithm.
 
1-D histogram with a float per channel (see TH1 documentation)}
 
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
 
Bool_t WriteOptionsReference() const
 
Class that contains all the data information.
 
std::vector< Float_t > & GetTargets()
 
Double_t GetWeight() const
return the event weight - depending on whether the flag IgnoreNegWeightsInTraining is or not.
 
Float_t GetTarget(UInt_t itgt) const
 
Base class for TMVA fitters.
 
Double_t Run()
estimator function interface for fitting
 
Fitter using a Genetic Algorithm.
 
The TMVA::Interval Class.
 
Base class for all TMVA methods using artificial neural networks.
 
virtual void ProcessOptions()
do nothing specific at this moment
 
virtual void MakeClassSpecific(std::ostream &, const TString &) const
write specific classifier response
 
virtual Double_t GetMvaValue(Double_t *err=0, Double_t *errUpper=0)
get the mva value generated by the NN
 
Multilayer Perceptron class built off of MethodANNBase.
 
Bool_t LineSearch(TMatrixD &Dir, std::vector< Double_t > &Buffer, Double_t *dError=0)
 
void GetHelpMessage() const
get help message text
 
void BackPropagationMinimize(Int_t nEpochs)
minimize estimator / train network with back propagation algorithm
 
Double_t GetMSEErr(const Event *ev, UInt_t index=0)
 
Double_t GetMvaValue(Double_t *err=0, Double_t *errUpper=0)
get the mva value generated by the NN
 
void MakeClassSpecific(std::ostream &, const TString &) const
write specific classifier response
 
void AdjustSynapseWeights()
just adjust the synapse weights (should be called in batch mode)
 
void SteepestDir(TMatrixD &Dir)
 
void TrainOneEpoch()
train network over a single epoch/cycle of events
 
virtual Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets)
MLP can handle classification with 2 classes and regression with one regression-target.
 
Bool_t GetHessian(TMatrixD &Hessian, TMatrixD &Gamma, TMatrixD &Delta)
 
Double_t ComputeEstimator(std::vector< Double_t > ¶meters)
this function is called by GeneticANN for GA optimization
 
void InitializeLearningRates()
initialize learning rates of synapses, used only by back propagation
 
void CalculateNeuronDeltas()
have each neuron calculate its delta by back propagation
 
Double_t DerivDir(TMatrixD &Dir)
 
Double_t GetCEErr(const Event *ev, UInt_t index=0)
 
virtual ~MethodMLP()
destructor nothing to be done
 
void SetDir(TMatrixD &Hessian, TMatrixD &Dir)
 
void Shuffle(Int_t *index, Int_t n)
Input:
 
void SimulateEvent(const Event *ev)
 
void SetDirWeights(std::vector< Double_t > &Origin, TMatrixD &Dir, Double_t alpha)
 
void SetGammaDelta(TMatrixD &Gamma, TMatrixD &Delta, std::vector< Double_t > &Buffer)
 
Double_t EstimatorFunction(std::vector< Double_t > ¶meters)
interface to the estimate
 
void GetApproxInvHessian(TMatrixD &InvHessian, bool regulate=true)
 
void BFGSMinimize(Int_t nEpochs)
train network with BFGS algorithm
 
void UpdateSynapses()
update synapse error fields and adjust the weights (if in sequential mode)
 
void Init()
default initializations
 
void ProcessOptions()
process user options
 
void TrainOneEvent(Int_t ievt)
train network over a single event this uses the new event model
 
Double_t GetDesiredOutput(const Event *ev)
get the desired output of this event
 
void GeneticMinimize()
create genetics class similar to GeneticCut give it vector of parameter ranges (parameters = weights)...
 
void DecaySynapseWeights(Bool_t lateEpoch)
decay synapse weights in last 10 epochs, lower learning rate even more to find a good minimum
 
void TrainOneEventFast(Int_t ievt, Float_t *&branchVar, Int_t &type)
fast per-event training
 
void UpdateNetwork(Double_t desired, Double_t eventWeight=1.0)
update the network based on how closely the output matched the desired output
 
MethodMLP(const TString &jobName, const TString &methodTitle, DataSetInfo &theData, const TString &theOption)
standard constructor
 
void DeclareOptions()
define the options (their key words) that can be set in the option string
 
Double_t CalculateEstimator(Types::ETreeType treeType=Types::kTraining, Int_t iEpoch=-1)
calculate the estimator that training is attempting to minimize
 
Neuron class used by TMVA artificial neural network methods.
 
void AdjustSynapseWeights()
adjust the pre-synapses' weights for each neuron (input neuron has no pre-synapse) this method should...
 
void ForceValue(Double_t value)
force the value, typically for input and bias neurons
 
void UpdateSynapsesSequential()
update the pre-synapses for each neuron (input neuron has no pre-synapse) this method should only be ...
 
void UpdateSynapsesBatch()
update and adjust the pre-synapses for each neuron (input neuron has no pre-synapse) this method shou...
 
void CalculateDelta()
calculate error field
 
Synapse class used by TMVA artificial neural network methods.
 
void SetWeight(Double_t weight)
set synapse weight
 
void SetDEDw(Double_t DEDw)
 
void SetLearningRate(Double_t rate)
 
void DecayLearningRate(Double_t rate)
 
void CalculateDelta()
calculate/adjust the error field for this synapse
 
Timing information for training and evaluation of MVA methods.
 
void DrawProgressBar(Int_t, const TString &comment="")
draws progress bar in color or B&W caution:
 
Singleton class for Global types used by TMVA.
 
virtual TMatrixTBase< Element > & UnitMatrix()
Make a unit matrix (matrix need not be a square one).
 
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1)
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
 
TMatrixT< Element > & Invert(Double_t *det=0)
Invert the matrix and calculate its determinant.
 
TMatrixT< Element > & Transpose(const TMatrixT< Element > &source)
Transpose matrix source.
 
Int_t GetEntriesFast() const
 
TObject * At(Int_t idx) const
 
This is a simple weighted bidirectional connection between two neurons.
 
void SetWeight(Double_t w)
Sets the weight of the synapse.
 
std::string GetName(const std::string &scope_name)
 
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
 
MsgLogger & Endl(MsgLogger &ml)
 
Double_t Sqrt(Double_t x)
 
Double_t Gamma(Double_t z)
Computation of gamma(z) for all z.
 
static void output(int code)