Logo ROOT  
Reference Guide
TNeuron.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Matt Jachowski
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : TNeuron *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation (see header for description) *
12  * *
13  * Authors (alphabetical): *
14  * Matt Jachowski <jachowski@stanford.edu> - Stanford University, USA *
15  * *
16  * Copyright (c) 2005: *
17  * CERN, Switzerland *
18  * *
19  * Redistribution and use in source and binary forms, with or without *
20  * modification, are permitted according to the terms listed in LICENSE *
21  * (http://tmva.sourceforge.net/LICENSE) *
22  **********************************************************************************/
23 
24 /*! \class TMVA::TNeuron
25 \ingroup TMVA
26 Neuron class used by TMVA artificial neural network methods
27 */
28 
29 #include "TMVA/TNeuron.h"
30 
31 #include "TMVA/MsgLogger.h"
32 #include "TMVA/TActivation.h"
33 #include "TMVA/Tools.h"
34 #include "TMVA/TNeuronInput.h"
35 #include "TMVA/Types.h"
36 
37 #include "TH1D.h"
38 #include "ThreadLocalStorage.h"
39 #include "TObjArray.h"
40 
41 static const Int_t UNINITIALIZED = -1;
42 
43 using std::vector;
44 
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// standard constructor
49 
51 {
52  InitNeuron();
53 }
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 /// destructor
57 
59 {
60  if (fLinksIn != NULL) delete fLinksIn;
61  if (fLinksOut != NULL) delete fLinksOut;
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// initialize the neuron, most variables still need to be set via setters
66 
68 {
69  fLinksIn = new TObjArray();
70  fLinksOut = new TObjArray();
71  fValue = UNINITIALIZED;
72  fActivationValue = UNINITIALIZED;
73  fDelta = UNINITIALIZED;
74  fDEDw = UNINITIALIZED;
75  fError = UNINITIALIZED;
76  fActivation = NULL;
77  fForcedValue = kFALSE;
78  fInputCalculator = NULL;
79 }
80 
81 ////////////////////////////////////////////////////////////////////////////////
82 /// force the value, typically for input and bias neurons
83 
85 {
86  fValue = value;
87  fForcedValue = kTRUE;
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// calculate neuron input
92 
94 {
95  if (fForcedValue) return;
96  fValue = fInputCalculator->GetInput(this);
97 }
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 /// calculate neuron activation/output
101 
103 {
104  if (fActivation == NULL) {
105  PrintMessage( kWARNING ,"No activation equation specified." );
106  fActivationValue = UNINITIALIZED;
107  return;
108  }
109  fActivationValue = fActivation->Eval(fValue);
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// calculate error field
114 
116 {
117  // no need to adjust input neurons
118  if (IsInputNeuron()) {
119  fDelta = 0.0;
120  return;
121  }
122 
123  Double_t error;
124 
125  // output neuron should have error set all ready
126  if (IsOutputNeuron()) error = fError;
127 
128  // need to calculate error for any other neuron
129  else {
130  error = 0.0;
131  TSynapse* synapse = NULL;
132  // Replaced TObjArrayIter pointer by object, as creating it on the stack
133  // is much faster (5-10% improvement seen) than re-allocating the new
134  // memory for the pointer each time. Thanks to Peter Elmer who pointed this out
135  // TObjArrayIter* iter = (TObjArrayIter*)fLinksOut->MakeIterator();
136  TObjArrayIter iter(fLinksOut);
137  while (true) {
138  synapse = (TSynapse*) iter.Next();
139  if (synapse == NULL) break;
140  error += synapse->GetWeightedDelta();
141  }
142 
143  }
144 
145  fDelta = error * fActivation->EvalDerivative(GetValue());
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// set input calculator
150 
152 {
153  if (fInputCalculator != NULL) delete fInputCalculator;
154  fInputCalculator = calculator;
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 /// set activation equation
159 
161 {
162  if (fActivation != NULL) delete fActivation;
163  fActivation = activation;
164 }
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// add synapse as a pre-link to this neuron
168 
170 {
171  if (IsInputNeuron()) return;
172  fLinksIn->Add(pre);
173 }
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// add synapse as a post-link to this neuron
177 
179 {
180  if (IsOutputNeuron()) return;
181  fLinksOut->Add(post);
182 }
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// delete all pre-links
186 
188 {
189  DeleteLinksArray(fLinksIn);
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// delete an array of TSynapses
194 
196 {
197  if (links == NULL) return;
198 
199  TSynapse* synapse = NULL;
200  Int_t numLinks = links->GetEntriesFast();
201  for (Int_t i=0; i<numLinks; i++) {
202  synapse = (TSynapse*)links->At(i);
203  if (synapse != NULL) delete synapse;
204  }
205  delete links;
206  links = NULL;
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// set error, this should only be done for an output neuron
211 
213 {
214  if (!IsOutputNeuron())
215  PrintMessage( kWARNING, "Warning! Setting an error on a non-output neuron is probably not what you want to do." );
216 
217  fError = error;
218 }
219 
220 ////////////////////////////////////////////////////////////////////////////////
221 /// update and adjust the pre-synapses for each neuron (input neuron has no pre-synapse)
222 /// this method should only be called in batch mode
223 
225 {
226  if (IsInputNeuron()) return;
227 
228  TSynapse* synapse = NULL;
229  TObjArrayIter iter(fLinksIn);
230  while (true) {
231  synapse = (TSynapse*) iter.Next();
232  if (synapse == NULL) break;
233  synapse->CalculateDelta();
234  }
235 
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// update the pre-synapses for each neuron (input neuron has no pre-synapse)
240 /// this method should only be called in sequential mode
241 
243 {
244  if (IsInputNeuron()) return;
245 
246  TSynapse* synapse = NULL;
247  TObjArrayIter iter(fLinksIn);
248 
249  while (true) {
250  synapse = (TSynapse*) iter.Next();
251  if (synapse == NULL) break;
252  synapse->InitDelta();
253  synapse->CalculateDelta();
254  synapse->AdjustWeight();
255  }
256 
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// adjust the pre-synapses' weights for each neuron (input neuron has no pre-synapse)
261 /// this method should only be called in batch mode
262 
264 {
265  if (IsInputNeuron()) return;
266 
267  TSynapse* synapse = NULL;
268  TObjArrayIter iter(fLinksIn);
269 
270 
271  while (true) {
272  synapse = (TSynapse*) iter.Next();
273  if (synapse == NULL) break;
274  synapse->AdjustWeight();
275  }
276 
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// initialize the error fields of all pre-neurons
281 /// this method should only be called in batch mode
282 
284 {
285  // an input neuron has no pre-weights to adjust
286  if (IsInputNeuron()) return;
287 
288  TSynapse* synapse = NULL;
289  TObjArrayIter iter(fLinksIn);
290 
291  while (true) {
292  synapse = (TSynapse*) iter.Next();
293 
294  if (synapse == NULL) break;
295  synapse->InitDelta();
296  }
297 
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// print an array of TSynapses, for debugging
302 
304 {
305  if (links == NULL) {
306  Log() << kDEBUG << "\t\t\t<none>" << Endl;
307  return;
308  }
309 
310  TSynapse* synapse;
311 
312  Int_t numLinks = links->GetEntriesFast();
313  for (Int_t i = 0; i < numLinks; i++) {
314  synapse = (TSynapse*)links->At(i);
315  Log() << kDEBUG <<
316  "\t\t\tweighta: " << synapse->GetWeight()
317  << "\t\tw-value: " << synapse->GetWeightedValue()
318  << "\t\tw-delta: " << synapse->GetWeightedDelta()
319  << "\t\tl-rate: " << synapse->GetLearningRate()
320  << Endl;
321  }
322 }
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// print activation equation, for debugging
326 
328 {
329  if (fActivation != NULL) Log() << kDEBUG << fActivation->GetExpression() << Endl;
330  else Log() << kDEBUG << "<none>" << Endl;
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// print message, for debugging
335 
336 void TMVA::TNeuron::PrintMessage( EMsgType type, TString message)
337 {
338  Log() << type << message << Endl;
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 
344 {
345  TTHREAD_TLS_DECL_ARG2(MsgLogger,logger,"TNeuron",kDEBUG); //! message logger, static to save resources
346  return logger;
347 }
TMVA::TSynapse::GetWeightedDelta
Double_t GetWeightedDelta()
get error field of post-neuron weighted by synapse weight
Definition: TSynapse.cxx:87
TMVA::TNeuron::InitNeuron
void InitNeuron()
initialize the neuron, most variables still need to be set via setters
Definition: TNeuron.cxx:67
TMVA::TNeuron::AddPreLink
void AddPreLink(TSynapse *pre)
add synapse as a pre-link to this neuron
Definition: TNeuron.cxx:169
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TObjArray
An array of TObjects.
Definition: TObjArray.h:37
TMVA::TSynapse::GetWeight
Double_t GetWeight()
Definition: TSynapse.h:53
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TMVA::TNeuron::UpdateSynapsesSequential
void UpdateSynapsesSequential()
update the pre-synapses for each neuron (input neuron has no pre-synapse) this method should only be ...
Definition: TNeuron.cxx:242
TMVA::TNeuron::CalculateDelta
void CalculateDelta()
calculate error field
Definition: TNeuron.cxx:115
TMath::Log
Double_t Log(Double_t x)
Definition: TMath.h:760
TMVA::TNeuron::AddPostLink
void AddPostLink(TSynapse *post)
add synapse as a post-link to this neuron
Definition: TNeuron.cxx:178
TMVA::TNeuronInput
Interface for TNeuron input calculation classes.
Definition: TNeuronInput.h:42
TMVA::TActivation
Interface for TNeuron activation function classes.
Definition: TActivation.h:42
TMVA::TSynapse::InitDelta
void InitDelta()
Definition: TSynapse.h:83
TMVA::TSynapse::CalculateDelta
void CalculateDelta()
calculate/adjust the error field for this synapse
Definition: TSynapse.cxx:108
TMVA::TNeuron::AdjustSynapseWeights
void AdjustSynapseWeights()
adjust the pre-synapses' weights for each neuron (input neuron has no pre-synapse) this method should...
Definition: TNeuron.cxx:263
TObjArray::At
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
TMVA::TSynapse::GetLearningRate
Double_t GetLearningRate()
Definition: TSynapse.h:59
TString
Basic string class.
Definition: TString.h:136
TObjArrayIter
Iterator of object array.
Definition: TObjArray.h:126
TMVA::TNeuron::TNeuron
TNeuron()
standard constructor
Definition: TNeuron.cxx:50
TMVA::TNeuron::CalculateValue
void CalculateValue()
calculate neuron input
Definition: TNeuron.cxx:93
TMVA::TNeuron::SetError
void SetError(Double_t error)
set error, this should only be done for an output neuron
Definition: TNeuron.cxx:212
TActivation.h
TMVA::TNeuron
Neuron class used by TMVA artificial neural network methods.
Definition: TNeuron.h:49
TMVA::TNeuron::UpdateSynapsesBatch
void UpdateSynapsesBatch()
update and adjust the pre-synapses for each neuron (input neuron has no pre-synapse) this method shou...
Definition: TNeuron.cxx:224
TMVA::TNeuron::PrintActivationEqn
void PrintActivationEqn()
print activation equation, for debugging
Definition: TNeuron.cxx:327
MsgLogger.h
TMVA::TSynapse::GetWeightedValue
Double_t GetWeightedValue()
get output of pre-neuron weighted by synapse weight
Definition: TSynapse.cxx:76
TMVA::TNeuron::SetActivationEqn
void SetActivationEqn(TActivation *activation)
set activation equation
Definition: TNeuron.cxx:160
TMVA::TSynapse
Synapse class used by TMVA artificial neural network methods.
Definition: TSynapse.h:42
TObjArray::GetEntriesFast
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
TMVA::TNeuron::PrintLinks
void PrintLinks(TObjArray *links) const
print an array of TSynapses, for debugging
Definition: TNeuron.cxx:303
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
UNINITIALIZED
static const Int_t UNINITIALIZED
Definition: TNeuron.cxx:41
TMVA::TNeuron::~TNeuron
virtual ~TNeuron()
destructor
Definition: TNeuron.cxx:58
TMVA::TNeuron::ForceValue
void ForceValue(Double_t value)
force the value, typically for input and bias neurons
Definition: TNeuron.cxx:84
Types.h
TMVA::Endl
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:158
TMVA::TNeuron::PrintMessage
void PrintMessage(EMsgType, TString message)
print message, for debugging
Definition: TNeuron.cxx:336
TMVA::TNeuron::InitSynapseDeltas
void InitSynapseDeltas()
initialize the error fields of all pre-neurons this method should only be called in batch mode
Definition: TNeuron.cxx:283
TMVA::TNeuron::CalculateActivationValue
void CalculateActivationValue()
calculate neuron activation/output
Definition: TNeuron.cxx:102
Double_t
double Double_t
Definition: RtypesCore.h:59
TMVA::MsgLogger
ostringstream derivative to redirect and format output
Definition: MsgLogger.h:59
TMVA::TNeuron::DeletePreLinks
void DeletePreLinks()
delete all pre-links
Definition: TNeuron.cxx:187
TObjArray.h
TNeuronInput.h
TMVA::TNeuron::Log
MsgLogger & Log() const
Definition: TNeuron.cxx:343
TMVA::TNeuron::DeleteLinksArray
void DeleteLinksArray(TObjArray *&links)
delete an array of TSynapses
Definition: TNeuron.cxx:195
Tools.h
type
int type
Definition: TGX11.cxx:121
TObjArrayIter::Next
TObject * Next()
Return next object in array. Returns 0 when no more objects in array.
Definition: TObjArray.cxx:931
TH1D.h
ThreadLocalStorage.h
TMVA::TNeuron::SetInputCalculator
void SetInputCalculator(TNeuronInput *calculator)
set input calculator
Definition: TNeuron.cxx:151
TMVA::TSynapse::AdjustWeight
void AdjustWeight()
adjust the weight based on the error field all ready calculated by CalculateDelta
Definition: TSynapse.cxx:98
int
TNeuron.h