public Agent(FeedForwardNN brain, Player player, Transform rightGoalTransform) { Brain = brain; Player = player; Player.rightGoalTransform = rightGoalTransform; BallInitialPosition = Player.ballInitialPosition; RightGoalPosition = rightGoalTransform.position; fitness = Mathf.NegativeInfinity; }
public FeedForwardNN reLu2; // 1 FFNN(arbitrary number of hidden layers) at the end public AttentiveBrain(FeedForwardNN[,] linears, FeedForwardNN linear, FeedForwardNN reLu1, FeedForwardNN reLu2) { Debug.Assert(linears.GetLength(1) == 3); Debug.Assert(linear.Layers.GetLength(0) == 2); this.linears = linears; this.linear = linear; this.reLu1 = reLu1; this.reLu2 = reLu2; }
private void Player_OnInput(object sender, double[] inputs) { if (!IsActive) { return; } Vector <double> .Build.DenseOfArray(inputs); Player.ApplyOutput(FeedForwardNN.FeedForward(Brain, Vector <double> .Build.DenseOfArray(inputs)).AsArray()); CalculateFitness(); //Debug.Log(fitness); }
// We want to reuse this object instead of creating new ones each generation. public void Reset(Vector2 playerPos, bool resetFitness = false, FeedForwardNN brain = null) { Brain = brain ?? Brain; fitness = resetFitness ? Mathf.NegativeInfinity : fitness; hasMaxFitness = false; shotTheBall = false; shotTheBallRewarded = false; fitnessCanIncrease = false; touchedRightGoal = false; touchingRightGoal = false; touchedBall = false; touchingCorner = false; Player.Reset(playerPos); BallInitialPosition = Player.ballInitialPosition; }
// private static FeedForwardNN crossover(FeedForwardNN[] parents) // { // var newBrain = new FeedForwardNN(parents[0].Layers); // for (int l = 0; l < parents[0].Weights.Length; l++) // { // for (int n = 0; n < parents[0].Weights[l].GetLength(0); n++) // { // int parentIndex = random.Next(parents.Length); // for (int w = 0; w < parents[0].Weights[l].GetLength(1); w++) // { // Debug.Log(parentIndex); // newBrain.Weights[l][n, w] = random.NextDouble() > mutationRate ? FeedForwardNN.GetRandomWeight : parents[parentIndex].Weights[l][n, w]; // } // newBrain.Biases[l][n] = random.NextDouble() > mutationRate ? FeedForwardNN.GetRandomBias : parents[parentIndex].Biases[l][n]; // } // } // return newBrain; // } private static FeedForwardNN mutate(FeedForwardNN brain) { var random = new Random(); //return brain; var newBrain = new FeedForwardNN(brain.Layers); for (int l = 1; l < brain.Layers.Length; l++) { for (int n = 0; n < brain.Layers[l].NodeCount; n++) { for (int w = 0; w < brain.Layers[l].Weights.ColumnCount; w++) { var mutBy = mutationRate * (random.NextDouble() - 0.5) * 2; newBrain.Layers[l].Weights[n, w] = brain.Layers[l].Weights[n, w] * mutBy; } var mutByBias = mutationRate * (random.NextDouble() - 0.5) * 0.5; newBrain.Layers[l].Biases[n] = brain.Layers[l].Biases[n] * mutByBias; } } return(newBrain); }
private void CreateNewGeneration() { trainingNo = 0; MinFitness = Mathf.Infinity; MaxFitness = Mathf.NegativeInfinity; // Turn negative infinities to min fitness in the generation so we can calculate. var minGenFitness = currentGeneration.Where(a => a.fitness != Mathf.NegativeInfinity).Min(a => a.fitness); // currentGeneration.ForEach(a => a.fitness = a.fitness == Mathf.NegativeInfinity ? minGenFitness - 1000 : a.fitness); var orderedByFitness = currentGeneration.OrderByDescending(a => a.fitness); // var listt = orderedByFitness.ToList(); // just to debug var selectedAgents = orderedByFitness.Take((int)Math.Floor(currentGeneration.Count * 0.4f)).ToList(); //SampleAgent.Brain = selectedAgents[0].Brain; // Get the elite to the list first int eliteCount = (int)Math.Floor(selectedAgents.Count * eliteRatio); // And new comers int newAgentsCount = (int)Math.Floor(selectedAgents.Count * newAgentsRatio); var newGenerationBrains = new List <FeedForwardNN>(); for (int g = 0; g < eliteCount; g++) { newGenerationBrains.Add(selectedAgents[g].Brain); } for (int n = 0; n < newAgentsCount; n++) { newGenerationBrains.Add(new FeedForwardNN(layerDefinitions)); } var remainingCount = (float)population - eliteCount - newAgentsCount; var countOfBestAgent = (remainingCount / selectedAgents.Count * 2 - 1); float selectiveRatio = countOfBestAgent / remainingCount; // for linear distribution for (int s = 0; s < selectedAgents.Count; s++) { int agentCount = Mathf.CeilToInt(selectiveRatio * (selectedAgents.Count - s)); for (int a = 0; a < agentCount; a++) { var parent1 = selectedAgents[s].Brain; //var parent2 = SelectRandomlyByFitness(fitnessSum, minFitness); FeedForwardNN childBrain = mutate(parent1); newGenerationBrains.Add(childBrain); } } for (int v = 0; v < newGenerationBrains.Count - currentGeneration.Count; v++) { currentGeneration.Add(new Agent(new FeedForwardNN(layerDefinitions), Instantiate(PlayerPrefab), RightGoalTransform)); } for (int b = 0; b < newGenerationBrains.Count; b++) { currentGeneration[b].Brain = newGenerationBrains[b]; } generationNo++; TxtGeneration.text = generationNo.ToString(); TxtPopulation.text = currentGeneration.Count.ToString(); }
public static Vector <double> FeedForward(FeedForwardNN nn, Vector <double> inputs) { return(FeedForward(inputs, nn.Layers, 1)); }