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 }