source: proiecte/ParallelANN/BCMToolbox/Hebbian2.cs @ 171

Last change on this file since 171 was 171, checked in by (none), 14 years ago
File size: 5.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6namespace BCMToolbox
7{
8
9    #region Hebbian2 Base
10    public abstract class SynchronousHebbian2Network : FixedTraceableNetwork
11    {
12        double[] __intermediaryOutputs = null;
13       
14
15        protected Func<double, double> __activation = MathToolbox.Sigmoid;
16        protected Func<double, double> __activation_inverse = MathToolbox.InverseSigmoid;
17
18        public SynchronousHebbian2Network(int neuronCount, int newID)
19            : base(neuronCount, newID)
20        {
21            __intermediaryOutputs = new double[neuronCount];
22        }
23
24     
25        public override string Identification
26        {
27            get
28            {
29                return String.Format("Hebb2 Layer #{0}", this.UID);
30            }
31        }
32
33        public virtual double Inertia
34        {
35            get
36            {
37                return 0.02;
38            }
39        }
40
41        public virtual double OutputDecay
42        {
43            get
44            {
45                return 0.85;
46            }
47        }
48
49        protected abstract double WeightModificationKernel(double weight, double input, double output);
50       
51
52        public virtual bool HasNormalizedWeights
53        {
54            get
55            {
56                return false;
57            }
58        }
59
60        public virtual bool HasNormalizedInputs
61        {
62            get
63            {
64                return false;
65            }
66        }
67
68       
69
70        public override void ApplyInputs(double[] inputs)
71        {
72            lock (SyncRoot)
73            {
74                if (inputs == null)
75                    throw new ArgumentNullException();
76
77                if (inputs.Length != this.Count)
78                    throw new ArgumentException("Invalid input size. Expected: ", this.Count.ToString());
79
80                for (int i = 0; i < this.Count; i++)
81                    __potentials[i] += inputs[i];
82            }
83
84            if(HasNormalizedInputs)
85                NormalizePotentials(2.0);
86           
87            base.ApplyInputs(inputs);
88        }
89
90
91        public override void Propagate()
92        {
93            // calculate outputs
94            for (int i = 0; i < this.Count; i++)
95            {
96                __intermediaryOutputs[i] = 0.0;
97                for (int j = 0; j < this.Count; j++)
98                    if ((i != j) && !double.IsNaN(__weights[j, i]))
99                        __intermediaryOutputs[i] += __weights[j, i] * __potentials[j];
100                __intermediaryOutputs[i] = __activation(__intermediaryOutputs[i]);
101            }
102
103            if (HasNormalizedInputs)
104            {
105                double[] temp = __potentials;
106                __potentials = __intermediaryOutputs;
107                NormalizePotentials(2.0);
108                __potentials = temp;
109            }
110
111            // update weights and lock outputs
112            lock (SyncRoot)
113            {               
114                for (int i = 0; i < this.Count; i++)
115                    for (int j = 0; j < this.Count; j++)
116                    {
117                        if ((i == j) || double.IsNaN(__weights[i, j]))
118                            continue;
119
120                        __weights[i,j] = WeightModificationKernel(__weights[i, j], __potentials[i], __intermediaryOutputs[j]);
121
122
123                        System.Diagnostics.Debug.Assert(!double.IsNaN(__weights[i, j]));
124                        System.Diagnostics.Debug.Assert(!double.IsInfinity(__weights[i, j]));
125
126
127                       
128                    }
129               
130                if(HasNormalizedWeights)
131                    NormalizeWeights(2.0);
132
133                for (int i = 0; i < this.Count; i++)
134                    __potentials[i] = __intermediaryOutputs[i] * OutputDecay;
135            }
136           
137            base.Propagate();
138        }
139
140        public override void Initialize(Func<int, int, double> initializerWeights, Func<int, double> initializerPotentials)
141        {
142            base.Initialize(initializerWeights, initializerPotentials);
143            if(HasNormalizedInputs)
144                NormalizePotentials(2.0);
145
146            if (HasNormalizedWeights)
147                NormalizeWeights(2.0);
148        }
149    }
150
151    #endregion
152
153    // 0->0 (--), 1->0 (+), 1->1 (++), 0->1 (-)
154    #region Model 01
155    public class Model01 : SynchronousHebbian2Network
156    {
157        const double EXC_THRESHOLD = 0.5;
158        const double MEMORY_CONSTANT = 2.5;
159        public Model01(int neuronCount, int newID)
160            : base(neuronCount, newID)
161        {
162        }
163
164        protected override double WeightModificationKernel(double weight, double input, double output)
165        {
166            double unpacked = __activation_inverse(weight);
167            unpacked += Math.Sign(input - EXC_THRESHOLD)*Math.Pow(Math.Abs(input - EXC_THRESHOLD), MEMORY_CONSTANT) * (1 - Math.Abs(input - output)) * Inertia;
168            unpacked = __activation(unpacked);
169           
170
171           
172            return unpacked;
173        }
174
175        public override double Inertia
176        {
177            get
178            {
179                return 0.02;
180            }
181        }
182    }
183    #endregion
184}
Note: See TracBrowser for help on using the repository browser.