i am new to programming and especialy at programming ai. I am sorry if the problem is stupid or easy to fix. I have created a primitive flappy bird game with neural network to controll it. Every thing goes ok until all the birds die. After all birds die i am choosing the best bird, create Array of new population , set the new birds "brain" to equal to the best bird "brain", and finally i am mutate all the new population birds brain a tiny so they are not be the same. I tried to mutate using probability, mutate all the weights of new birds brain, set if statement so weights doesnt go below 1.0 or under -1.0. The result is the same , all the birds at the next generation (second) act like they are having the same "brain". Here are some code that i think is worth to check. I can place all the code but it is big.
Repopulation
for (int i = 0; i < population; i++) {
birds.add(new Bird());
birds.get(i).brain=lastbird.brain;
birds.get(i).brain.mutate(0.1);
}
Mutation function
public void mutate(double eta) {
Random dice = new Random();
for (int layer = 1; layer < NETWORK_SIZE; layer++) {
for (int neuron = 0; neuron < NETWORK_LAYER_SIZES[layer]; neuron++) {
if (dice.nextDouble() < eta) {
bias[layer][neuron] += dice.nextGaussian()/2;
}
for (int prevNeuron = 0; prevNeuron < NETWORK_LAYER_SIZES[layer - 1]; prevNeuron++) {
if (dice.nextDouble() < eta) {
weights[layer][neuron][prevNeuron] += dice.nextGaussian()/2;
}
}
}
}
}
Network(brain) veriables and constructor
public class Network {
private double[][] output;
private double[][][] weights;
private double[][] bias;
private double[][] error_signal;
private double[][] output_derivative;
public final int[] NETWORK_LAYER_SIZES;
public final int INPUT_SIZE;
public final int OUTPUT_SIZE;
public final int NETWORK_SIZE;
public Network(int... NETWORK_LAYER_SIZES) {
this.NETWORK_LAYER_SIZES = NETWORK_LAYER_SIZES;
this.INPUT_SIZE = NETWORK_LAYER_SIZES[0];
this.NETWORK_SIZE = NETWORK_LAYER_SIZES.length;
this.OUTPUT_SIZE = NETWORK_LAYER_SIZES[NETWORK_SIZE - 1];
this.output = new double[NETWORK_SIZE][];
this.weights = new double[NETWORK_SIZE][][];
this.bias = new double[NETWORK_SIZE][];
this.error_signal = new double[NETWORK_SIZE][];
this.output_derivative = new double[NETWORK_SIZE][];
for (int i = 0; i < NETWORK_SIZE; i++) {
this.output[i] = new double[NETWORK_LAYER_SIZES[i]];
this.error_signal[i] = new double[NETWORK_LAYER_SIZES[i]];
this.output_derivative[i] = new double[NETWORK_LAYER_SIZES[i]];
this.bias[i] = NetworkTools.createRandomArray(NETWORK_LAYER_SIZES[i], -0.5, 0.7);
if (i > 0) {
weights[i] = NetworkTools.createRandomArray(NETWORK_LAYER_SIZES[i], NETWORK_LAYER_SIZES[i - 1], -1, 1);
}
}
}