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