126 DeclareOptionRef( fNcycles = 500,
"NCycles",
"Number of training cycles" );
127 DeclareOptionRef( fLayerSpec =
"N,N-1",
"HiddenLayers",
"Specification of hidden layer architecture" );
128 DeclareOptionRef( fNeuronType =
"sigmoid",
"NeuronType",
"Neuron activation function type" );
129 DeclareOptionRef( fRandomSeed = 1,
"RandomSeed",
"Random seed for initial synapse weights (0 means unique seed for each run; default value '1')");
131 DeclareOptionRef(fEstimatorS=
"MSE",
"EstimatorType",
132 "MSE (Mean Square Estimator) for Gaussian Likelihood or CE(Cross-Entropy) for Bernoulli Likelihood" );
138 std::vector<TString>* names =
aChooser.GetAllActivationNames();
141 AddPreDefVal(names->at(i));
144 DeclareOptionRef(fNeuronInputType=
"sum",
"NeuronInputType",
"Neuron input function type");
146 names =
iChooser.GetAllNeuronInputNames();
148 for (
Int_t i = 0; i <
nTypes; i++) AddPreDefVal(names->at(i));
158 if ( DoRegression() || DoMulticlass()) fEstimatorS =
"MSE";
159 else fEstimatorS =
"CE" ;
160 if (fEstimatorS ==
"MSE" ) fEstimator = kMSE;
161 else if (fEstimatorS ==
"CE") fEstimator = kCE;
162 std::vector<Int_t>*
layout = ParseLayoutString(fLayerSpec);
173 std::vector<Int_t>*
layout =
new std::vector<Int_t>();
191 layout->push_back( DataInfo().GetNTargets() );
192 else if( DoMulticlass() )
193 layout->push_back( DataInfo().GetNClasses() );
210 fInputCalculator =
NULL;
212 fEstimatorHistTrain =
NULL;
213 fEstimatorHistTest =
NULL;
216 fEpochMonHistS.clear();
217 fEpochMonHistB.clear();
218 fEpochMonHistW.clear();
222 fOutputNeurons.clear();
242 if (fNetwork !=
NULL) {
247 DeleteNetworkLayer(
layer);
252 if (frgen !=
NULL)
delete frgen;
253 if (fActivation !=
NULL)
delete fActivation;
254 if (fOutput !=
NULL)
delete fOutput;
255 if (fIdentity !=
NULL)
delete fIdentity;
256 if (fInputCalculator !=
NULL)
delete fInputCalculator;
257 if (fSynapses !=
NULL)
delete fSynapses;
264 fInputCalculator =
NULL;
289 if (fEstimatorS ==
"MSE") fEstimator = kMSE;
290 else if (fEstimatorS ==
"CE") fEstimator = kCE;
291 else Log()<<kWARNING<<
"fEstimator="<<fEstimator<<
"\tfEstimatorS="<<fEstimatorS<<
Endl;
292 if (fEstimator!=kMSE && fEstimator!=kCE) Log()<<kWARNING<<
"Estimator type unspecified \t"<<
Endl;
295 Log() << kHEADER <<
"Building Network. " <<
Endl;
302 fActivation =
aChooser.CreateActivation(fNeuronType);
303 fIdentity =
aChooser.CreateActivation(
"linear");
304 if (fEstimator==kMSE) fOutput =
aChooser.CreateActivation(
"linear");
305 else if (fEstimator==kCE) fOutput =
aChooser.CreateActivation(
"sigmoid");
307 fInputCalculator =
iChooser.CreateNeuronInput(fNeuronInputType);
310 fRegulatorIdx.clear();
315 fInputLayer = (
TObjArray*)fNetwork->At(0);
317 fOutputNeurons.clear();
322 if (weights ==
NULL) InitWeights();
323 else ForceWeights(weights);
347 if (i!=0 && i!=
numLayers-1) fRegulators.push_back(0.);
349 if (i==0) fRegulators.push_back(0.);
355 fRegulatorIdx.push_back(fRegulators.size()-1);
427 synapse->SetPostNeuron(neuron);
438 PrintMessage(
"Initializing weights");
445 synapse->SetWeight(4.0*frgen->Rndm() - 2.0);
454 PrintMessage(
"Forcing weights");
460 synapse->SetWeight(weights->at(i));
478 neuron = GetInputNeuron(
j);
511 if (Verbose() ||
Debug() ||
force) Log() << kINFO << message <<
Endl;
520 Log() << kINFO <<
"***Type anything to continue (q to quit): ";
521 std::getline(std::cin, dummy);
522 if (dummy ==
"q" || dummy ==
"Q") {
523 PrintMessage(
"quit" );
534 if (!
Debug())
return;
536 Log() << kINFO <<
Endl;
537 PrintMessage(
"Printing network " );
538 Log() << kINFO <<
"-------------------------------------------------------------------" <<
Endl;
548 Log() << kINFO <<
"Layer #" << i <<
" (" <<
numNeurons <<
" neurons):" <<
Endl;
563 Log() << kINFO <<
"\tNeuron #" <<
j <<
" (LinksIn: " << neuron->
NumPreLinks()
565 PrintNeuron( neuron );
575 <<
"\t\tValue:\t" << neuron->
GetValue()
578 Log() << kINFO <<
"\t\tActivationEquation:\t";
580 Log() << kINFO <<
"\t\tLinksIn:" <<
Endl;
582 Log() << kINFO <<
"\t\tLinksOut:" <<
Endl;
597 for (
UInt_t i = 0; i < GetNvar(); i++) {
601 ForceNetworkCalculations();
624 for (
UInt_t i = 0; i < GetNvar(); i++) {
628 ForceNetworkCalculations();
633 if (fRegressionReturnVal ==
NULL) fRegressionReturnVal =
new std::vector<Float_t>();
634 fRegressionReturnVal->clear();
642 const Event*
evT2 = GetTransformationHandler().InverseTransform(
evT );
644 fRegressionReturnVal->push_back(
evT2->GetTarget(
itgt) );
649 return *fRegressionReturnVal;
663 for (
UInt_t i = 0; i < GetNvar(); i++) {
667 ForceNetworkCalculations();
671 if (fMulticlassReturnVal ==
NULL) fMulticlassReturnVal =
new std::vector<Float_t>();
672 fMulticlassReturnVal->clear();
673 std::vector<Float_t> temp;
677 temp.push_back(GetOutputNeuron(
icls )->GetActivationValue() );
686 (*fMulticlassReturnVal).push_back(1.0/(1.0+
norm));
691 return *fMulticlassReturnVal;
717 std::stringstream s(
"");
721 s << std::scientific <<
synapse->GetWeight() <<
" ";
728 if( fInvHessian.GetNcols()>0 ){
741 fInvHessian.GetMatrix2Array( elements );
750 std::stringstream s(
"");
753 s << std::scientific << (*(elements+
index)) <<
" ";
770 std::vector<Int_t>*
layout =
new std::vector<Int_t>();
794 if (GetTrainingTMVAVersionCode() <
TMVA_VERSION(4,2,1) && fActivation->GetExpression().Contains(
"tanh")){
840 fUseRegulator =
kTRUE;
854 if (
nElements > std::numeric_limits<int>::max()-100){
855 Log() << kFATAL <<
"you tried to read a hessian matrix with " <<
nElements <<
" elements, --> too large, guess s.th. went wrong reading from the weight file" <<
Endl;
873 s >> (*(elements+
index));
880 fInvHessian.SetMatrixArray( elements );
896 std::vector<Double_t>* weights =
new std::vector<Double_t>();
898 while (
istr>> dummy >> weight) weights->push_back(weight);
900 ForceWeights(weights);
912 fRanking =
new Ranking( GetName(),
"Importance" );
921 neuron = GetInputNeuron(
ivar);
952 std::vector<TH1*>*
hv )
const
981 if (
hv)
hv->push_back( hist );
994 PrintMessage(
TString::Format(
"Write special histos to file: %s", BaseDir()->GetPath()).Data(),
kTRUE);
996 if (fEstimatorHistTrain) fEstimatorHistTrain->Write();
997 if (fEstimatorHistTest ) fEstimatorHistTest ->Write();
1000 CreateWeightMonitoringHists(
"weights_hist" );
1007 epochdir = BaseDir()->mkdir(
"EpochMonitoring" );
1012 for (std::vector<TH1*>::const_iterator it = fEpochMonHistS.begin(); it != fEpochMonHistS.end(); ++it) {
1016 for (std::vector<TH1*>::const_iterator it = fEpochMonHistB.begin(); it != fEpochMonHistB.end(); ++it) {
1020 for (std::vector<TH1*>::const_iterator it = fEpochMonHistW.begin(); it != fEpochMonHistW.end(); ++it) {
1035 fout <<
" double ActivationFnc(double x) const;" << std::endl;
1036 fout <<
" double OutputActivationFnc(double x) const;" << std::endl;
1043 fout <<
" // weight matrix from layer " <<
lIdx-1 <<
" to " <<
lIdx << std::endl;
1047 fout <<
"};" << std::endl;
1051 fout <<
"inline void " << className <<
"::Initialize()" << std::endl;
1052 fout <<
"{" << std::endl;
1053 fout <<
" // build network structure" << std::endl;
1056 fout <<
" // weight matrix from layer " << i <<
" to " << i+1 << std::endl;
1064 fout <<
" fWeightMatrix" << i <<
"to" << i+1 <<
"[" << k <<
"][" <<
j <<
"] = " <<
synapse->GetWeight() <<
";" << std::endl;
1069 fout <<
"}" << std::endl;
1073 fout <<
"inline double " << className <<
"::GetMvaValue__( const std::vector<double>& inputValues ) const" << std::endl;
1074 fout <<
"{" << std::endl;
1075 fout <<
" if (inputValues.size() != (unsigned int)" << ((
TObjArray *)fNetwork->At(0))->GetEntries() - 1 <<
") {"
1077 fout <<
" std::cout << \"Input vector needs to be of size \" << "
1078 << ((
TObjArray *)fNetwork->At(0))->GetEntries() - 1 <<
" << std::endl;" << std::endl;
1079 fout <<
" return 0;" << std::endl;
1080 fout <<
" }" << std::endl;
1084 int numNodes =
layer->GetEntries();
1085 fout <<
" std::array<double, " << numNodes <<
"> fWeights" <<
lIdx <<
" {{}};" << std::endl;
1088 fout <<
" fWeights" <<
lIdx <<
".back() = 1.;" << std::endl;
1092 fout <<
" // layer " << i <<
" to " << i + 1 << std::endl;
1094 fout <<
" for (int o=0; o<" << ((
TObjArray *)fNetwork->At(i + 1))->GetEntries() <<
"; o++) {" << std::endl;
1096 fout <<
" for (int o=0; o<" << ((
TObjArray *)fNetwork->At(i + 1))->GetEntries() - 1 <<
"; o++) {"
1100 fout <<
" std::array<double, " << ((
TObjArray *)fNetwork->At(i))->GetEntries()
1101 <<
"> buffer; // no need to initialise" << std::endl;
1102 fout <<
" for (int i = 0; i<" << ((
TObjArray *)fNetwork->At(i))->GetEntries() <<
" - 1; i++) {"
1104 fout <<
" buffer[i] = fWeightMatrix" << i <<
"to" << i + 1 <<
"[o][i] * inputValues[i];" << std::endl;
1105 fout <<
" } // loop over i" << std::endl;
1106 fout <<
" buffer.back() = fWeightMatrix" << i <<
"to" << i + 1 <<
"[o]["
1107 << ((
TObjArray *)fNetwork->At(i))->GetEntries() - 1 <<
"];" << std::endl;
1109 fout <<
" std::array<double, " << ((
TObjArray *)fNetwork->At(i))->GetEntries()
1110 <<
"> buffer; // no need to initialise" << std::endl;
1111 fout <<
" for (int i=0; i<" << ((
TObjArray *)fNetwork->At(i))->GetEntries() <<
"; i++) {" << std::endl;
1112 fout <<
" buffer[i] = fWeightMatrix" << i <<
"to" << i + 1 <<
"[o][i] * fWeights" << i <<
"[i];"
1114 fout <<
" } // loop over i" << std::endl;
1116 fout <<
" for (int i=0; i<" << ((
TObjArray *)fNetwork->At(i))->GetEntries() <<
"; i++) {" << std::endl;
1117 if (fNeuronInputType ==
"sum") {
1118 fout <<
" fWeights" << i + 1 <<
"[o] += buffer[i];" << std::endl;
1119 }
else if (fNeuronInputType ==
"sqsum") {
1120 fout <<
" fWeights" << i + 1 <<
"[o] += buffer[i]*buffer[i];" << std::endl;
1122 fout <<
" fWeights" << i + 1 <<
"[o] += fabs(buffer[i]);" << std::endl;
1124 fout <<
" } // loop over i" << std::endl;
1125 fout <<
" } // loop over o" << std::endl;
1127 fout <<
" for (int o=0; o<" << ((
TObjArray *)fNetwork->At(i + 1))->GetEntries() <<
"; o++) {" << std::endl;
1129 fout <<
" for (int o=0; o<" << ((
TObjArray *)fNetwork->At(i + 1))->GetEntries() - 1 <<
"; o++) {"
1133 fout <<
" fWeights" << i + 1 <<
"[o] = ActivationFnc(fWeights" << i + 1 <<
"[o]);" << std::endl;
1135 fout <<
" fWeights" << i + 1 <<
"[o] = OutputActivationFnc(fWeights" << i + 1 <<
"[o]);"
1137 fout <<
" } // loop over o" << std::endl;
1140 fout <<
" return fWeights" <<
numLayers - 1 <<
"[0];" << std::endl;
1141 fout <<
"}" << std::endl;
1146 fncName = className+
"::OutputActivationFnc";
1150 fout <<
"// Clean up" << std::endl;
1151 fout <<
"inline void " << className <<
"::Clear()" << std::endl;
1152 fout <<
"{" << std::endl;
1153 fout <<
"}" << std::endl;
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
float Float_t
Float 4 bytes (float)
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 index
void Debug(Int_t level, const char *fmt,...)
#define TMVA_VERSION(a, b, c)
Describe directory structure in memory.
2-D histogram with a float per channel (see TH1 documentation)
void SetBinContent(Int_t bin, Double_t content) override
Set bin content.
Class that contains all the data information.
void ProcessOptions() override
do nothing specific at this moment
std::vector< Int_t > * ParseLayoutString(TString layerSpec)
parse layout specification string and return a vector, each entry containing the number of neurons to...
virtual ~MethodANNBase()
destructor
void DeclareOptions() override
define the options (their key words) that can be set in the option string here the options valid for ...
void DeleteNetworkLayer(TObjArray *&layer)
delete a network layer
void WriteMonitoringHistosToFile() const override
write histograms to file
virtual void BuildNetwork(std::vector< Int_t > *layout, std::vector< Double_t > *weights=nullptr, Bool_t fromFile=kFALSE)
build network given a layout (number of neurons in each layer) and optional weights array
void DeleteNetwork()
delete/clear network
const Ranking * CreateRanking() override
compute ranking of input variables by summing function of weights
void WaitForKeyboard()
wait for keyboard input, for debugging
MethodANNBase(const TString &jobName, Types::EMVA methodType, const TString &methodTitle, DataSetInfo &theData, const TString &theOption)
standard constructor Note: Right now it is an option to choose the neuron input function,...
void AddPreLinks(TNeuron *neuron, TObjArray *prevLayer)
add synapses connecting a neuron to its preceding layer
void PrintNeuron(TNeuron *neuron) const
print a neuron, for debugging
void MakeClassSpecific(std::ostream &, const TString &) const override
write specific classifier response
void PrintMessage(TString message, Bool_t force=kFALSE) const
print messages, turn off printing by setting verbose and debug flag appropriately
void InitANNBase()
initialize ANNBase object
const std::vector< Float_t > & GetMulticlassValues() override
get the multiclass classification values generated by the NN
void PrintLayer(TObjArray *layer) const
print a single layer, for debugging
void ReadWeightsFromStream(std::istream &istr) override
destroy/clear the network then read it back in from the weights file
void InitWeights()
initialize the synapse weights randomly
void ReadWeightsFromXML(void *wghtnode) override
read MLP from xml weight file
void BuildLayers(std::vector< Int_t > *layout, Bool_t from_file=false)
build the network layers
const std::vector< Float_t > & GetRegressionValues() override
get the regression value generated by the NN
void ForceWeights(std::vector< Double_t > *weights)
force the synapse weights
void BuildLayer(Int_t numNeurons, TObjArray *curLayer, TObjArray *prevLayer, Int_t layerIndex, Int_t numLayers, Bool_t from_file=false)
build a single layer with neurons and synapses connecting this layer to the previous layer
void ForceNetworkCalculations()
calculate input values to each neuron
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
get the mva value generated by the NN
void ForceNetworkInputs(const Event *ev, Int_t ignoreIndex=-1)
force the input values of the input neurons force the value for each input neuron
void AddWeightsXMLTo(void *parent) const override
create XML description of ANN classifier
Bool_t Debug() const
who the hell makes such strange Debug flags that even use "global pointers"..
virtual void PrintNetwork() const
print network representation, for debugging
void CreateWeightMonitoringHists(const TString &bulkname, std::vector< TH1 * > *hv=nullptr) const
Virtual base Class for all MVA method.
Ranking for variables in method (implementation)
Class for easily choosing activation functions.
Tanh activation function for ANN.
Neuron class used by TMVA artificial neural network methods.
Double_t GetActivationValue() const
void ForceValue(Double_t value)
force the value, typically for input and bias neurons
TSynapse * PostLinkAt(Int_t index) const
void SetActivationEqn(TActivation *activation)
set activation equation
Double_t GetDelta() const
void SetInputCalculator(TNeuronInput *calculator)
set input calculator
Int_t NumPreLinks() const
void PrintActivationEqn()
print activation equation, for debugging
void CalculateValue()
calculate neuron input
void CalculateActivationValue()
calculate neuron activation/output
void PrintPostLinks() const
Int_t NumPostLinks() const
void AddPreLink(TSynapse *pre)
add synapse as a pre-link to this neuron
Double_t GetValue() const
void DeletePreLinks()
delete all pre-links
void PrintPreLinks() const
Synapse class used by TMVA artificial neural network methods.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Random number generator class based on M.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Bool_t AddRawLine(XMLNodePointer_t parent, const char *line)
Add just line into xml file Line should has correct xml syntax that later it can be decoded by xml pa...
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=nullptr)
create new child element for parent node
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
returns first child of xmlnode
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
const char * GetNodeContent(XMLNodePointer_t xmlnode)
get contents (if any) of xmlnode
XMLNodePointer_t GetNext(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
return next to xmlnode node if realnode==kTRUE, any special nodes in between will be skipped
create variable transformations
MsgLogger & Endl(MsgLogger &ml)
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.