1
2
3
4
5
6
7 package yawn.nn.mlp;
8
9 import yawn.YawnRuntimeException;
10 import yawn.nn.Layer;
11 import yawn.nn.NeuralNode;
12 import yawn.util.Pattern;
13
14 /***
15 * This a layer is meant to be used in a Multi-Layer Perceptron. It handles the
16 * thresholds as an extra weight automaticaly.
17 *
18 * <p>$Id: MLPLayer.java,v 1.11 2005/04/20 18:55:03 supermarti Exp $</p>
19 *
20 * @author Luis Martí (luis dot marti at uc3m dot es)
21 * @version $Revision: 1.11 $
22 */
23 public class MLPLayer extends Layer {
24
25 /***
26 * @param nextLayer
27 * @param inputSize
28 */
29 public MLPLayer(Layer nextLayer, int inputSize, int nodesSize, Class nodesClass) {
30 super(nextLayer, inputSize);
31 try {
32 for (int i = 0; i < nodesSize; i++) {
33 NeuralNode node = (NeuralNode) (nodesClass.newInstance());
34 node.setInputSize(inputSize + 1);
35 units.add(node);
36 }
37 } catch (InstantiationException e) {
38 throw new YawnRuntimeException(e);
39 } catch (IllegalAccessException e) {
40 throw new YawnRuntimeException(e);
41 }
42 }
43
44 /***
45 * Does the `threshold as weight' trick.
46 *
47 * @param input
48 * the input pattern
49 */
50 public void setInput(Pattern input) {
51 Pattern inp = new Pattern(input);
52 inp.appendComponent(-1);
53 super.setInput(inp);
54 }
55
56 public Pattern calculateDeltasAsOutputLayer(Pattern expectedOutputs) {
57 Pattern res = new Pattern(units.size());
58 for (int i = 0; i < units.size(); i++) {
59 res.setComponent(((PerceptronNode) units.get(i))
60 .calculateOutputLayerDelta(expectedOutputs.getComponent(i)), i);
61 }
62
63 return res;
64 }
65
66 public Pattern calculateDeltasAsHiddenLayer(Pattern nextLayerDeltas) {
67 Pattern res = new Pattern(units.size());
68 for (int i = 0; i < units.size(); i++) {
69
70
71 NeuralNode[] nextNodes = nextLayer.getNodes();
72
73 Pattern w = new Pattern(nextNodes.length);
74
75 for (int k = 0; k < nextNodes.length; k++) {
76 w.setComponent(((PerceptronNode) nextNodes[k]).getWeights().getComponent(i), k);
77 }
78
79 res.setComponent(((PerceptronNode) units.get(i)).calculateHiddenLayerDelta(
80 nextLayerDeltas, w), i);
81 }
82
83 return res;
84 }
85
86 public void adapt(Pattern deltas, double learningRate, double momentumRate) {
87 NeuralNode[] nodes = getNodes();
88 for (int i = 0; i < nodes.length; i++) {
89 ((PerceptronNode) nodes[i]).adapt(deltas.getComponent(i), learningRate, momentumRate);
90 }
91 }
92 }