1 package yawn.nn.appart;
2
3 import yawn.nn.NeuralNode;
4 import yawn.util.Pattern;
5
6 /***
7 * A classifier (extended RBF) node intended for the recognition (F2) layer of a
8 * AppART network.
9 *
10 * <p>$Id: RadialBasisFunctionsNeuralNode.java,v 1.10 2005/05/09 11:04:55 supermarti Exp $</p>
11 *
12 * @author Luis Martí (luis dot marti at uc3m dot es)
13 * @version $Revision: 1.10 $
14 */
15 public class RadialBasisFunctionsNeuralNode extends NeuralNode {
16
17 /***
18 *
19 * @uml.property name="categoryIndex"
20 */
21 protected int categoryIndex;
22
23 /***
24 *
25 * @uml.property name="eta"
26 */
27 protected double eta;
28
29 /***
30 *
31 * @uml.property name="lambda"
32 * @uml.associationEnd multiplicity="(1 1)"
33 */
34 protected Pattern lambda;
35
36 /***
37 *
38 * @uml.property name="mu"
39 * @uml.associationEnd multiplicity="(1 1)"
40 */
41 protected Pattern mu;
42
43 /***
44 *
45 * @uml.property name="sigma"
46 * @uml.associationEnd multiplicity="(1 1)"
47 */
48 protected Pattern sigma;
49
50 /***
51 * holds the vigilance parameter specified in GF2
52 *
53 * @uml.property name="threshold"
54 */
55 protected double threshold;
56
57
58 /***
59 *
60 * @param inputSize
61 * @param aThreshold
62 * @param aCategoryIndex
63 */
64 public RadialBasisFunctionsNeuralNode(int inputSize, double aThreshold, int aCategoryIndex) {
65 super(inputSize);
66 categoryIndex = aCategoryIndex;
67 threshold = aThreshold;
68 mu = new Pattern(inputSize);
69 lambda = new Pattern(inputSize);
70 sigma = new Pattern(inputSize);
71 }
72
73 /***
74 *
75 * @see yawn.nn.NeuralNode#activationFunction(yawn.util.Pattern)
76 */
77 protected double activationFunction(Pattern input) {
78 double bigG = bigG(input);
79
80 if (bigG <= threshold) {
81 return 0;
82 }
83 return eta * bigG / deviationsProduct();
84 }
85
86 public double bigG() {
87 return bigG(input);
88 }
89
90 protected double bigG(Pattern input) {
91 return Math.exp(-0.5 * netInput(input));
92 }
93
94 public double deviationsProduct() {
95 double aux = 1.0;
96 for (int i = 0; i < getInputSize(); i++) {
97 aux *= sigma.getComponent(i);
98 }
99 return aux;
100 }
101
102 /***
103 * @return the index of this category node
104 *
105 * @uml.property name="categoryIndex"
106 */
107 public int getCategoryIndex() {
108 return this.categoryIndex;
109 }
110
111 /***
112 * @return the vakue of eta
113 *
114 * @uml.property name="eta"
115 */
116 public double getEta() {
117 return this.eta;
118 }
119
120
121 /***
122 *
123 * @see yawn.nn.NeuralNode#getInputSize()
124 */
125 public int getInputSize() {
126 return mu.size();
127 }
128
129 /***
130 * @return the value
131 *
132 * @uml.property name="lambda"
133 */
134 public Pattern getLambda() {
135 return this.lambda;
136 }
137
138 /***
139 * @return the value
140 *
141 * @uml.property name="mu"
142 */
143 public Pattern getMu() {
144 return this.mu;
145 }
146
147 /***
148 * @return the value
149 *
150 * @uml.property name="sigma"
151 */
152 public Pattern getSigma() {
153 return this.sigma;
154 }
155
156 /***
157 * @return the threshold value
158 *
159 * @uml.property name="threshold"
160 */
161 public double getThreshold() {
162 return this.threshold;
163 }
164
165
166 public void learn(double v) {
167 eta += v;
168 for (int i = 0; i < getInputSize(); i++) {
169 mu
170 .setComponent((1 - v / eta) * mu.getComponent(i) + v * input.getComponent(i)
171 / eta, i);
172 lambda.setComponent((1 - v / eta) * lambda.getComponent(i) + v * input.getComponent(i)
173 / eta, i);
174 sigma.setComponent(Math.sqrt(lambda.getComponent(i) - mu.getComponent(i)
175 * mu.getComponent(i)), i);
176 }
177 }
178
179 /***
180 * Sets up the node to exactly represents the class specified by the current
181 * input. This is used when committing a node.
182 *
183 * @param gamma
184 * initial standard deviations
185 * @param n
186 * index of the class being learned
187 */
188 public void learnNewClass(Pattern gamma, int n) {
189 categoryIndex = n;
190 eta = 1;
191 mu = (Pattern) input.clone();
192 for (int i = 0; i < getInputSize(); i++) {
193 lambda.setComponent(input.getComponent(i) * input.getComponent(i)
194 + gamma.getComponent(i), i);
195 }
196 sigma = (Pattern) gamma.clone();
197 }
198
199 public double netInput() {
200 return netInput(input);
201 }
202
203 protected double netInput(Pattern input) {
204 double netInput = 0;
205 for (int i = 0; i < input.size(); i++) {
206 netInput += Math.pow((input.getComponent(i) - mu.getComponent(i))
207 / sigma.getComponent(i), 2.0);
208 }
209 return netInput;
210 }
211
212 /***
213 * @param categoryIndex
214 *
215 * @uml.property name="categoryIndex"
216 */
217 public void setCategoryIndex(int categoryIndex) {
218 this.categoryIndex = categoryIndex;
219 }
220
221 /***
222 * @param eta
223 *
224 * @uml.property name="eta"
225 */
226 public void setEta(double eta) {
227 this.eta = eta;
228 }
229
230 /***
231 * @param lambda
232 *
233 * @uml.property name="lambda"
234 */
235 public void setLambda(Pattern lambda) {
236 this.lambda = lambda;
237 }
238
239 /***
240 * @param mu
241 *
242 * @uml.property name="mu"
243 */
244 public void setMu(Pattern mu) {
245 this.mu = mu;
246 }
247
248 /***
249 * @param sigma
250 *
251 * @uml.property name="sigma"
252 */
253 public void setSigma(Pattern sigma) {
254 this.sigma = sigma;
255 }
256
257 /***
258 * @param threshold
259 *
260 * @uml.property name="threshold"
261 */
262 public void setThreshold(double threshold) {
263 this.threshold = threshold;
264 }
265
266 }