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