1 package yawn.nn.gasart;
2
3 import java.util.Vector;
4
5 import yawn.nn.InputLayer;
6 import yawn.nn.appart.AppArt;
7 import yawn.nn.appart.GainControlUnitOnMatching;
8 import yawn.nn.appart.GainControlUnitOnOutput;
9 import yawn.util.Pattern;
10
11 /***
12 * This class implements the GasArt neural network. See <blockquote>
13 * Martí, L., Policriti, A. & García, L (2003). Hybrid Adaptive
14 * Resonance Theory Neural Networks for Universal CommitteeFunction
15 * Approximation. In Abraham, A. and Jain, L. (eds.), Innovations in Intelligent
16 * Systems and Applications, Studies in Fuzziness and Soft Computing Series.
17 * Heidelberg: Physica (Springer) Verlag </blockquote> for details.
18 *
19 * <p>$Id: GasArt.java,v 1.11 2005/05/09 11:04:57 supermarti Exp $</p>
20 *
21 * @author Luis Martí (luis dot marti at uc3m dot es)
22 * @version $Revision: 1.11 $
23 */
24
25 public class GasArt extends AppArt {
26
27 /***
28 *
29 */
30 private static final long serialVersionUID = 3258412824522208311L;
31
32 /***
33 * Stores the F2 layer topoCommons.LOGy
34 *
35 * @uml.property name="edgesVector"
36 * @uml.associationEnd multiplicity="(0 -1)" elementType="yawn.nn.gasart.GasEdge"
37 */
38 protected Vector edgesVector = new Vector();
39
40 protected double bmuFact;
41
42 protected int maxAge;
43
44 protected double neighborFact;
45
46 public GasArt(int inputSize, int outputSize, double initialDeviation, double bmuConst,
47 double neighborConst, double learncte, double matchError, double outError, int mAge) {
48
49
50 super();
51
52 initialDeviations = new Pattern(inputSize);
53 initialDeviations.setAllComponents(initialDeviation);
54
55 outputGainControl = new GainControlUnitOnOutput(outError);
56 f2Layer = new GasRecognitionLayer(predictionLayer, null, inputSize);
57 f2GainControl = new GainControlUnitOnMatching(matchError, f2Layer);
58 f2Layer.setGF2(f2GainControl);
59 inputLayer = new InputLayer(f2Layer, inputSize);
60 f2Layer.connectWith(predictionLayer);
61 bmuFact = bmuConst;
62 neighborFact = neighborConst;
63 maxAge = mAge;
64 }
65
66 public void clean() {
67 int pos = 0;
68 GasRecognitionNode unitOut = getHeaviest();
69 if (unitOut == null)
70 return;
71
72 GasRecognitionNode unit = null;
73 GasEdge ed;
74 while (!unitOut.toWhoIBelong.isEmpty()) {
75 ed = (GasEdge) unitOut.toWhoIBelong.elementAt(pos);
76 unitOut.toWhoIBelong.removeElement(ed);
77 unit = unitOut != ed.vertexA ? ed.vertexA : ed.vertexB;
78 unit.toWhoIBelong.removeElement(ed);
79 edgesVector.removeElement(ed);
80 pos++;
81 }
82 }
83
84 public void computeAllLengths() {
85 int l = edgesVector.size();
86 for (int i = 0; i < l; i++)
87 ((GasEdge) edgesVector.elementAt(i)).length();
88 }
89
90 public void computeAllSigmas() {
91 int l = ((GasRecognitionLayer) f2Layer).getUnits().size();
92 int l2 = 0;
93 double sig;
94 GasRecognitionNode unit;
95 for (int i = 0; i < l; i++) {
96 unit = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(i));
97 l2 = unit.toWhoIBelong.size();
98 sig = 0.0;
99 for (int j = 0; j < l2; j++)
100 sig += ((GasEdge) unit.toWhoIBelong.elementAt(j)).length();
101
102
103 if (l2 == 0)
104 unit.setSigma(0);
105 else
106 unit.setSigma(sig / l2);
107 }
108 l = edgesVector.size();
109 for (int i = 0; i < l; i++)
110 ((GasEdge) edgesVector.elementAt(i)).doneDist = false;
111
112 }
113
114 public void doBackTrack() {
115 penalize();
116 super.doBackTrack();
117 }
118
119 public void doMatchTracking() {
120 f2GainControl.minimumActivationMatchTracking();
121 }
122
123 public GasRecognitionNode getHeaviest() {
124 double max1 = -1 * Double.MIN_VALUE;
125 GasRecognitionNode result = null;
126 int pos1 = -1;
127 double cant = 0.0;
128 double sum = 0.0;
129 int l = ((GasRecognitionLayer) f2Layer).getUnits().size();
130 for (int i = 0; i < l; i++) {
131 cant = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(i)).resource;
132 sum += cant;
133 if (cant > max1) {
134 max1 = cant;
135 pos1 = i;
136 }
137 }
138
139 if (max1 > 0.5 * sum) {
140 result = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(pos1));
141 ((GasRecognitionLayer) f2Layer).deleteCategory(result);
142 }
143
144 return result;
145 }
146
147 public void learn(Pattern p) {
148 GasRecognitionNode firstBmu = null;
149
150 if (!isAdapting()) {
151 return;
152 }
153
154 firstBmu = makeFstSndBMUConexion(inputLayer.output());
155
156
157 makeCentralAdapIncAgeDelOld(firstBmu);
158
159
160
161 computeAllLengths();
162 computeAllSigmas();
163
164
165
166 this.predictionLayer.learn(p);
167 firstBmu.incResource(outputGainControl.getError());
168 }
169
170 public Pattern learnNewCategory(Pattern p) {
171 Pattern p1 = super.learnNewCategory(p);
172 if (!isAdapting())
173 return p1;
174
175
176
177
178
179
180
181
182
183 int l = f2Layer.size() - 1;
184 double cant;
185 double max = 0.0;
186 int pos = -1;
187 Object nw = ((GasRecognitionLayer) f2Layer).getUnits().get(l);
188
189
190
191
192 ((GasRecognitionNode) nw).inserted = true;
193 for (int i = 0; i < l; i++) {
194 cant = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(i)).resource;
195 if (cant > max) {
196 max = cant;
197 pos = i;
198 }
199 }
200
201 if (pos != -1)
202 makeNewEdge((GasRecognitionNode) nw,
203 (GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(pos));
204 double er = p.dist(p1);
205 ((GasRecognitionNode) nw).incResource(er);
206
207 return p1;
208 }
209
210 public void makeCentralAdapIncAgeDelOld(GasRecognitionNode Bmu) {
211 Bmu.learn(bmuFact);
212 int l = Bmu.toWhoIBelong.size();
213 GasRecognitionNode neighBor;
214 GasEdge ed;
215 Vector edV = new Vector();
216
217 for (int i = 0; i < l; i++) {
218 ed = (GasEdge) Bmu.toWhoIBelong.elementAt(i);
219 neighBor = (ed.vertexA == Bmu) ? ed.vertexB : ed.vertexA;
220 neighBor.learn(neighborFact);
221 ed.age++;
222 if (ed.age > maxAge)
223 edV.addElement(ed);
224 }
225
226 l = edV.size();
227
228 for (int j = 0; j < l; j++) {
229 ed = (GasEdge) edV.elementAt(j);
230 ed.vertexA.toWhoIBelong.removeElement(ed);
231 ed.vertexB.toWhoIBelong.removeElement(ed);
232 edgesVector.removeElement(ed);
233 }
234 }
235
236 public GasRecognitionNode makeFstSndBMUConexion(Pattern p) {
237
238 int l = f2Layer.size();
239 if (l == 1)
240 return (GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(0);
241
242 double cant;
243 double min1 = Float.MAX_VALUE;
244 double min2 = Float.MAX_VALUE;
245 int pos1 = -1;
246 int pos2 = -1;
247 for (int i = 0; i < l; i++) {
248 cant = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(i))
249 .position().dist(p);
250 if (cant < min1) {
251 min1 = cant;
252 pos1 = i;
253 }
254 if (cant < min2) {
255 min1 = min2;
256 pos1 = pos2;
257 min2 = cant;
258 pos2 = i;
259 }
260 }
261
262 GasRecognitionNode v1 = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits()
263 .get(pos2));
264 GasRecognitionNode v2 = ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits()
265 .get(pos1));
266 GasEdge ed = v1.edgeWith(v2);
267 v1.winner = true;
268 v1.second = v1.inserted = false;
269 v2.second = true;
270 v2.winner = v2.inserted = false;
271
272 if (ed != null)
273 ed.age = 0;
274 else
275 makeNewEdge(v1, v2);
276 return v1;
277 }
278
279 public void makeNewEdge(GasRecognitionNode v1, GasRecognitionNode v2) {
280 GasEdge nw = new GasEdge(v1, v2);
281 edgesVector.addElement(nw);
282 v1.toWhoIBelong.addElement(nw);
283 v2.toWhoIBelong.addElement(nw);
284 }
285
286 public void penalize() {
287 int l = ((GasRecognitionLayer) f2Layer).getUnits().size();
288 double er = outputGainControl.getError();
289
290 for (int i = 0; i < l; i++) {
291 ((GasRecognitionNode) ((GasRecognitionLayer) f2Layer).getUnits().get(i))
292 .setPenality(er);
293 }
294
295 }
296
297 }