1
2
3
4
5 package yawn.nn.mlp;
6
7 import yawn.nn.NeuralNode;
8 import yawn.util.Pattern;
9
10 /***
11 * This is part of the yawn project.
12 *
13 * <p>$Id: PerceptronNode.java,v 1.12 2005/05/09 11:04:54 supermarti Exp $</p>
14 *
15 * @author Luis Martí (luis dot marti at uc3m dot es)
16 * @version $Revision: 1.12 $
17 */
18 public abstract class PerceptronNode extends NeuralNode {
19
20 /***
21 *
22 * @uml.property name="weights"
23 * @uml.associationEnd multiplicity="(0 1)"
24 */
25 protected Pattern weights;
26
27 /***
28 *
29 * @uml.property name="momentum"
30 * @uml.associationEnd multiplicity="(0 1)"
31 */
32 protected Pattern momentum;
33
34 /***
35 *
36 * @uml.property name="minWeightValue"
37 */
38 protected double minWeightValue = -0.04;
39
40 /***
41 *
42 * @uml.property name="maxWeightValue"
43 */
44 protected double maxWeightValue = 0.04;
45
46
47 /***
48 * @param inputSize
49 */
50 public PerceptronNode(int inputSize) {
51 super(inputSize);
52 weights = new Pattern(inputSize);
53 randomizeWeights();
54 }
55
56 private void randomizeWeights() {
57 weights.randomize(minWeightValue, maxWeightValue);
58 }
59
60 public PerceptronNode() {
61 super(0);
62 }
63
64 public void setInputSize(int inputSize) {
65 super.setInputSize(inputSize);
66 weights = new Pattern(inputSize);
67 randomizeWeights();
68 }
69
70
71
72
73
74
75 protected double activationFunction(Pattern input) {
76 double net = weights.innerProduct(input);
77 return f(net);
78 }
79
80 /***
81 * @return the weigths of this node
82 *
83 * @uml.property name="weights"
84 */
85 public Pattern getWeights() {
86 return this.weights;
87 }
88
89 /***
90 * @param weights
91 *
92 * @uml.property name="weights"
93 */
94 public void setWeights(Pattern weights) {
95 this.weights = weights;
96 }
97
98
99 protected abstract double f(double x);
100
101 protected abstract double df(double x);
102
103 /***
104 * Adapt the weights using the delta rule.
105 *
106 * @param delta
107 * @param learningRate
108 */
109 public void adapt(double delta, double learningRate, double momentumRate) {
110 if (momentum == null) {
111 momentum = new Pattern(weights.size());
112 }
113
114 Pattern oldWeights = new Pattern(weights);
115
116 Pattern deltaTerm = input.multiply(learningRate * delta);
117 Pattern momentumTerm = momentum.multiply(momentumRate);
118
119 weights = weights.add(deltaTerm).add(momentumTerm);
120
121 momentum = weights.substract(oldWeights);
122 }
123
124 public double calculateOutputLayerDelta(double expected) {
125 return (expected - output()) * df(input.innerProduct(weights));
126 }
127
128 /***
129 * Calculate the deltas using the subsequent layer deltas and the weights
130 * emmanent from this node.
131 *
132 * @param nextLayerDeltas
133 * the deltas of the next layer
134 * @param nextLayerWeights
135 * the weights of the connections emaning from this node
136 * @return the value of this node's delta
137 */
138 public double calculateHiddenLayerDelta(Pattern nextLayerDeltas, Pattern nextLayerWeights) {
139 return df(input.innerProduct(weights)) * nextLayerWeights.innerProduct(nextLayerDeltas);
140 }
141
142 /***
143 * @return Returns the maxWeightValue.
144 *
145 * @uml.property name="maxWeightValue"
146 */
147 public double getMaxWeightValue() {
148 return this.maxWeightValue;
149 }
150
151 /***
152 * @param maxWeightValue
153 * The maxWeightValue to set.
154 *
155 * @uml.property name="maxWeightValue"
156 */
157 public void setMaxWeightValue(double maxWeightValue) {
158 this.maxWeightValue = maxWeightValue;
159 }
160
161 /***
162 * @return Returns the minWeightValue.
163 *
164 * @uml.property name="minWeightValue"
165 */
166 public double getMinWeightValue() {
167 return this.minWeightValue;
168 }
169
170 /***
171 * @param minWeightValue
172 * The minWeightValue to set.
173 *
174 * @uml.property name="minWeightValue"
175 */
176 public void setMinWeightValue(double minWeightValue) {
177 this.minWeightValue = minWeightValue;
178 }
179
180 }