Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
MethodMLP.cxx
Go to the documentation of this file.
1// @(#)root/tmva $Id$
2// Author: Krzysztof Danielowski, Andreas Hoecker, Matt Jachowski, Kamil Kraszewski, Maciej Kruk, Peter Speckmayer, Joerg Stelzer, Eckhard v. Toerne, Jan Therhaag, Jiahang Zhong
3
4/**********************************************************************************
5 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6 * Package: TMVA *
7 * Class : MethodMLP *
8 * *
9 * *
10 * Description: *
11 * ANN Multilayer Perceptron class for the discrimination of signal *
12 * from background. BFGS implementation based on TMultiLayerPerceptron *
13 * class from ROOT (http://root.cern.ch). *
14 * *
15 * Authors (alphabetical): *
16 * Krzysztof Danielowski <danielow@cern.ch> - IFJ & AGH, Poland *
17 * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
18 * Matt Jachowski <jachowski@stanford.edu> - Stanford University, USA *
19 * Kamil Kraszewski <kalq@cern.ch> - IFJ & UJ, Poland *
20 * Maciej Kruk <mkruk@cern.ch> - IFJ & AGH, Poland *
21 * Peter Speckmayer <peter.speckmayer@cern.ch> - CERN, Switzerland *
22 * Joerg Stelzer <stelzer@cern.ch> - DESY, Germany *
23 * Jan Therhaag <Jan.Therhaag@cern.ch> - U of Bonn, Germany *
24 * Eckhard v. Toerne <evt@uni-bonn.de> - U of Bonn, Germany *
25 * Jiahang Zhong <Jiahang.Zhong@cern.ch> - Academia Sinica, Taipei *
26 * *
27 * Copyright (c) 2005-2011: *
28 * CERN, Switzerland *
29 * U. of Victoria, Canada *
30 * MPI-K Heidelberg, Germany *
31 * U. of Bonn, Germany *
32 * *
33 * Redistribution and use in source and binary forms, with or without *
34 * modification, are permitted according to the terms listed in LICENSE *
35 * (see tmva/doc/LICENSE) *
36 **********************************************************************************/
37
38/*! \class TMVA::MethodMLP
39\ingroup TMVA
40
41Multilayer Perceptron class built off of MethodANNBase
42
43*/
44
45#include "TMVA/MethodMLP.h"
46
47#include "TMVA/Config.h"
48#include "TMVA/Configurable.h"
51#include "TMVA/DataSet.h"
52#include "TMVA/DataSetInfo.h"
53#include "TMVA/FitterBase.h"
54#include "TMVA/GeneticFitter.h"
55#include "TMVA/IFitterTarget.h"
56#include "TMVA/IMethod.h"
57#include "TMVA/Interval.h"
58#include "TMVA/MethodANNBase.h"
59#include "TMVA/MsgLogger.h"
60#include "TMVA/TNeuron.h"
61#include "TMVA/TSynapse.h"
62#include "TMVA/Timer.h"
63#include "TMVA/Tools.h"
64#include "TMVA/Types.h"
65
66#include "TH1.h"
67#include "TString.h"
68#include "TFitter.h"
69#include "TMatrixD.h"
70#include "TMath.h"
71
72#include <iostream>
73#include <cmath>
74#include <vector>
75
76#ifdef MethodMLP_UseMinuit__
77TMVA::MethodMLP* TMVA::MethodMLP::fgThis = 0;
79#endif
80
82
83
84 using std::vector;
85
86////////////////////////////////////////////////////////////////////////////////
87/// standard constructor
88
90 const TString& methodTitle,
92 const TString& theOption)
93 : MethodANNBase( jobName, Types::kMLP, methodTitle, theData, theOption),
94 fUseRegulator(false), fCalculateErrors(false),
95 fPrior(0.0), fPriorDev(0), fUpdateLimit(0),
96 fTrainingMethod(kBFGS), fTrainMethodS("BFGS"),
97 fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
98 fSamplingTraining(false), fSamplingTesting(false),
99 fLastAlpha(0.0), fTau(0.),
100 fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
101 fBPMode(kSequential), fBpModeS("None"),
102 fBatchSize(0), fTestRate(0), fEpochMon(false),
103 fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
104 fGA_SC_rate(0), fGA_SC_factor(0.0),
105 fDeviationsFromTargets(0),
106 fWeightRange (1.0)
107{
108
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// constructor from a weight file
113
115 const TString& theWeightFile)
117 fUseRegulator(false), fCalculateErrors(false),
118 fPrior(0.0), fPriorDev(0), fUpdateLimit(0),
119 fTrainingMethod(kBFGS), fTrainMethodS("BFGS"),
120 fSamplingFraction(1.0), fSamplingEpoch(0.0), fSamplingWeight(0.0),
121 fSamplingTraining(false), fSamplingTesting(false),
122 fLastAlpha(0.0), fTau(0.),
123 fResetStep(0), fLearnRate(0.0), fDecayRate(0.0),
124 fBPMode(kSequential), fBpModeS("None"),
125 fBatchSize(0), fTestRate(0), fEpochMon(false),
126 fGA_nsteps(0), fGA_preCalc(0), fGA_SC_steps(0),
127 fGA_SC_rate(0), fGA_SC_factor(0.0),
128 fDeviationsFromTargets(0),
129 fWeightRange (1.0)
130{
131}
132
133////////////////////////////////////////////////////////////////////////////////
134/// destructor
135/// nothing to be done
136
140
142{
143 Train(NumCycles());
144}
145
146
147
148////////////////////////////////////////////////////////////////////////////////
149/// MLP can handle classification with 2 classes and regression with one regression-target
150
152{
153 if (type == Types::kClassification && numberClasses == 2 ) return kTRUE;
154 if (type == Types::kMulticlass ) return kTRUE;
155 if (type == Types::kRegression ) return kTRUE;
156
157 return kFALSE;
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// default initializations
162
164{
165 // the minimum requirement to declare an event signal-like
166 SetSignalReferenceCut( 0.5 );
167#ifdef MethodMLP_UseMinuit__
168 fgThis = this;
169#endif
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// define the options (their key words) that can be set in the option string
174///
175/// know options:
176///
177/// - TrainingMethod `<string>` Training method
178/// available values are:
179/// - BP Back-Propagation `<default>`
180/// - GA Genetic Algorithm (takes a LONG time)
181///
182/// - LearningRate `<float>` NN learning rate parameter
183/// - DecayRate `<float>` Decay rate for learning parameter
184/// - TestRate `<int>` Test for overtraining performed at each #%th epochs
185///
186/// - BPMode `<string>` Back-propagation learning mode
187/// available values are:
188/// - sequential `<default>`
189/// - batch
190///
191/// - BatchSize `<int>` Batch size: number of events/batch, only set if in Batch Mode,
192/// - -1 for BatchSize=number_of_events
193
195{
196 DeclareOptionRef(fTrainMethodS="BP", "TrainingMethod",
197 "Train with Back-Propagation (BP), BFGS Algorithm (BFGS), or Genetic Algorithm (GA - slower and worse)");
198 AddPreDefVal(TString("BP"));
199 AddPreDefVal(TString("GA"));
200 AddPreDefVal(TString("BFGS"));
201
202 DeclareOptionRef(fLearnRate=0.02, "LearningRate", "ANN learning rate parameter");
203 DeclareOptionRef(fDecayRate=0.01, "DecayRate", "Decay rate for learning parameter");
204 DeclareOptionRef(fTestRate =10, "TestRate", "Test for overtraining performed at each #th epochs");
205 DeclareOptionRef(fEpochMon = kFALSE, "EpochMonitoring", "Provide epoch-wise monitoring plots according to TestRate (caution: causes big ROOT output file!)" );
206
207 DeclareOptionRef(fSamplingFraction=1.0, "Sampling","Only 'Sampling' (randomly selected) events are trained each epoch");
208 DeclareOptionRef(fSamplingEpoch=1.0, "SamplingEpoch","Sampling is used for the first 'SamplingEpoch' epochs, afterwards, all events are taken for training");
209 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.");
210
211 DeclareOptionRef(fSamplingTraining=kTRUE, "SamplingTraining","The training sample is sampled");
212 DeclareOptionRef(fSamplingTesting= kFALSE, "SamplingTesting" ,"The testing sample is sampled");
213
214 DeclareOptionRef(fResetStep=50, "ResetStep", "How often BFGS should reset history");
215 DeclareOptionRef(fTau =3.0, "Tau", "LineSearch \"size step\"");
216
217 DeclareOptionRef(fBpModeS="sequential", "BPMode",
218 "Back-propagation learning mode: sequential or batch");
219 AddPreDefVal(TString("sequential"));
220 AddPreDefVal(TString("batch"));
221
222 DeclareOptionRef(fBatchSize=-1, "BatchSize",
223 "Batch size: number of events/batch, only set if in Batch Mode, -1 for BatchSize=number_of_events");
224
225 DeclareOptionRef(fImprovement=1e-30, "ConvergenceImprove",
226 "Minimum improvement which counts as improvement (<0 means automatic convergence check is turned off)");
227
228 DeclareOptionRef(fSteps=-1, "ConvergenceTests",
229 "Number of steps (without improvement) required for convergence (<0 means automatic convergence check is turned off)");
230
231 DeclareOptionRef(fUseRegulator=kFALSE, "UseRegulator",
232 "Use regulator to avoid over-training"); //zjh
233 DeclareOptionRef(fUpdateLimit=10000, "UpdateLimit",
234 "Maximum times of regulator update"); //zjh
235 DeclareOptionRef(fCalculateErrors=kFALSE, "CalculateErrors",
236 "Calculates inverse Hessian matrix at the end of the training to be able to calculate the uncertainties of an MVA value"); //zjh
237
238 DeclareOptionRef(fWeightRange=1.0, "WeightRange",
239 "Take the events for the estimator calculations from small deviations from the desired value to large deviations only over the weight range");
240
241}
242
243////////////////////////////////////////////////////////////////////////////////
244/// process user options
245
247{
249
250
251 if (IgnoreEventsWithNegWeightsInTraining()) {
252 Log() << kINFO
253 << "Will ignore negative events in training!"
254 << Endl;
255 }
256
257
258 if (fTrainMethodS == "BP" ) fTrainingMethod = kBP;
259 else if (fTrainMethodS == "BFGS") fTrainingMethod = kBFGS;
260 else if (fTrainMethodS == "GA" ) fTrainingMethod = kGA;
261
262 if (fBpModeS == "sequential") fBPMode = kSequential;
263 else if (fBpModeS == "batch") fBPMode = kBatch;
264
265 // InitializeLearningRates();
266
267 if (fBPMode == kBatch) {
268 Data()->SetCurrentType(Types::kTraining);
269 Int_t numEvents = Data()->GetNEvents();
271 }
272}
273
274////////////////////////////////////////////////////////////////////////////////
275/// initialize learning rates of synapses, used only by back propagation
276
278{
279 Log() << kDEBUG << "Initialize learning rates" << Endl;
281 Int_t numSynapses = fSynapses->GetEntriesFast();
282 for (Int_t i = 0; i < numSynapses; i++) {
283 synapse = (TSynapse*)fSynapses->At(i);
284 synapse->SetLearningRate(fLearnRate);
285 }
286}
287
288////////////////////////////////////////////////////////////////////////////////
289/// calculate the estimator that training is attempting to minimize
290
292{
293 // sanity check
295 Log() << kFATAL << "<CalculateEstimator> fatal error: wrong tree type: " << treeType << Endl;
296 }
297
298 Types::ETreeType saveType = Data()->GetCurrentType();
299 Data()->SetCurrentType(treeType);
300
301 // if epochs are counted create monitoring histograms (only available for classification)
302 TString type = (treeType == Types::kTraining ? "train" : "test");
303 TString name = TString::Format("convergencetest___mlp_%s_epoch_%04i", type.Data(), iEpoch);
304 TString nameB = name + "_B";
305 TString nameS = name + "_S";
306 Int_t nbin = 100;
307 Float_t limit = 2;
308 TH1* histS = 0;
309 TH1* histB = 0;
310 if (fEpochMon && iEpoch >= 0 && !DoRegression()) {
311 histS = new TH1F( nameS, nameS, nbin, -limit, limit );
312 histB = new TH1F( nameB, nameB, nbin, -limit, limit );
313 }
314
316
317 // loop over all training events
318 Int_t nEvents = GetNEvents();
319 UInt_t nClasses = DataInfo().GetNClasses();
320 UInt_t nTgts = DataInfo().GetNTargets();
321
322
323 Float_t sumOfWeights = 0.f;
324 if( fWeightRange < 1.f ){
325 fDeviationsFromTargets = new std::vector<std::pair<Float_t,Float_t> >(nEvents);
326 }
327
328 for (Int_t i = 0; i < nEvents; i++) {
329
330 const Event* ev = GetEvent(i);
331
332 if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
333 && (saveType == Types::kTraining)){
334 continue;
335 }
336
337 Double_t w = ev->GetWeight();
338
339 ForceNetworkInputs( ev );
340 ForceNetworkCalculations();
341
342 Double_t d = 0, v = 0;
343 if (DoRegression()) {
344 for (UInt_t itgt = 0; itgt < nTgts; itgt++) {
345 v = GetOutputNeuron( itgt )->GetActivationValue();
346 Double_t targetValue = ev->GetTarget( itgt );
348 d += (dt*dt);
349 }
350 estimator += d*w;
351 } else if (DoMulticlass() ) {
352 UInt_t cls = ev->GetClass();
353 if (fEstimator==kCE){
354 Double_t norm(0);
355 for (UInt_t icls = 0; icls < nClasses; icls++) {
356 Float_t activationValue = GetOutputNeuron( icls )->GetActivationValue();
357 norm += exp( activationValue );
358 if(icls==cls)
359 d = exp( activationValue );
360 }
361 d = -TMath::Log(d/norm);
362 }
363 else{
364 for (UInt_t icls = 0; icls < nClasses; icls++) {
365 Double_t desired = (icls==cls) ? 1.0 : 0.0;
366 v = GetOutputNeuron( icls )->GetActivationValue();
367 d = (desired-v)*(desired-v);
368 }
369 }
370 estimator += d*w; //zjh
371 } else {
372 Double_t desired = DataInfo().IsSignal(ev)?1.:0.;
373 v = GetOutputNeuron()->GetActivationValue();
374 if (fEstimator==kMSE) d = (desired-v)*(desired-v); //zjh
375 else if (fEstimator==kCE) d = -2*(desired*TMath::Log(v)+(1-desired)*TMath::Log(1-v)); //zjh
376 estimator += d*w; //zjh
377 }
378
379 if( fDeviationsFromTargets )
380 fDeviationsFromTargets->push_back(std::pair<Float_t,Float_t>(d,w));
381
382 sumOfWeights += w;
383
384
385 // fill monitoring histograms
386 if (DataInfo().IsSignal(ev) && histS != 0) histS->Fill( float(v), float(w) );
387 else if (histB != 0) histB->Fill( float(v), float(w) );
388 }
389
390
391 if( fDeviationsFromTargets ) {
392 std::sort(fDeviationsFromTargets->begin(),fDeviationsFromTargets->end());
393
395 estimator = 0.f;
396
397 Float_t weightRangeCut = fWeightRange*sumOfWeights;
398 Float_t weightSum = 0.f;
399 for(std::vector<std::pair<Float_t,Float_t> >::iterator itDev = fDeviationsFromTargets->begin(), itDevEnd = fDeviationsFromTargets->end(); itDev != itDevEnd; ++itDev ){
400 float deviation = (*itDev).first;
401 float devWeight = (*itDev).second;
402 weightSum += devWeight; // add the weight of this event
403 if( weightSum <= weightRangeCut ) { // if within the region defined by fWeightRange
405 }
406 }
407
409 delete fDeviationsFromTargets;
410 }
411
412 if (histS != 0) fEpochMonHistS.push_back( histS );
413 if (histB != 0) fEpochMonHistB.push_back( histB );
414
415 //if (DoRegression()) estimator = TMath::Sqrt(estimator/Float_t(nEvents));
416 //else if (DoMulticlass()) estimator = TMath::Sqrt(estimator/Float_t(nEvents));
417 //else estimator = estimator*0.5/Float_t(nEvents);
419
420
421 //if (fUseRegulator) estimator+=fPrior/Float_t(nEvents); //zjh
422
423 Data()->SetCurrentType( saveType );
424
425 // provide epoch-wise monitoring
426 if (fEpochMon && iEpoch >= 0 && !DoRegression() && treeType == Types::kTraining) {
427 CreateWeightMonitoringHists( TString::Format("epochmonitoring___epoch_%04i_weights_hist", iEpoch), &fEpochMonHistW );
428 }
429
430 return estimator;
431}
432
433////////////////////////////////////////////////////////////////////////////////
434
436{
437 if (fNetwork == 0) {
438 //Log() << kERROR <<"ANN Network is not initialized, doing it now!"<< Endl;
439 Log() << kFATAL <<"ANN Network is not initialized, doing it now!"<< Endl;
440 SetAnalysisType(GetAnalysisType());
441 }
442 Log() << kDEBUG << "reinitialize learning rates" << Endl;
443 InitializeLearningRates();
444 Log() << kHEADER;
445 PrintMessage("Training Network");
446 Log() << Endl;
447 Int_t nEvents=GetNEvents();
448 Int_t nSynapses=fSynapses->GetEntriesFast();
449 if (nSynapses>nEvents)
450 Log()<<kWARNING<<"ANN too complicated: #events="<<nEvents<<"\t#synapses="<<nSynapses<<Endl;
451
452
453#ifdef MethodMLP_UseMinuit__
455#else
456 if (fTrainingMethod == kGA) GeneticMinimize();
457 else if (fTrainingMethod == kBFGS) BFGSMinimize(nEpochs);
458 else BackPropagationMinimize(nEpochs);
459#endif
460
461 float trainE = CalculateEstimator( Types::kTraining, 0 ) ; // estimator for training sample //zjh
462 float testE = CalculateEstimator( Types::kTesting, 0 ) ; // estimator for test sample //zjh
463 if (fUseRegulator){
464 Log()<<kINFO<<"Finalizing handling of Regulator terms, trainE="<<trainE<<" testE="<<testE<<Endl;
465 UpdateRegulators();
466 Log()<<kINFO<<"Done with handling of Regulator terms"<<Endl;
467 }
468
469 if( fCalculateErrors || fUseRegulator )
470 {
471 Int_t numSynapses=fSynapses->GetEntriesFast();
472 fInvHessian.ResizeTo(numSynapses,numSynapses);
473 GetApproxInvHessian( fInvHessian ,false);
474 }
475}
476
477////////////////////////////////////////////////////////////////////////////////
478/// train network with BFGS algorithm
479
481{
482 Timer timer( (fSteps>0?100:nEpochs), GetName() );
483
484 // create histograms for overtraining monitoring
485 Int_t nbinTest = Int_t(nEpochs/fTestRate);
486 if(!IsSilentFile())
487 {
488 fEstimatorHistTrain = new TH1F( "estimatorHistTrain", "training estimator",
489 nbinTest, Int_t(fTestRate/2), nbinTest*fTestRate+Int_t(fTestRate/2) );
490 fEstimatorHistTest = new TH1F( "estimatorHistTest", "test estimator",
491 nbinTest, Int_t(fTestRate/2), nbinTest*fTestRate+Int_t(fTestRate/2) );
492 }
493
494 Int_t nSynapses = fSynapses->GetEntriesFast();
496
497 for (Int_t i=0;i<nSynapses;i++) {
498 TSynapse* synapse = (TSynapse*)fSynapses->At(i);
499 synapse->SetDEDw(0.0);
500 }
501
502 std::vector<Double_t> buffer( nWeights );
503 for (Int_t i=0;i<nWeights;i++) buffer[i] = 0.;
504
505 TMatrixD Dir ( nWeights, 1 );
506 TMatrixD Hessian ( nWeights, nWeights );
507 TMatrixD Gamma ( nWeights, 1 );
508 TMatrixD Delta ( nWeights, 1 );
509 Int_t RegUpdateCD=0; //zjh
510 Int_t RegUpdateTimes=0; //zjh
512
513 Double_t trainE = -1;
514 Double_t testE = -1;
515
516 fLastAlpha = 0.;
517
518 if(fSamplingTraining || fSamplingTesting)
519 Data()->InitSampling(1.0,1.0,fRandomSeed); // initialize sampling to initialize the random generator with the given seed
520
521 if (fSteps > 0) Log() << kINFO << "Inaccurate progress timing for MLP... " << Endl;
522 timer.DrawProgressBar( 0 );
523
524 // start training cycles (epochs)
525 for (Int_t i = 0; i < nEpochs; i++) {
526
527 if (Float_t(i)/nEpochs < fSamplingEpoch) {
528 if ((i+1)%fTestRate == 0 || (i == 0)) {
529 if (fSamplingTraining) {
530 Data()->SetCurrentType( Types::kTraining );
531 Data()->InitSampling(fSamplingFraction,fSamplingWeight);
532 Data()->CreateSampling();
533 }
534 if (fSamplingTesting) {
535 Data()->SetCurrentType( Types::kTesting );
536 Data()->InitSampling(fSamplingFraction,fSamplingWeight);
537 Data()->CreateSampling();
538 }
539 }
540 }
541 else {
542 Data()->SetCurrentType( Types::kTraining );
543 Data()->InitSampling(1.0,1.0);
544 Data()->SetCurrentType( Types::kTesting );
545 Data()->InitSampling(1.0,1.0);
546 }
547 Data()->SetCurrentType( Types::kTraining );
548
549 //zjh
550 if (fUseRegulator) {
551 UpdatePriors();
552 RegUpdateCD++;
553 }
554 //zjh
555
556 SetGammaDelta( Gamma, Delta, buffer );
557
558 if (i % fResetStep == 0 && i<0.5*nEpochs) { //zjh
559 SteepestDir( Dir );
560 Hessian.UnitMatrix();
561 RegUpdateCD=0; //zjh
562 }
563 else {
564 if (GetHessian( Hessian, Gamma, Delta )) {
565 SteepestDir( Dir );
566 Hessian.UnitMatrix();
567 RegUpdateCD=0; //zjh
568 }
569 else SetDir( Hessian, Dir );
570 }
571
572 Double_t dError=0; //zjh
573 if (DerivDir( Dir ) > 0) {
574 SteepestDir( Dir );
575 Hessian.UnitMatrix();
576 RegUpdateCD=0; //zjh
577 }
578 if (LineSearch( Dir, buffer, &dError )) { //zjh
579 Hessian.UnitMatrix();
580 SteepestDir( Dir );
581 RegUpdateCD=0; //zjh
582 if (LineSearch(Dir, buffer, &dError)) { //zjh
583 i = nEpochs;
584 Log() << kFATAL << "Line search failed! Huge troubles somewhere..." << Endl;
585 }
586 }
587
588 //zjh+
589 if (dError<0) Log()<<kWARNING<<"\nnegative dError=" <<dError<<Endl;
591
592 if ( fUseRegulator && RegUpdateTimes<fUpdateLimit && RegUpdateCD>=5 && fabs(dError)<0.1*AccuError) {
593 Log()<<kDEBUG<<"\n\nUpdate regulators "<<RegUpdateTimes<<" on epoch "<<i<<"\tdError="<<dError<<Endl;
594 UpdateRegulators();
595 Hessian.UnitMatrix();
596 RegUpdateCD=0;
598 AccuError=0;
599 }
600 //zjh-
601
602 // monitor convergence of training and control sample
603 if ((i+1)%fTestRate == 0) {
604 //trainE = CalculateEstimator( Types::kTraining, i ) - fPrior/Float_t(GetNEvents()); // estimator for training sample //zjh
605 //testE = CalculateEstimator( Types::kTesting, i ) - fPrior/Float_t(GetNEvents()); // estimator for test sample //zjh
606 trainE = CalculateEstimator( Types::kTraining, i ) ; // estimator for training sample //zjh
607 testE = CalculateEstimator( Types::kTesting, i ) ; // estimator for test sample //zjh
608 if(!IsSilentFile()) //saved to see in TMVAGui, no needed without file
609 {
610 fEstimatorHistTrain->Fill( i+1, trainE );
611 fEstimatorHistTest ->Fill( i+1, testE );
612 }
614 if ((testE < GetCurrentValue()) || (GetCurrentValue()<1e-100)) {
615 success = kTRUE;
616 }
617 Data()->EventResult( success );
618
619 SetCurrentValue( testE );
620 if (HasConverged()) {
621 if (Float_t(i)/nEpochs < fSamplingEpoch) {
622 Int_t newEpoch = Int_t(fSamplingEpoch*nEpochs);
623 i = newEpoch;
624 ResetConvergenceCounter();
625 }
626 else break;
627 }
628 }
629
630 // draw progress
631 TString convText = TString::Format( "<D^2> (train/test/epoch): %.4g/%.4g/%d", trainE, testE,i ); //zjh
632 if (fSteps > 0) {
633 Float_t progress = 0;
634 if (Float_t(i)/nEpochs < fSamplingEpoch)
635 // progress = Progress()*fSamplingEpoch*fSamplingFraction*100;
636 progress = Progress()*fSamplingFraction*100*fSamplingEpoch;
637 else
638 {
639 // progress = 100.0*(fSamplingEpoch*fSamplingFraction+(1.0-fSamplingFraction*fSamplingEpoch)*Progress());
640 progress = 100.0*(fSamplingFraction*fSamplingEpoch+(1.0-fSamplingEpoch)*Progress());
641 }
642 Float_t progress2= 100.0*RegUpdateTimes/fUpdateLimit; //zjh
643 if (progress2>progress) progress=progress2; //zjh
644 timer.DrawProgressBar( Int_t(progress), convText );
645 }
646 else {
647 Int_t progress=Int_t(nEpochs*RegUpdateTimes/Float_t(fUpdateLimit)); //zjh
648 if (progress<i) progress=i; //zjh
649 timer.DrawProgressBar( progress, convText ); //zjh
650 }
651
652 // some verbose output
653 if (fgPRINT_SEQ) {
654 PrintNetwork();
655 WaitForKeyboard();
656 }
657 }
658}
659
660////////////////////////////////////////////////////////////////////////////////
661
662void TMVA::MethodMLP::SetGammaDelta( TMatrixD &Gamma, TMatrixD &Delta, std::vector<Double_t> &buffer )
663{
664 Int_t nWeights = fSynapses->GetEntriesFast();
665
666 Int_t IDX = 0;
667 Int_t nSynapses = fSynapses->GetEntriesFast();
668 for (Int_t i=0;i<nSynapses;i++) {
669 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
670 Gamma[IDX++][0] = -synapse->GetDEDw();
671 }
672
673 for (Int_t i=0;i<nWeights;i++) Delta[i][0] = buffer[i];
674
675 ComputeDEDw();
676
677 IDX = 0;
678 for (Int_t i=0;i<nSynapses;i++)
679 {
680 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
681 Gamma[IDX++][0] += synapse->GetDEDw();
682 }
683}
684
685////////////////////////////////////////////////////////////////////////////////
686
688{
689 Int_t nSynapses = fSynapses->GetEntriesFast();
690 for (Int_t i=0;i<nSynapses;i++) {
691 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
692 synapse->SetDEDw( 0.0 );
693 }
694
695 Int_t nEvents = GetNEvents();
696 Int_t nPosEvents = nEvents;
697 for (Int_t i=0;i<nEvents;i++) {
698
699 const Event* ev = GetEvent(i);
700 if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
701 && (Data()->GetCurrentType() == Types::kTraining)){
702 --nPosEvents;
703 continue;
704 }
705
706 SimulateEvent( ev );
707
708 for (Int_t j=0;j<nSynapses;j++) {
709 TSynapse *synapse = (TSynapse*)fSynapses->At(j);
710 synapse->SetDEDw( synapse->GetDEDw() + synapse->GetDelta() );
711 }
712 }
713
714 for (Int_t i=0;i<nSynapses;i++) {
715 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
716 Double_t DEDw=synapse->GetDEDw(); //zjh
717 if (fUseRegulator) DEDw+=fPriorDev[i]; //zjh
718 synapse->SetDEDw( DEDw / nPosEvents ); //zjh
719 }
720}
721
722////////////////////////////////////////////////////////////////////////////////
723
725{
726 Double_t eventWeight = ev->GetWeight();
727
728 ForceNetworkInputs( ev );
729 ForceNetworkCalculations();
730
731 if (DoRegression()) {
732 UInt_t ntgt = DataInfo().GetNTargets();
733 for (UInt_t itgt = 0; itgt < ntgt; itgt++) {
734 Double_t desired = ev->GetTarget(itgt);
735 Double_t error = ( GetOutputNeuron( itgt )->GetActivationValue() - desired )*eventWeight;
736 GetOutputNeuron( itgt )->SetError(error);
737 }
738 } else if (DoMulticlass()) {
739 UInt_t nClasses = DataInfo().GetNClasses();
740 UInt_t cls = ev->GetClass();
741 for (UInt_t icls = 0; icls < nClasses; icls++) {
742 Double_t desired = ( cls==icls ? 1.0 : 0.0 );
743 Double_t error = ( GetOutputNeuron( icls )->GetActivationValue() - desired )*eventWeight;
744 GetOutputNeuron( icls )->SetError(error);
745 }
746 } else {
747 Double_t desired = GetDesiredOutput( ev );
748 Double_t error=-1; //zjh
749 if (fEstimator==kMSE) error = ( GetOutputNeuron()->GetActivationValue() - desired )*eventWeight; //zjh
750 else if (fEstimator==kCE) error = -eventWeight/(GetOutputNeuron()->GetActivationValue() -1 + desired); //zjh
751 GetOutputNeuron()->SetError(error);
752 }
753
754 CalculateNeuronDeltas();
755 for (Int_t j=0;j<fSynapses->GetEntriesFast();j++) {
756 TSynapse *synapse = (TSynapse*)fSynapses->At(j);
757 synapse->InitDelta();
758 synapse->CalculateDelta();
759 }
760}
761
762////////////////////////////////////////////////////////////////////////////////
763
765{
766 Int_t IDX = 0;
767 Int_t nSynapses = fSynapses->GetEntriesFast();
768
769 for (Int_t i=0;i<nSynapses;i++) {
770 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
771 Dir[IDX++][0] = -synapse->GetDEDw();
772 }
773}
774
775////////////////////////////////////////////////////////////////////////////////
776
778{
780 if ((Double_t) gd[0][0] == 0.) return kTRUE;
781 TMatrixD aHg(Hessian, TMatrixD::kMult, Gamma);
782 TMatrixD tmp(Gamma, TMatrixD::kTransposeMult, Hessian);
784 Double_t a = 1 / (Double_t) gd[0][0];
785 Double_t f = 1 + ((Double_t)gHg[0][0]*a);
787 res *= f;
790 res *= a;
791 Hessian += res;
792
793 return kFALSE;
794}
795
796////////////////////////////////////////////////////////////////////////////////
797
799{
800 Int_t IDX = 0;
801 Int_t nSynapses = fSynapses->GetEntriesFast();
803
804 for (Int_t i=0;i<nSynapses;i++) {
805 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
806 DEDw[IDX++][0] = synapse->GetDEDw();
807 }
808
809 dir = Hessian * DEDw;
810 for (Int_t i=0;i<IDX;i++) dir[i][0] = -dir[i][0];
811}
812
813////////////////////////////////////////////////////////////////////////////////
814
816{
817 Int_t IDX = 0;
818 Int_t nSynapses = fSynapses->GetEntriesFast();
819 Double_t Result = 0.0;
820
821 for (Int_t i=0;i<nSynapses;i++) {
822 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
823 Result += Dir[IDX++][0] * synapse->GetDEDw();
824 }
825 return Result;
826}
827
828////////////////////////////////////////////////////////////////////////////////
829
831{
832 Int_t IDX = 0;
833 Int_t nSynapses = fSynapses->GetEntriesFast();
835
836 std::vector<Double_t> Origin(nWeights);
837 for (Int_t i=0;i<nSynapses;i++) {
838 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
839 Origin[i] = synapse->GetWeight();
840 }
841
842 Double_t err1 = GetError();
844 Double_t alpha1 = 0.;
845 Double_t alpha2 = fLastAlpha;
846
847
848 if (alpha2 < 0.01) alpha2 = 0.01;
849 else if (alpha2 > 2.0) alpha2 = 2.0;
852
853 SetDirWeights( Origin, Dir, alpha2 );
854 Double_t err2 = GetError();
855 //Double_t err2 = err1;
858
859
860 if (err1 > err2) {
861 for (Int_t i=0;i<100;i++) {
862 alpha3 *= fTau;
863 SetDirWeights(Origin, Dir, alpha3);
864 err3 = GetError();
865 if (err3 > err2) {
866 bingo = kTRUE;
867 break;
868 }
869 alpha1 = alpha2;
870 err1 = err2;
871 alpha2 = alpha3;
872 err2 = err3;
873 }
874 if (!bingo) {
875 SetDirWeights(Origin, Dir, 0.);
876 return kTRUE;
877 }
878 }
879 else {
880 for (Int_t i=0;i<100;i++) {
881 alpha2 /= fTau;
882 if (i==50) {
883 Log() << kWARNING << "linesearch, starting to investigate direction opposite of steepestDIR" << Endl;
885 }
886 SetDirWeights(Origin, Dir, alpha2);
887 err2 = GetError();
888 if (err1 > err2) {
889 bingo = kTRUE;
890 break;
891 }
892 alpha3 = alpha2;
893 err3 = err2;
894 }
895 if (!bingo) {
896 SetDirWeights(Origin, Dir, 0.);
897 Log() << kWARNING << "linesearch, failed even in opposite direction of steepestDIR" << Endl;
898 fLastAlpha = 0.05;
899 return kTRUE;
900 }
901 }
902
903 if (alpha1>0 && alpha2>0 && alpha3 > 0) {
904 fLastAlpha = 0.5 * (alpha1 + alpha3 -
905 (err3 - err1) / ((err3 - err2) / ( alpha3 - alpha2 )
906 - ( err2 - err1 ) / (alpha2 - alpha1 )));
907 }
908 else {
909 fLastAlpha = alpha2;
910 }
911
912 fLastAlpha = fLastAlpha < 10000 ? fLastAlpha : 10000;
913
914 SetDirWeights(Origin, Dir, fLastAlpha);
915
916 // leaving these lines uncommented is a heavy price to pay for only a warning message
917 // (which shouldn't appear anyway)
918 // --> about 15% of time is spent in the final GetError().
919 //
920 Double_t finalError = GetError();
921 if (finalError > err1) {
922 Log() << kWARNING << "Line search increased error! Something is wrong."
923 << "fLastAlpha=" << fLastAlpha << "al123=" << alpha1 << " "
924 << alpha2 << " " << alpha3 << " err1="<< err1 << " errfinal=" << finalError << Endl;
925 }
926
927 for (Int_t i=0;i<nSynapses;i++) {
928 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
929 buffer[IDX] = synapse->GetWeight() - Origin[IDX];
930 IDX++;
931 }
932
933 if (dError) (*dError)=(errOrigin-finalError)/finalError; //zjh
934
935 return kFALSE;
936}
937
938////////////////////////////////////////////////////////////////////////////////
939
940void TMVA::MethodMLP::SetDirWeights( std::vector<Double_t> &Origin, TMatrixD &Dir, Double_t alpha )
941{
942 Int_t IDX = 0;
943 Int_t nSynapses = fSynapses->GetEntriesFast();
944
945 for (Int_t i=0;i<nSynapses;i++) {
946 TSynapse *synapse = (TSynapse*)fSynapses->At(i);
947 synapse->SetWeight( Origin[IDX] + Dir[IDX][0] * alpha );
948 IDX++;
949 }
950 if (fUseRegulator) UpdatePriors();//zjh
951}
952
953
954////////////////////////////////////////////////////////////////////////////////
955
957{
958 Int_t nEvents = GetNEvents();
959 UInt_t ntgts = GetNTargets();
960 Double_t Result = 0.;
961
962 for (Int_t i=0;i<nEvents;i++) {
963 const Event* ev = GetEvent(i);
964
965 if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
966 && (Data()->GetCurrentType() == Types::kTraining)){
967 continue;
968 }
969 SimulateEvent( ev );
970
971 Double_t error = 0.;
972 if (DoRegression()) {
973 for (UInt_t itgt = 0; itgt < ntgts; itgt++) {
974 error += GetMSEErr( ev, itgt );//zjh
975 }
976 } else if ( DoMulticlass() ){
977 for( UInt_t icls = 0, iclsEnd = DataInfo().GetNClasses(); icls < iclsEnd; icls++ ){
978 error += GetMSEErr( ev, icls );
979 }
980 } else {
981 if (fEstimator==kMSE) error = GetMSEErr( ev ); //zjh
982 else if (fEstimator==kCE) error= GetCEErr( ev ); //zjh
983 }
984 Result += error * ev->GetWeight();
985 }
986 if (fUseRegulator) Result+=fPrior; //zjh
987 if (Result<0) Log()<<kWARNING<<"\nNegative Error!!! :"<<Result-fPrior<<"+"<<fPrior<<Endl;
988 return Result;
989}
990
991////////////////////////////////////////////////////////////////////////////////
992
994{
995 Double_t error = 0;
996 Double_t output = GetOutputNeuron( index )->GetActivationValue();
997 Double_t target = 0;
998 if (DoRegression()) target = ev->GetTarget( index );
999 else if (DoMulticlass()) target = (ev->GetClass() == index ? 1.0 : 0.0 );
1000 else target = GetDesiredOutput( ev );
1001
1002 error = 0.5*(output-target)*(output-target); //zjh
1003
1004 return error;
1005
1006}
1007
1008////////////////////////////////////////////////////////////////////////////////
1009
1011{
1012 Double_t error = 0;
1013 Double_t output = GetOutputNeuron( index )->GetActivationValue();
1014 Double_t target = 0;
1015 if (DoRegression()) target = ev->GetTarget( index );
1016 else if (DoMulticlass()) target = (ev->GetClass() == index ? 1.0 : 0.0 );
1017 else target = GetDesiredOutput( ev );
1018
1019 error = -(target*TMath::Log(output)+(1-target)*TMath::Log(1-output));
1020
1021 return error;
1022}
1023
1024////////////////////////////////////////////////////////////////////////////////
1025/// minimize estimator / train network with back propagation algorithm
1026
1028{
1029 // Timer timer( nEpochs, GetName() );
1030 Timer timer( (fSteps>0?100:nEpochs), GetName() );
1031 Int_t lateEpoch = (Int_t)(nEpochs*0.95) - 1;
1032
1033 // create histograms for overtraining monitoring
1034 Int_t nbinTest = Int_t(nEpochs/fTestRate);
1035 if(!IsSilentFile())
1036 {
1037 fEstimatorHistTrain = new TH1F( "estimatorHistTrain", "training estimator",
1038 nbinTest, Int_t(fTestRate/2), nbinTest*fTestRate+Int_t(fTestRate/2) );
1039 fEstimatorHistTest = new TH1F( "estimatorHistTest", "test estimator",
1040 nbinTest, Int_t(fTestRate/2), nbinTest*fTestRate+Int_t(fTestRate/2) );
1041 }
1042 if(fSamplingTraining || fSamplingTesting)
1043 Data()->InitSampling(1.0,1.0,fRandomSeed); // initialize sampling to initialize the random generator with the given seed
1044
1045 if (fSteps > 0) Log() << kINFO << "Inaccurate progress timing for MLP... " << Endl;
1046 timer.DrawProgressBar(0);
1047
1048 // estimators
1049 Double_t trainE = -1;
1050 Double_t testE = -1;
1051
1052 // start training cycles (epochs)
1053 for (Int_t i = 0; i < nEpochs; i++) {
1054
1055 if (Float_t(i)/nEpochs < fSamplingEpoch) {
1056 if ((i+1)%fTestRate == 0 || (i == 0)) {
1057 if (fSamplingTraining) {
1058 Data()->SetCurrentType( Types::kTraining );
1059 Data()->InitSampling(fSamplingFraction,fSamplingWeight);
1060 Data()->CreateSampling();
1061 }
1062 if (fSamplingTesting) {
1063 Data()->SetCurrentType( Types::kTesting );
1064 Data()->InitSampling(fSamplingFraction,fSamplingWeight);
1065 Data()->CreateSampling();
1066 }
1067 }
1068 }
1069 else {
1070 Data()->SetCurrentType( Types::kTraining );
1071 Data()->InitSampling(1.0,1.0);
1072 Data()->SetCurrentType( Types::kTesting );
1073 Data()->InitSampling(1.0,1.0);
1074 }
1075 Data()->SetCurrentType( Types::kTraining );
1076
1077 TrainOneEpoch();
1078 DecaySynapseWeights(i >= lateEpoch);
1079
1080 // monitor convergence of training and control sample
1081 if ((i+1)%fTestRate == 0) {
1082 trainE = CalculateEstimator( Types::kTraining, i ); // estimator for training sample
1083 testE = CalculateEstimator( Types::kTesting, i ); // estimator for test sample
1084 if(!IsSilentFile())
1085 {
1086 fEstimatorHistTrain->Fill( i+1, trainE );
1087 fEstimatorHistTest ->Fill( i+1, testE );
1088 }
1090 if ((testE < GetCurrentValue()) || (GetCurrentValue()<1e-100)) {
1091 success = kTRUE;
1092 }
1093 Data()->EventResult( success );
1094
1095 SetCurrentValue( testE );
1096 if (HasConverged()) {
1097 if (Float_t(i)/nEpochs < fSamplingEpoch) {
1098 Int_t newEpoch = Int_t(fSamplingEpoch*nEpochs);
1099 i = newEpoch;
1100 ResetConvergenceCounter();
1101 }
1102 else {
1103 if (lateEpoch > i) lateEpoch = i;
1104 else break;
1105 }
1106 }
1107 }
1108
1109 // draw progress bar (add convergence value)
1110 TString convText = TString::Format( "<D^2> (train/test): %.4g/%.4g", trainE, testE );
1111 if (fSteps > 0) {
1112 Float_t progress = 0;
1113 if (Float_t(i)/nEpochs < fSamplingEpoch)
1114 progress = Progress()*fSamplingEpoch*fSamplingFraction*100;
1115 else
1116 progress = 100*(fSamplingEpoch*fSamplingFraction+(1.0-fSamplingFraction*fSamplingEpoch)*Progress());
1117
1118 timer.DrawProgressBar( Int_t(progress), convText );
1119 }
1120 else {
1121 timer.DrawProgressBar( i, convText );
1122 }
1123 }
1124}
1125
1126////////////////////////////////////////////////////////////////////////////////
1127/// train network over a single epoch/cycle of events
1128
1130{
1131 Int_t nEvents = Data()->GetNEvents();
1132
1133 // randomize the order events will be presented, important for sequential mode
1134 Int_t* index = new Int_t[nEvents];
1135 for (Int_t i = 0; i < nEvents; i++) index[i] = i;
1136 Shuffle(index, nEvents);
1137
1138 // loop over all training events
1139 for (Int_t i = 0; i < nEvents; i++) {
1140
1141 const Event * ev = GetEvent(index[i]);
1142 if ((ev->GetWeight() < 0) && IgnoreEventsWithNegWeightsInTraining()
1143 && (Data()->GetCurrentType() == Types::kTraining)){
1144 continue;
1145 }
1146
1147 TrainOneEvent(index[i]);
1148
1149 // do adjustments if in batch mode
1150 if (fBPMode == kBatch && (i+1)%fBatchSize == 0) {
1151 AdjustSynapseWeights();
1152 if (fgPRINT_BATCH) {
1153 PrintNetwork();
1154 WaitForKeyboard();
1155 }
1156 }
1157
1158 // debug in sequential mode
1159 if (fgPRINT_SEQ) {
1160 PrintNetwork();
1161 WaitForKeyboard();
1162 }
1163 }
1164
1165 delete[] index;
1166}
1167
1168////////////////////////////////////////////////////////////////////////////////
1169/// Input:
1170/// - index: the array to shuffle
1171/// - n: the size of the array
1172/// Output:
1173/// - index: the shuffled indexes
1174///
1175/// This method is used for sequential training
1176
1178{
1179 Int_t j, k;
1180 Int_t a = n - 1;
1181 for (Int_t i = 0; i < n; i++) {
1182 j = (Int_t) (frgen->Rndm() * a);
1183 if (j<n){ // address the 'worries' of coverity
1184 k = index[j];
1185 index[j] = index[i];
1186 index[i] = k;
1187 }
1188 }
1189}
1190
1191////////////////////////////////////////////////////////////////////////////////
1192/// decay synapse weights
1193/// in last 10 epochs, lower learning rate even more to find a good minimum
1194
1196{
1198 Int_t numSynapses = fSynapses->GetEntriesFast();
1199 for (Int_t i = 0; i < numSynapses; i++) {
1200 synapse = (TSynapse*)fSynapses->At(i);
1201 if (lateEpoch) synapse->DecayLearningRate(TMath::Sqrt(fDecayRate)); // In order to lower the learning rate even more, we need to apply sqrt instead of square.
1202 else synapse->DecayLearningRate(fDecayRate);
1203 }
1204}
1205
1206////////////////////////////////////////////////////////////////////////////////
1207/// fast per-event training
1208
1210{
1211 GetEvent(ievt);
1212
1213 // as soon as we know how to get event weights, get that here
1214
1215 // note: the normalization of event weights will affect the choice
1216 // of learning rate, one will have to experiment to get the right value.
1217 // in general, if the "average" event weight is 1, the learning rate
1218 // should be good if set around 0.02 (a good value if all event weights are 1)
1219 Double_t eventWeight = 1.0;
1220
1221 // get the desired output of this event
1223 if (type == 0) desired = fOutput->GetMin(); // background //zjh
1224 else desired = fOutput->GetMax(); // signal //zjh
1225
1226 // force the value for each input neuron
1227 Double_t x;
1228 TNeuron* neuron;
1229
1230 for (UInt_t j = 0; j < GetNvar(); j++) {
1231 x = branchVar[j];
1232 if (IsNormalised()) x = gTools().NormVariable( x, GetXmin( j ), GetXmax( j ) );
1233 neuron = GetInputNeuron(j);
1234 neuron->ForceValue(x);
1235 }
1236
1237 ForceNetworkCalculations();
1238 UpdateNetwork(desired, eventWeight);
1239}
1240
1241////////////////////////////////////////////////////////////////////////////////
1242/// train network over a single event
1243/// this uses the new event model
1244
1246{
1247 // note: the normalization of event weights will affect the choice
1248 // of learning rate, one will have to experiment to get the right value.
1249 // in general, if the "average" event weight is 1, the learning rate
1250 // should be good if set around 0.02 (a good value if all event weights are 1)
1251
1252 const Event * ev = GetEvent(ievt);
1253 Double_t eventWeight = ev->GetWeight();
1254 ForceNetworkInputs( ev );
1255 ForceNetworkCalculations();
1256 if (DoRegression()) UpdateNetwork( ev->GetTargets(), eventWeight );
1257 if (DoMulticlass()) UpdateNetwork( *DataInfo().GetTargetsForMulticlass( ev ), eventWeight );
1258 else UpdateNetwork( GetDesiredOutput( ev ), eventWeight );
1259}
1260
1261////////////////////////////////////////////////////////////////////////////////
1262/// get the desired output of this event
1263
1265{
1266 return DataInfo().IsSignal(ev)?fOutput->GetMax():fOutput->GetMin(); //zjh
1267}
1268
1269////////////////////////////////////////////////////////////////////////////////
1270/// update the network based on how closely
1271/// the output matched the desired output
1272
1274{
1275 Double_t error = GetOutputNeuron()->GetActivationValue() - desired;
1276 if (fEstimator==kMSE) error = GetOutputNeuron()->GetActivationValue() - desired ; //zjh
1277 else if (fEstimator==kCE) error = -1./(GetOutputNeuron()->GetActivationValue() -1 + desired); //zjh
1278 else Log() << kFATAL << "Estimator type unspecified!!" << Endl; //zjh
1279 error *= eventWeight;
1280 GetOutputNeuron()->SetError(error);
1281 CalculateNeuronDeltas();
1282 UpdateSynapses();
1283}
1284
1285////////////////////////////////////////////////////////////////////////////////
1286/// update the network based on how closely
1287/// the output matched the desired output
1288
1289void TMVA::MethodMLP::UpdateNetwork(const std::vector<Float_t>& desired, Double_t eventWeight)
1290{
1291 // Norm for softmax
1292 Double_t norm = 0.;
1293 for (UInt_t i = 0, iEnd = desired.size(); i < iEnd; ++i) {
1294 Double_t act = GetOutputNeuron(i)->GetActivationValue();
1295 norm += TMath::Exp(act);
1296 }
1297
1298 // Get output of network, and apply softmax
1299 for (UInt_t i = 0, iEnd = desired.size(); i < iEnd; ++i) {
1300 Double_t act = GetOutputNeuron(i)->GetActivationValue();
1301 Double_t output = TMath::Exp(act) / norm;
1302 Double_t error = output - desired.at(i);
1303 error *= eventWeight;
1304 GetOutputNeuron(i)->SetError(error);
1305 }
1306
1307 // Do backpropagation
1308 CalculateNeuronDeltas();
1309 UpdateSynapses();
1310}
1311
1312////////////////////////////////////////////////////////////////////////////////
1313/// have each neuron calculate its delta by back propagation
1314
1316{
1317 TNeuron* neuron;
1319 Int_t numLayers = fNetwork->GetEntriesFast();
1321
1322 // step backwards through the network (back propagation)
1323 // deltas calculated starting at output layer
1324 for (Int_t i = numLayers-1; i >= 0; i--) {
1325 curLayer = (TObjArray*)fNetwork->At(i);
1326 numNeurons = curLayer->GetEntriesFast();
1327
1328 for (Int_t j = 0; j < numNeurons; j++) {
1329 neuron = (TNeuron*) curLayer->At(j);
1330 neuron->CalculateDelta();
1331 }
1332 }
1333}
1334
1335////////////////////////////////////////////////////////////////////////////////
1336/// create genetics class similar to GeneticCut
1337/// give it vector of parameter ranges (parameters = weights)
1338/// link fitness function of this class to ComputeEstimator
1339/// instantiate GA (see MethodCuts)
1340/// run it
1341/// then this should exist for GA, Minuit and random sampling
1342
1344{
1345 PrintMessage("Minimizing Estimator with GA");
1346
1347 // define GA parameters
1348 fGA_preCalc = 1;
1349 fGA_SC_steps = 10;
1350 fGA_SC_rate = 5;
1351 fGA_SC_factor = 0.95;
1352 fGA_nsteps = 30;
1353
1354 // ranges
1355 std::vector<Interval*> ranges;
1356
1357 Int_t numWeights = fSynapses->GetEntriesFast();
1358 for (Int_t ivar=0; ivar< numWeights; ivar++) {
1359 ranges.push_back( new Interval( 0, GetXmax(ivar) - GetXmin(ivar) ));
1360 }
1361
1362 FitterBase *gf = new GeneticFitter( *this, Log().GetPrintedSource(), ranges, GetOptions() );
1363 gf->Run();
1364
1365 Double_t estimator = CalculateEstimator();
1366 Log() << kINFO << "GA: estimator after optimization: " << estimator << Endl;
1367}
1368
1369////////////////////////////////////////////////////////////////////////////////
1370/// interface to the estimate
1371
1372Double_t TMVA::MethodMLP::EstimatorFunction( std::vector<Double_t>& parameters)
1373{
1374 return ComputeEstimator( parameters );
1375}
1376
1377////////////////////////////////////////////////////////////////////////////////
1378/// this function is called by GeneticANN for GA optimization
1379
1380Double_t TMVA::MethodMLP::ComputeEstimator( std::vector<Double_t>& parameters)
1381{
1383 Int_t numSynapses = fSynapses->GetEntriesFast();
1384
1385 for (Int_t i = 0; i < numSynapses; i++) {
1386 synapse = (TSynapse*)fSynapses->At(i);
1387 synapse->SetWeight(parameters.at(i));
1388 }
1389 if (fUseRegulator) UpdatePriors(); //zjh
1390
1391 Double_t estimator = CalculateEstimator();
1392
1393 return estimator;
1394}
1395
1396////////////////////////////////////////////////////////////////////////////////
1397/// update synapse error fields and adjust the weights (if in sequential mode)
1398
1400{
1401 TNeuron* neuron;
1404 Int_t numLayers = fNetwork->GetEntriesFast();
1405
1406 for (Int_t i = 0; i < numLayers; i++) {
1407 curLayer = (TObjArray*)fNetwork->At(i);
1408 numNeurons = curLayer->GetEntriesFast();
1409
1410 for (Int_t j = 0; j < numNeurons; j++) {
1411 neuron = (TNeuron*) curLayer->At(j);
1412 if (fBPMode == kBatch) neuron->UpdateSynapsesBatch();
1413 else neuron->UpdateSynapsesSequential();
1414 }
1415 }
1416}
1417
1418////////////////////////////////////////////////////////////////////////////////
1419/// just adjust the synapse weights (should be called in batch mode)
1420
1422{
1423 TNeuron* neuron;
1426 Int_t numLayers = fNetwork->GetEntriesFast();
1427
1428 for (Int_t i = numLayers-1; i >= 0; i--) {
1429 curLayer = (TObjArray*)fNetwork->At(i);
1430 numNeurons = curLayer->GetEntriesFast();
1431
1432 for (Int_t j = 0; j < numNeurons; j++) {
1433 neuron = (TNeuron*) curLayer->At(j);
1434 neuron->AdjustSynapseWeights();
1435 }
1436 }
1437}
1438
1439////////////////////////////////////////////////////////////////////////////////
1440
1442{
1443 fPrior=0;
1444 fPriorDev.clear();
1445 Int_t nSynapses = fSynapses->GetEntriesFast();
1446 for (Int_t i=0;i<nSynapses;i++) {
1447 TSynapse* synapse = (TSynapse*)fSynapses->At(i);
1448 fPrior+=0.5*fRegulators[fRegulatorIdx[i]]*(synapse->GetWeight())*(synapse->GetWeight());
1449 fPriorDev.push_back(fRegulators[fRegulatorIdx[i]]*(synapse->GetWeight()));
1450 }
1451}
1452
1453////////////////////////////////////////////////////////////////////////////////
1454
1456{
1457 TMatrixD InvH(0,0);
1458 GetApproxInvHessian(InvH);
1459 Int_t numSynapses=fSynapses->GetEntriesFast();
1460 Int_t numRegulators=fRegulators.size();
1461 Float_t gamma=0,
1462 variance=1.; // Gaussian noise
1463 std::vector<Int_t> nWDP(numRegulators);
1464 std::vector<Double_t> trace(numRegulators),weightSum(numRegulators);
1465 for (int i=0;i<numSynapses;i++) {
1466 TSynapse* synapses = (TSynapse*)fSynapses->At(i);
1467 Int_t idx=fRegulatorIdx[i];
1468 nWDP[idx]++;
1469 trace[idx]+=InvH[i][i];
1470 gamma+=1-fRegulators[idx]*InvH[i][i];
1471 weightSum[idx]+=(synapses->GetWeight())*(synapses->GetWeight());
1472 }
1473 if (fEstimator==kMSE) {
1474 if (GetNEvents()>gamma) variance=CalculateEstimator( Types::kTraining, 0 )/(1-(gamma/GetNEvents()));
1475 else variance=CalculateEstimator( Types::kTraining, 0 );
1476 }
1477
1478 //Log() << kDEBUG << Endl;
1479 for (int i=0;i<numRegulators;i++)
1480 {
1481 //fRegulators[i]=variance*(nWDP[i]-fRegulators[i]*trace[i])/weightSum[i];
1482 fRegulators[i]=variance*nWDP[i]/(weightSum[i]+variance*trace[i]);
1483 if (fRegulators[i]<0) fRegulators[i]=0;
1484 Log()<<kDEBUG<<"R"<<i<<":"<<fRegulators[i]<<"\t";
1485 }
1486 float trainE = CalculateEstimator( Types::kTraining, 0 ) ; // estimator for training sample //zjh
1487 float testE = CalculateEstimator( Types::kTesting, 0 ) ; // estimator for test sample //zjh
1488
1489 Log()<<kDEBUG<<"\n"<<"trainE:"<<trainE<<"\ttestE:"<<testE<<"\tvariance:"<<variance<<"\tgamma:"<<gamma<<Endl;
1490
1491}
1492
1493////////////////////////////////////////////////////////////////////////////////
1494
1496{
1497 Int_t numSynapses=fSynapses->GetEntriesFast();
1498 InvHessian.ResizeTo( numSynapses, numSynapses );
1499 InvHessian=0;
1502 Int_t nEvents = GetNEvents();
1503 for (Int_t i=0;i<nEvents;i++) {
1504 GetEvent(i);
1505 double outputValue=GetMvaValue(); // force calculation
1506 GetOutputNeuron()->SetError(1./fOutput->EvalDerivative(GetOutputNeuron()->GetValue()));
1507 CalculateNeuronDeltas();
1508 for (Int_t j = 0; j < numSynapses; j++){
1509 TSynapse* synapses = (TSynapse*)fSynapses->At(j);
1510 synapses->InitDelta();
1511 synapses->CalculateDelta();
1512 sens[j][0]=sensT[0][j]=synapses->GetDelta();
1513 }
1514 if (fEstimator==kMSE ) InvHessian+=sens*sensT;
1515 else if (fEstimator==kCE) InvHessian+=(outputValue*(1-outputValue))*sens*sensT;
1516 }
1517
1518 // TVectorD eValue(numSynapses);
1519 if (regulate) {
1520 for (Int_t i = 0; i < numSynapses; i++){
1521 InvHessian[i][i]+=fRegulators[fRegulatorIdx[i]];
1522 }
1523 }
1524 else {
1525 for (Int_t i = 0; i < numSynapses; i++){
1526 InvHessian[i][i]+=1e-6; //to avoid precision problem that will destroy the pos-def
1527 }
1528 }
1529
1530 InvHessian.Invert();
1531
1532}
1533
1534////////////////////////////////////////////////////////////////////////////////
1535
1537{
1538 Double_t MvaValue = MethodANNBase::GetMvaValue();// contains back propagation
1539
1540 // no hessian (old training file) or no error requested
1541 if (!fCalculateErrors || errLower==0 || errUpper==0)
1542 return MvaValue;
1543
1545 Int_t numSynapses=fSynapses->GetEntriesFast();
1546 if (fInvHessian.GetNcols()!=numSynapses) {
1547 Log() << kWARNING << "inconsistent dimension " << fInvHessian.GetNcols() << " vs " << numSynapses << Endl;
1548 }
1551 GetOutputNeuron()->SetError(1./fOutput->EvalDerivative(GetOutputNeuron()->GetValue()));
1552 //GetOutputNeuron()->SetError(1.);
1553 CalculateNeuronDeltas();
1554 for (Int_t i = 0; i < numSynapses; i++){
1555 TSynapse* synapses = (TSynapse*)fSynapses->At(i);
1556 synapses->InitDelta();
1557 synapses->CalculateDelta();
1558 sensT[0][i]=synapses->GetDelta();
1559 }
1560 sens.Transpose(sensT);
1561 TMatrixD sig=sensT*fInvHessian*sens;
1562 variance=sig[0][0];
1563 median=GetOutputNeuron()->GetValue();
1564
1565 if (variance<0) {
1566 Log()<<kWARNING<<"Negative variance!!! median=" << median << "\tvariance(sigma^2)=" << variance <<Endl;
1567 variance=0;
1568 }
1569 variance=sqrt(variance);
1570
1571 //upper
1572 MvaUpper=fOutput->Eval(median+variance);
1573 if(errUpper)
1575
1576 //lower
1577 MvaLower=fOutput->Eval(median-variance);
1578 if(errLower)
1580
1581 return MvaValue;
1582}
1583
1584
1585#ifdef MethodMLP_UseMinuit__
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// minimize using Minuit
1589
1590void TMVA::MethodMLP::MinuitMinimize()
1591{
1592 fNumberOfWeights = fSynapses->GetEntriesFast();
1593
1595
1596 // minuit-specific settings
1597 Double_t args[10];
1598
1599 // output level
1600 args[0] = 2; // put to 0 for results only, or to -1 for no garbage
1601 tfitter->ExecuteCommand( "SET PRINTOUT", args, 1 );
1602 tfitter->ExecuteCommand( "SET NOWARNINGS", args, 0 );
1603
1604 double w[54];
1605
1606 // init parameters
1607 for (Int_t ipar=0; ipar < fNumberOfWeights; ipar++) {
1608 TString parName = TString::Format("w%i", ipar);
1609 tfitter->SetParameter( ipar,
1610 parName, w[ipar], 0.1, 0, 0 );
1611 }
1612
1613 // define the CFN function
1614 tfitter->SetFCN( &IFCN );
1615
1616 // define fit strategy
1617 args[0] = 2;
1618 tfitter->ExecuteCommand( "SET STRATEGY", args, 1 );
1619
1620 // now do the fit !
1621 args[0] = 1e-04;
1622 tfitter->ExecuteCommand( "MIGRAD", args, 1 );
1623
1626 if (doBetter) {
1627 args[0] = 1e-04;
1628 tfitter->ExecuteCommand( "IMPROVE", args, 1 );
1629
1630 if (doEvenBetter) {
1631 args[0] = 500;
1632 tfitter->ExecuteCommand( "MINOS", args, 1 );
1633 }
1634 }
1635}
1636
1637////////////////////////////////////////////////////////////////////////////////
1638/// Evaluate the minimisation function
1639///
1640/// Input parameters:
1641/// - npars: number of currently variable parameters
1642/// CAUTION: this is not (necessarily) the dimension of the fitPars vector !
1643/// - fitPars: array of (constant and variable) parameters
1644/// - iflag: indicates what is to be calculated (see example below)
1645/// - grad: array of gradients
1646///
1647/// Output parameters:
1648/// - f: the calculated function value.
1649/// - grad: the (optional) vector of first derivatives).
1650
1651void TMVA::MethodMLP::IFCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t* fitPars, Int_t iflag )
1652{
1653 ((MethodMLP*)GetThisPtr())->FCN( npars, grad, f, fitPars, iflag );
1654}
1655
1656TTHREAD_TLS(Int_t) nc = 0;
1657TTHREAD_TLS(double) minf = 1000000;
1658
1659void TMVA::MethodMLP::FCN( Int_t& npars, Double_t* grad, Double_t &f, Double_t* fitPars, Int_t iflag )
1660{
1661 // first update the weights
1662 for (Int_t ipar=0; ipar<fNumberOfWeights; ipar++) {
1663 TSynapse* synapse = (TSynapse*)fSynapses->At(ipar);
1664 synapse->SetWeight(fitPars[ipar]);
1665 }
1666
1667 // now compute the estimator
1668 f = CalculateEstimator();
1669
1670 nc++;
1671 if (f < minf) minf = f;
1672 for (Int_t ipar=0; ipar<fNumberOfWeights; ipar++) Log() << kDEBUG << fitPars[ipar] << " ";
1673 Log() << kDEBUG << Endl;
1674 Log() << kDEBUG << "***** New estimator: " << f << " min: " << minf << " --> ncalls: " << nc << Endl;
1675}
1676
1677////////////////////////////////////////////////////////////////////////////////
1678/// global "this" pointer to be used in minuit
1679
1680TMVA::MethodMLP* TMVA::MethodMLP::GetThisPtr()
1681{
1682 return fgThis;
1683}
1684
1685#endif
1686
1687
1688////////////////////////////////////////////////////////////////////////////////
1689/// write specific classifier response
1690
1691void TMVA::MethodMLP::MakeClassSpecific( std::ostream& fout, const TString& className ) const
1692{
1694}
1695
1696////////////////////////////////////////////////////////////////////////////////
1697/// get help message text
1698///
1699/// typical length of text line:
1700/// "|--------------------------------------------------------------|"
1701
1703{
1704 TString col = gConfig().WriteOptionsReference() ? TString() : gTools().Color("bold");
1706
1707 Log() << Endl;
1708 Log() << col << "--- Short description:" << colres << Endl;
1709 Log() << Endl;
1710 Log() << "The MLP artificial neural network (ANN) is a traditional feed-" << Endl;
1711 Log() << "forward multilayer perceptron implementation. The MLP has a user-" << Endl;
1712 Log() << "defined hidden layer architecture, while the number of input (output)" << Endl;
1713 Log() << "nodes is determined by the input variables (output classes, i.e., " << Endl;
1714 Log() << "signal and one background). " << Endl;
1715 Log() << Endl;
1716 Log() << col << "--- Performance optimisation:" << colres << Endl;
1717 Log() << Endl;
1718 Log() << "Neural networks are stable and performing for a large variety of " << Endl;
1719 Log() << "linear and non-linear classification problems. However, in contrast" << Endl;
1720 Log() << "to (e.g.) boosted decision trees, the user is advised to reduce the " << Endl;
1721 Log() << "number of input variables that have only little discrimination power. " << Endl;
1722 Log() << "" << Endl;
1723 Log() << "In the tests we have carried out so far, the MLP and ROOT networks" << Endl;
1724 Log() << "(TMlpANN, interfaced via TMVA) performed equally well, with however" << Endl;
1725 Log() << "a clear speed advantage for the MLP. The Clermont-Ferrand neural " << Endl;
1726 Log() << "net (CFMlpANN) exhibited worse classification performance in these" << Endl;
1727 Log() << "tests, which is partly due to the slow convergence of its training" << Endl;
1728 Log() << "(at least 10k training cycles are required to achieve approximately" << Endl;
1729 Log() << "competitive results)." << Endl;
1730 Log() << Endl;
1731 Log() << col << "Overtraining: " << colres
1732 << "only the TMlpANN performs an explicit separation of the" << Endl;
1733 Log() << "full training sample into independent training and validation samples." << Endl;
1734 Log() << "We have found that in most high-energy physics applications the " << Endl;
1735 Log() << "available degrees of freedom (training events) are sufficient to " << Endl;
1736 Log() << "constrain the weights of the relatively simple architectures required" << Endl;
1737 Log() << "to achieve good performance. Hence no overtraining should occur, and " << Endl;
1738 Log() << "the use of validation samples would only reduce the available training" << Endl;
1739 Log() << "information. However, if the performance on the training sample is " << Endl;
1740 Log() << "found to be significantly better than the one found with the inde-" << Endl;
1741 Log() << "pendent test sample, caution is needed. The results for these samples " << Endl;
1742 Log() << "are printed to standard output at the end of each training job." << Endl;
1743 Log() << Endl;
1744 Log() << col << "--- Performance tuning via configuration options:" << colres << Endl;
1745 Log() << Endl;
1746 Log() << "The hidden layer architecture for all ANNs is defined by the option" << Endl;
1747 Log() << "\"HiddenLayers=N+1,N,...\", where here the first hidden layer has N+1" << Endl;
1748 Log() << "neurons and the second N neurons (and so on), and where N is the number " << Endl;
1749 Log() << "of input variables. Excessive numbers of hidden layers should be avoided," << Endl;
1750 Log() << "in favour of more neurons in the first hidden layer." << Endl;
1751 Log() << "" << Endl;
1752 Log() << "The number of cycles should be above 500. As said, if the number of" << Endl;
1753 Log() << "adjustable weights is small compared to the training sample size," << Endl;
1754 Log() << "using a large number of training samples should not lead to overtraining." << Endl;
1755}
1756
#define REGISTER_METHOD(CLASS)
for example
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:148
TMatrixT< Double_t > TMatrixD
Definition TMatrixDfwd.h:23
const_iterator begin() const
const_iterator end() const
<div class="legacybox"><h2>Legacy Code</h2> TFitter is a legacy interface: there will be no bug fixes...
Definition TFitter.h:19
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
Bool_t WriteOptionsReference() const
Definition Config.h:65
Class that contains all the data information.
Definition DataSetInfo.h:62
Base class for TMVA fitters.
Definition FitterBase.h:51
Fitter using a Genetic Algorithm.
The TMVA::Interval Class.
Definition Interval.h:61
Base class for all TMVA methods using artificial neural networks.
void ProcessOptions() override
do nothing specific at this moment
void MakeClassSpecific(std::ostream &, const TString &) const override
write specific classifier response
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
get the mva value generated by the NN
Multilayer Perceptron class built off of MethodANNBase.
Definition MethodMLP.h:69
void GetHelpMessage() const override
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)
zjh
void MakeClassSpecific(std::ostream &, const TString &) const override
write specific classifier response
void DeclareOptions() override
define the options (their key words) that can be set in the option string
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
Bool_t GetHessian(TMatrixD &Hessian, TMatrixD &Gamma, TMatrixD &Delta)
Double_t ComputeEstimator(std::vector< Double_t > &parameters)
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 EstimatorFunction(std::vector< Double_t > &parameters) override
interface to the estimate
Double_t DerivDir(TMatrixD &Dir)
Double_t GetCEErr(const Event *ev, UInt_t index=0)
zjh
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)
void UpdatePriors()
zjh
void GetApproxInvHessian(TMatrixD &InvHessian, bool regulate=true)
rank-1 approximation, neglect 2nd derivatives. //zjh
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 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)...
Double_t GetError()
void Init() override
default initializations
Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets) override
MLP can handle classification with 2 classes and regression with one regression-target.
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
Definition MethodMLP.cxx:89
void UpdateRegulators()
zjh
Bool_t LineSearch(TMatrixD &Dir, std::vector< Double_t > &Buffer, Double_t *dError=nullptr)
zjh
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
get the mva value generated by the NN
void Train() override
Double_t CalculateEstimator(Types::ETreeType treeType=Types::kTraining, Int_t iEpoch=-1)
calculate the estimator that training is attempting to minimize
void ProcessOptions() override
process user options
Neuron class used by TMVA artificial neural network methods.
Definition TNeuron.h:49
void AdjustSynapseWeights()
adjust the pre-synapses' weights for each neuron (input neuron has no pre-synapse) this method should...
Definition TNeuron.cxx:262
void ForceValue(Double_t value)
force the value, typically for input and bias neurons
Definition TNeuron.cxx:83
void UpdateSynapsesSequential()
update the pre-synapses for each neuron (input neuron has no pre-synapse) this method should only be ...
Definition TNeuron.cxx:241
void UpdateSynapsesBatch()
update and adjust the pre-synapses for each neuron (input neuron has no pre-synapse) this method shou...
Definition TNeuron.cxx:223
void CalculateDelta()
calculate error field
Definition TNeuron.cxx:114
Synapse class used by TMVA artificial neural network methods.
Definition TSynapse.h:42
Timing information for training and evaluation of MVA methods.
Definition Timer.h:58
Double_t NormVariable(Double_t x, Double_t xmin, Double_t xmax)
normalise to output range: [-1, 1]
Definition Tools.cxx:111
const TString & Color(const TString &)
human readable color strings
Definition Tools.cxx:803
Singleton class for Global types used by TMVA.
Definition Types.h:71
@ kMulticlass
Definition Types.h:129
@ kClassification
Definition Types.h:127
@ kRegression
Definition Types.h:128
@ kTraining
Definition Types.h:143
@ kDEBUG
Definition Types.h:56
virtual TMatrixTBase< Element > & UnitMatrix()
Make a unit matrix (matrix need not be a square one).
TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1) override
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=nullptr)
Invert the matrix and calculate its determinant.
An array of TObjects.
Definition TObjArray.h:31
Basic string class.
Definition TString.h:138
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2459
This is a simple weighted bidirectional connection between two neurons.
Definition TSynapse.h:20
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Config & gConfig()
Tools & gTools()
MsgLogger & Endl(MsgLogger &ml)
Definition MsgLogger.h:148
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Definition TMath.h:722
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:769
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675