TNeuron.cxx

Go to the documentation of this file.
00001 // @(#)root/tmva $Id: TNeuron.cxx 36966 2010-11-26 09:50:13Z evt $
00002 // Author: Matt Jachowski
00003 
00004 /**********************************************************************************
00005  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
00006  * Package: TMVA                                                                  *
00007  * Class  : TNeuron                                                               *
00008  * Web    : http://tmva.sourceforge.net                                           *
00009  *                                                                                *
00010  * Description:                                                                   *
00011  *      Implementation (see header for description)                               *
00012  *                                                                                *
00013  * Authors (alphabetical):                                                        *
00014  *      Matt Jachowski  <jachowski@stanford.edu> - Stanford University, USA       *
00015  *                                                                                *
00016  * Copyright (c) 2005:                                                            *
00017  *      CERN, Switzerland                                                         *
00018  *                                                                                *
00019  * Redistribution and use in source and binary forms, with or without             *
00020  * modification, are permitted according to the terms listed in LICENSE           *
00021  * (http://tmva.sourceforge.net/LICENSE)                                          *
00022  **********************************************************************************/
00023 
00024 //_______________________________________________________________________
00025 //
00026 // Neuron class used by TMVA artificial neural network methods
00027 //
00028 //_______________________________________________________________________
00029 
00030 #include "TH1D.h"
00031 
00032 #ifndef ROOT_TMVA_MsgLogger
00033 #include "TMVA/MsgLogger.h"
00034 #endif
00035 #ifndef ROOT_TMVA_TNeuron
00036 #include "TMVA/TNeuron.h"
00037 #endif
00038 #ifndef ROOT_TMVA_TActivation
00039 #include "TMVA/TActivation.h"
00040 #endif
00041 #ifndef ROOT_TMVA_Tools
00042 #include "TMVA/Tools.h"
00043 #endif
00044 #ifndef ROOT_TMVA_TNeuronInput
00045 #include "TMVA/TNeuronInput.h"
00046 #endif
00047 
00048 static const Int_t UNINITIALIZED = -1;
00049 
00050 using std::vector;
00051 
00052 ClassImp(TMVA::TNeuron)
00053 
00054 TMVA::MsgLogger* TMVA::TNeuron::fgLogger = 0;
00055 
00056 //______________________________________________________________________________
00057 TMVA::TNeuron::TNeuron()
00058 {
00059    // standard constructor
00060    if (!fgLogger) fgLogger = new MsgLogger("TNeuron",kDEBUG);
00061    InitNeuron();
00062 }
00063 
00064 TMVA::TNeuron::~TNeuron()
00065 {
00066    // destructor
00067    if (fLinksIn != NULL)  delete fLinksIn;
00068    if (fLinksOut != NULL) delete fLinksOut;
00069 }
00070 
00071 void TMVA::TNeuron::InitNeuron()
00072 {
00073    // initialize the neuron, most variables still need to be set via setters
00074    fLinksIn = new TObjArray();
00075    fLinksOut = new TObjArray();
00076    fValue = UNINITIALIZED;
00077    fActivationValue = UNINITIALIZED;
00078    fDelta = UNINITIALIZED;
00079    fDEDw = UNINITIALIZED;
00080    fError = UNINITIALIZED;
00081    fActivation = NULL;
00082    fForcedValue = kFALSE;
00083    fInputCalculator = NULL;
00084 }
00085 
00086 //______________________________________________________________________________
00087 void TMVA::TNeuron::ForceValue(Double_t value)
00088 {
00089    // force the value, typically for input and bias neurons
00090    fValue = value;
00091    fForcedValue = kTRUE;
00092 }
00093 
00094 //______________________________________________________________________________
00095 void TMVA::TNeuron::CalculateValue()
00096 {
00097    // calculate neuron input
00098    if (fForcedValue) return;
00099    fValue = fInputCalculator->GetInput(this);
00100 }
00101 
00102 //______________________________________________________________________________
00103 void TMVA::TNeuron::CalculateActivationValue()
00104 {
00105    // calculate neuron activation/output
00106 
00107    if (fActivation == NULL) {
00108       PrintMessage( kWARNING ,"No activation equation specified." );
00109       fActivationValue = UNINITIALIZED;
00110       return;
00111    }
00112    fActivationValue = fActivation->Eval(fValue);
00113 }
00114 
00115 
00116 //______________________________________________________________________________
00117 void TMVA::TNeuron::CalculateDelta()
00118 {
00119    // calculate error field
00120 
00121    // no need to adjust input neurons
00122    if (IsInputNeuron()) {
00123       fDelta = 0.0;
00124       return;
00125    }
00126 
00127    Double_t error;
00128 
00129    // output neuron should have error set all ready
00130    if (IsOutputNeuron()) error = fError;
00131 
00132    // need to calculate error for any other neuron
00133    else {
00134       error = 0.0;
00135       TSynapse* synapse = NULL;
00136       TObjArrayIter* iter = (TObjArrayIter*)fLinksOut->MakeIterator();
00137 
00138       while (true) {
00139          synapse = (TSynapse*) iter->Next();
00140          if (synapse == NULL) break;
00141          error += synapse->GetWeightedDelta();
00142       }
00143 
00144       delete iter;
00145    }
00146 
00147    fDelta = error * fActivation->EvalDerivative(GetValue());
00148 }
00149 
00150 //______________________________________________________________________________
00151 void TMVA::TNeuron::SetInputCalculator(TNeuronInput* calculator)
00152 {
00153    // set input calculator
00154    if (fInputCalculator != NULL) delete fInputCalculator; 
00155    fInputCalculator = calculator;
00156 }
00157 
00158 //______________________________________________________________________________
00159 void TMVA::TNeuron::SetActivationEqn(TActivation* activation)
00160 {
00161    // set activation equation
00162    if (fActivation != NULL) delete fActivation;
00163    fActivation = activation;
00164 }
00165 
00166 //______________________________________________________________________________
00167 void TMVA::TNeuron::AddPreLink(TSynapse* pre)
00168 {
00169    // add synapse as a pre-link to this neuron
00170    if (IsInputNeuron()) return;
00171    fLinksIn->Add(pre);
00172 }
00173 
00174 //______________________________________________________________________________
00175 void TMVA::TNeuron::AddPostLink(TSynapse* post)
00176 {
00177    // add synapse as a post-link to this neuron
00178    if (IsOutputNeuron()) return;
00179    fLinksOut->Add(post);
00180 }
00181 
00182 //______________________________________________________________________________
00183 void TMVA::TNeuron::DeletePreLinks()
00184 {
00185    // delete all pre-links
00186    DeleteLinksArray(fLinksIn);
00187 }
00188 
00189 //______________________________________________________________________________
00190 void TMVA::TNeuron::DeleteLinksArray(TObjArray*& links)
00191 {
00192    // delete an array of TSynapses
00193 
00194    if (links == NULL) return;
00195 
00196    TSynapse* synapse = NULL;
00197    Int_t numLinks = links->GetEntriesFast();
00198    for (Int_t i=0; i<numLinks; i++) {
00199       synapse = (TSynapse*)links->At(i);
00200       if (synapse != NULL) delete synapse;
00201    }
00202    delete links;
00203    links = NULL;
00204 }
00205 
00206 //______________________________________________________________________________
00207 void TMVA::TNeuron::SetError(Double_t error)
00208 {
00209    // set error, this should only be done for an output neuron
00210    if (!IsOutputNeuron())
00211       PrintMessage( kWARNING, "Warning! Setting an error on a non-output neuron is probably not what you want to do." );
00212 
00213    fError = error;
00214 }
00215 
00216 //______________________________________________________________________________
00217 void TMVA::TNeuron::UpdateSynapsesBatch()
00218 {
00219    // update and adjust the pre-synapses for each neuron (input neuron has no pre-synapse)
00220    // this method should only be called in batch mode
00221 
00222    if (IsInputNeuron()) return;
00223 
00224    TSynapse* synapse = NULL;
00225    TObjArrayIter* iter = (TObjArrayIter*) fLinksIn->MakeIterator();
00226 
00227    while (true) {
00228       synapse = (TSynapse*) iter->Next();
00229       if (synapse == NULL) break;
00230       synapse->CalculateDelta();
00231    }
00232 
00233    delete iter;
00234 }
00235 
00236 //______________________________________________________________________________
00237 void TMVA::TNeuron::UpdateSynapsesSequential()
00238 {
00239    // update the pre-synapses for each neuron (input neuron has no pre-synapse)
00240    // this method should only be called in sequential mode
00241 
00242    if (IsInputNeuron()) return;
00243 
00244    TSynapse* synapse = NULL;
00245    TObjArrayIter* iter = (TObjArrayIter*) fLinksIn->MakeIterator();
00246 
00247    while (true) {
00248       synapse = (TSynapse*) iter->Next();
00249       if (synapse == NULL) break;
00250       synapse->InitDelta();
00251       synapse->CalculateDelta();
00252       synapse->AdjustWeight();
00253    }
00254 
00255    delete iter;
00256 }
00257 
00258 //______________________________________________________________________________
00259 void TMVA::TNeuron::AdjustSynapseWeights()
00260 {
00261    // adjust the pre-synapses' weights for each neuron (input neuron has no pre-synapse)
00262    // this method should only be called in batch mode
00263 
00264    if (IsInputNeuron()) return;
00265 
00266    TSynapse* synapse = NULL;
00267    TObjArrayIter* iter = (TObjArrayIter*) fLinksIn->MakeIterator();
00268 
00269    while (true) {
00270       synapse = (TSynapse*) iter->Next();
00271       if (synapse == NULL) break;
00272       synapse->AdjustWeight();
00273    }
00274 
00275    delete iter;
00276 }
00277 
00278 //______________________________________________________________________________
00279 void TMVA::TNeuron::InitSynapseDeltas()
00280 {
00281    // initialize the error fields of all pre-neurons
00282    // this method should only be called in batch mode
00283 
00284    // an input neuron has no pre-weights to adjust
00285    if (IsInputNeuron()) return;
00286 
00287    TSynapse* synapse = NULL;
00288    TObjArrayIter* iter = (TObjArrayIter*) fLinksIn->MakeIterator();
00289 
00290    while (true) {
00291       synapse = (TSynapse*) iter->Next();
00292       if (synapse == NULL) break;
00293       synapse->InitDelta();
00294    }
00295 
00296    delete iter;
00297 }
00298 
00299 //______________________________________________________________________________
00300 void TMVA::TNeuron::PrintLinks(TObjArray* links) const 
00301 {
00302    // print an array of TSynapses, for debugging
00303 
00304    if (links == NULL) {
00305       Log() << kDEBUG << "\t\t\t<none>" << Endl;
00306       return;
00307    }
00308 
00309    TSynapse* synapse;
00310 
00311    Int_t numLinks = links->GetEntriesFast();
00312    for  (Int_t i = 0; i < numLinks; i++) {
00313       synapse = (TSynapse*)links->At(i);
00314       Log() << kDEBUG <<  
00315          "\t\t\tweighta: " << synapse->GetWeight()
00316            << "\t\tw-value: " << synapse->GetWeightedValue()
00317            << "\t\tw-delta: " << synapse->GetWeightedDelta()
00318            << "\t\tl-rate: "  << synapse->GetLearningRate()
00319            << Endl;
00320    }
00321 }
00322 
00323 //______________________________________________________________________________
00324 void TMVA::TNeuron::PrintActivationEqn()
00325 {
00326    // print activation equation, for debugging
00327    if (fActivation != NULL) Log() << kDEBUG << fActivation->GetExpression() << Endl;
00328    else                     Log() << kDEBUG << "<none>" << Endl;
00329 }
00330 
00331 //______________________________________________________________________________
00332 void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
00333 {
00334    // print message, for debugging
00335    Log() << type << message << Endl;
00336 }

Generated on Tue Jul 5 14:37:21 2011 for ROOT_528-00b_version by  doxygen 1.5.1