From c37675d7b3f6ffe142fe7498a5627c2dbdad752a Mon Sep 17 00:00:00 2001 From: Enrico Fasoli Date: Sat, 8 Aug 2015 13:06:59 +0200 Subject: [PATCH] added some groundwork for recurrent neural networks --- core/src/logic/World.java | 2 ++ core/src/logic/neural/Brain.java | 10 +++++----- core/src/logic/neural/Neuron.java | 31 +++++++++++++++++++++---------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/core/src/logic/World.java b/core/src/logic/World.java index 90e32a4..61f9a67 100644 --- a/core/src/logic/World.java +++ b/core/src/logic/World.java @@ -241,6 +241,8 @@ public class World implements Runnable { n = top[first].getBrain().breed(top[sec].getBrain().getMap()); } catch (Exception ex) { // Should not happen + Log.log(Log.ERROR, "Could not breed: " + ex.getMessage() + + "\nIt is advised to restart the simulation after changing the brain's topology"); Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); } Creature ne = spawnCreature(n); diff --git a/core/src/logic/neural/Brain.java b/core/src/logic/neural/Brain.java index b4ef973..000b28f 100644 --- a/core/src/logic/neural/Brain.java +++ b/core/src/logic/neural/Brain.java @@ -46,7 +46,7 @@ public class Brain { for (int j = 0; j < brainMap[i].length; j++) { // for each neuron // skip input layer if (neurons[i + 1][j] == null) { - neurons[i + 1][j] = new Neuron(j, bias, this, brainMap[i][j]); + neurons[i + 1][j] = new Neuron(i + 1, i, bias, this, brainMap[i][j]); } else { neurons[i + 1][j].setWeights(brainMap[i][j]); } @@ -63,7 +63,7 @@ public class Brain { for (int i = 0; i < neurons.length; i++) { for (int j = 0; j < neurons[i].length; j++) { // create neuron - Neuron n = new Neuron(i, bias, this); + Neuron n = new Neuron(i, i - 1, bias, this); neurons[i][j] = n; Log.log(Log.DEBUG, "Adding Layer " + (i + 1) + " Neuron " + (j + 1)); } @@ -269,10 +269,10 @@ public class Brain { } } - private void recomputeName(){ + private void recomputeName() { name = Serializer.nameBrain(getMap()); } - + /** * Returns an array with pointers to all this brain's neurons. * @@ -285,5 +285,5 @@ public class Brain { public String getName() { return name; } - + } diff --git a/core/src/logic/neural/Neuron.java b/core/src/logic/neural/Neuron.java index e56c204..6ec13b9 100644 --- a/core/src/logic/neural/Neuron.java +++ b/core/src/logic/neural/Neuron.java @@ -15,7 +15,7 @@ public class Neuron { private NeuronCache cache; private float bias, output; private boolean isInputNeuron; - private int layer; + private int layer, receivesFromLayer; private Brain brain; /** @@ -24,10 +24,12 @@ public class Neuron { * * @param layer the layer in which this neuron is positioned * @param bias the bias of this neuron + * @param receivesFromLayer the layer to read data from (negative for input + * neurons) * @param brain the brain which contains this neuron */ - public Neuron(int layer, float bias, Brain brain) { - this(layer, bias, brain, null); + public Neuron(int layer, int receivesFromLayer, float bias, Brain brain) { + this(layer, receivesFromLayer, bias, brain, null); } /** @@ -35,19 +37,26 @@ public class Neuron { * being the input layer, with given weights * * @param layer the layer in which this neuron is positioned + * @param receivesFromLayer the layer to read data from (negative for input + * neurons) * @param bias the bias of this neuron * @param brain the brain which contains this neuron * @param weights the weights to use to configure this neuron */ - public Neuron(int layer, float bias, Brain brain, float[] weights) { + public Neuron(int layer, int receivesFromLayer, float bias, Brain brain, float[] weights) { this.brain = brain; this.layer = layer; - if (weights == null) { + this.receivesFromLayer = receivesFromLayer; + if (receivesFromLayer < 0 || layer == 0) { + isInputNeuron = true; + } else if (weights == null) { scramble(); } else { this.weights = weights; } - cache = new NeuronCache(this.weights.length); + if (!isInputNeuron) { + cache = new NeuronCache(this.weights.length); + } } /** @@ -56,8 +65,8 @@ public class Neuron { private void scramble() { // init weights if (layer > 0) { - weights = new float[brain.getNeurons()[layer - 1].length]; - } else { // layer 0 + weights = new float[brain.getNeurons()[receivesFromLayer].length]; + } else { // layer 0 or negative isInputNeuron = true; weights = new float[0]; } @@ -76,7 +85,9 @@ public class Neuron { * @return the output of this neuron. */ public float compute() { - if(weights == null || weights.length == 0) isInputNeuron = true; + if (weights == null || weights.length == 0) { + isInputNeuron = true; + } if (isInputNeuron) { return output; } @@ -93,7 +104,7 @@ public class Neuron { Logger.getLogger(Neuron.class.getName()).log(Level.SEVERE, null, ex); } } else { - Neuron n = brain.getNeurons()[layer - 1][i]; + Neuron n = brain.getNeurons()[receivesFromLayer][i]; float v = n.compute() * weights[i]; a += v; cache.put(i, v);