View Javadoc

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&iacute;, L., Policriti, A. & Garc&iacute;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&iacute; (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          // super(outputSize, learncte);
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             // el llamado a length retornara enseguida pues ya fueron calculadas
102             // las distancias
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         // es decir los dos mas cercanos a la sennal de entrada
157         makeCentralAdapIncAgeDelOld(firstBmu);
158 
159         // las aristas que se eliminaran deben decirle a sus extremos que
160         // las saquen de sus vectores
161         computeAllLengths();
162         computeAllSigmas();// usa los length reciencalculados
163 
164         // los "solos" poner sus sigmas a 0
165         // debe al terminar ponerse los doneDist a false
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         // SI YA NO ESTOY APRENDIENDO Y ERA ALGUNA ENTRADA
175         // PARA LA QUE NO HUBO CATEGORIA QUE REACCIONARA(puesto que entro aqui)
176         // DARE UN "I DON'T KNOW"
177 
178         /*
179          * AQUI ADEMAS SE HARA QUE LA UNIDAD QUE REPRESENTA A LA NUEVA CATEGORIA
180          * SE HAGA VECINO DEL QUE MAYOR ERROR TENGA ACUMULADO (PUEDE QUE NO
181          * EXISTA NADIE MAS O QUE NADIE HAYA ACUMULADO ERROR)
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);// el
188                                                                         // que
189                                                                         // se
190         // acabo de
191         // insertar
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);// desire,outPut
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         // si se llamo ,al menos existe una unidad
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         // en pos2 queda el firstBmu y en pos1 el SndBmu
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 }