Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class Tester
- {
- public static void main(String[] args)
- {
- double[][] inputs = {
- {0.547361, -2.04845, -2.71647},
- {1.9708, -1.16141, -0.0485735},
- {-3.18799, 2.97068, 0.26499},
- {-0.498425, -1.04703, 1.61744}
- };
- double[][] outputs = {
- {1.0, 0.0, 0.0, 0.0},
- {0.0, 1.0, 0.0, 0.0},
- {0.0, 0.0, 1.0, 0.0},
- {0.0, 0.0, 0.0, 1.0}
- };
- Example[] examples = new Example[inputs.length];
- for (int i = 0; i < examples.length; i++)
- examples[i] = new Example(inputs[i], outputs[i]);
- int[] hiddenLayers = {4,4}; // sizes of hidden layers
- Network net = new Network();
- net.backPropLearning(examples, hiddenLayers, 10000, 1.0);
- }
- }
- public class Network
- {
- private Layer[] layers;
- static double reportMultiplier = -1.0;
- private void setLayer (Layer layer, int i)
- {
- layers[i] = layer;
- }
- private void createLayers (int numInputs, int numOutputs, int[] hiddenLayers)
- {
- layers = new Layer[hiddenLayers.length + 2];
- Layer inputLayer = new Layer(numInputs);
- setLayer(inputLayer, 0);
- for (int i = 0; i < hiddenLayers.length; i++)
- setLayer(new Layer(layers[i], hiddenLayers[i]), i + 1);
- Layer outputLayer = new Layer(layers[hiddenLayers.length], numOutputs);
- setLayer(outputLayer, layers.length - 1);
- for (int i = 0; i < layers.length; i++)
- layers[i].createNeurons();
- }
- private double activation (double x)
- {
- return 1.0 / (1.0 + Math.exp(-x)); // sigmoid
- }
- private double activationDerivative (double x)
- {
- double exp = Math.exp(x);
- return exp / Math.pow((exp + 1.0), 2); // d/dx sigmoid
- }
- private void printReport (int n, Example[] examples)
- {
- String s = "";
- double errorSum = 0.0;
- int m = layers.length - 1;
- for (int i = 0; i < layers[m].getSize(); i++)
- for (int j = 0; j < examples.length; j++)
- errorSum += Math.abs(examples[j].getOutput(i) - (layers[m].getNeuron(i)).getOutput());
- s = "n:" + n;
- while (s.length() < 10)
- s += " ";
- s += "error:" + (float) errorSum;
- while (s.length() < 30)
- s += " ";
- System.out.print(s);
- if (reportMultiplier < 0)
- reportMultiplier = 50 / errorSum;
- for (int i = 0; i < errorSum * reportMultiplier; i++)
- System.out.print("|");
- System.out.println();
- }
- public void backPropLearning (Example[] examples, int[] hiddenLayers, int steps, double learningFactor)
- {
- createLayers(examples[0].numInputs(), examples[0].numOutputs(), hiddenLayers);
- int n = 0;
- int numPlots = 50;
- int plotStep = Math.max(1, steps / numPlots);
- while (n < steps) {
- for (int e = 0; e < examples.length; e++) {
- Example example = examples[e];
- // Propagate the inputs forward to compute the output
- for (int i = 0; i < layers[0].getSize(); i++)
- layers[0].getNeuron(i).setOutput(example.getInput(i));
- for (int i = 1; i < layers.length; i++) {
- for (int j = 0; j < layers[i].getSize(); j++) {
- Neuron nj = layers[i].getNeuron(j);
- double in = 0.0;
- for (int k = 0; k < nj.numInputs(); k++) {
- Axon akj = nj.getInput(k);
- Neuron nk = akj.getStart();
- in += akj.getWeight() * nk.getOutput();
- }
- nj.setInput(in);
- nj.setOutput(activation(in));
- }
- }
- // Propagate deltas backward from output to input layer
- int m = layers.length - 1;
- for (int i = 0; i < layers[m].getSize(); i++) {
- Neuron ni = layers[m].getNeuron(i);
- double errori = example.getOutput(i) - ni.getOutput();
- ni.setDelta(activationDerivative(ni.getInput()) * errori);
- }
- for (int i = m - 1; i >= 0; i--) {
- for (int j = 0; j < layers[i].getSize(); j++) {
- Neuron nj = layers[i].getNeuron(j);
- double delta = 0.0;
- for (int k = 0; k < nj.numOutputs(); k++) {
- Axon ajk = nj.getOutput(k);
- Neuron nk = ajk.getEnd();
- delta += ajk.getWeight() * nk.getDelta();
- }
- delta *= activationDerivative(nj.getInput());
- nj.setDelta(delta);
- }
- }
- // Update every weight in network using deltas
- for (int i = 0; i < layers.length - 1; i++) {
- for (int j = 0; j < layers[i].getSize(); j++) {
- Neuron nj = layers[i].getNeuron(j);
- for (int k = 0; k < nj.numOutputs(); k++) {
- Axon ajk = nj.getOutput(k);
- Neuron nk = ajk.getEnd();
- ajk.modifyWeight(learningFactor * nk.getDelta() * nj.getOutput());
- ajk.modifyWeight(learningFactor * nj.getDelta() * nk.getOutput());
- }
- }
- }
- }
- if (n % plotStep == 0)
- printReport(n, examples);
- n++;
- }
- printReport(n, examples);
- }
- }
- public class Layer
- {
- private Neuron[] neurons;
- private Layer previous;
- private Layer next;
- public Layer (int n)
- {
- neurons = new Neuron[n];
- }
- public Layer (Layer l, int n)
- {
- this(n);
- previous = l;
- previous.next = this;
- }
- public void createNeurons ()
- {
- int n = previous == null ? 0 : previous.neurons.length;
- int m = next == null ? 0 : next.neurons.length;
- for (int i = 0; i < neurons.length; i++) {
- neurons[i] = new Neuron(n, m);
- for (int j = 0; j < n; j++)
- neurons[i].addInput(previous.neurons[j]);
- }
- }
- public int getSize ()
- {
- return neurons.length;
- }
- public Neuron getNeuron (int i)
- {
- return neurons[i];
- }
- }
- public class Neuron
- {
- private Axon[] inputs;
- private Axon[] outputs;
- private double input;
- private double output;
- private double delta;
- public Neuron () // dummy constructor
- {
- inputs = new Axon[0];
- outputs = new Axon[1];
- input = 1.0;
- output = 1.0;
- delta = 0.0;
- }
- public Neuron (int n, int m)
- {
- this();
- n += 1; // add the dummy input
- inputs = new Axon[n];
- outputs = new Axon[m];
- Neuron dummy = new Neuron();
- addInput(dummy);
- }
- private void append (Axon[] arr, Axon a)
- {
- int i = 0;
- while (i < arr.length && arr[i] != null)
- i++;
- if (i < arr.length)
- arr[i] = a;
- }
- private void addOutput (Axon a)
- {
- append(outputs, a);
- }
- public void addInput (Neuron n)
- {
- Axon a = new Axon(n, this);
- append(inputs, a);
- n.addOutput(a);
- }
- public double getInput ()
- {
- return input;
- }
- public void setInput (double in)
- {
- input = in;
- }
- public double getOutput ()
- {
- return output;
- }
- public void setOutput (double out)
- {
- output = out;
- }
- public double getDelta ()
- {
- return delta;
- }
- public void setDelta (double newDelta)
- {
- delta = newDelta;
- }
- public int numInputs ()
- {
- return inputs.length;
- }
- public int numOutputs ()
- {
- return outputs.length;
- }
- public Axon getInput (int i)
- {
- return inputs[i];
- }
- public Axon getOutput (int i)
- {
- return outputs[i];
- }
- }
- public class Axon
- {
- private double weight;
- private Neuron start;
- private Neuron end;
- public Axon (Neuron s, Neuron e)
- {
- start = s;
- end = e;
- weight = 2.0 * Math.random() - 1.0; // random initial weight between -1 and 1
- }
- public Neuron getStart ()
- {
- return start;
- }
- public Neuron getEnd ()
- {
- return end;
- }
- public double getWeight ()
- {
- return weight;
- }
- public void modifyWeight (double x)
- {
- weight += x;
- }
- }
- public class Example
- {
- double[] inputs;
- double[] outputs;
- public Example (double[] in, double[] out)
- {
- inputs = in;
- outputs = out;
- }
- public double getInput (int i)
- {
- return inputs[i];
- }
- public double getOutput (int i)
- {
- return outputs[i];
- }
- public int numInputs ()
- {
- return inputs.length;
- }
- public int numOutputs ()
- {
- return outputs.length;
- }
- }
Add Comment
Please, Sign In to add comment