- Home /
i am having problems with my neural network (made from scratch),I am creating a neural network, however, whenever i start it. it crashes
i am creating a simple ai where the bots try to rotate themselves to look at a target, and it always moves forward.
i have made the script stop giving me errors, but now when i try running it. it crashes unity and no longer works. here are the scripts:
the neural network has all the functions to improve itself (randomly, or unsupervised learning)
using System;
using System.Collections.Generic;
using UnityEngine;
public class NeuralNetwork : MonoBehaviour, IComparable<NeuralNetwork>
{
int[] layers;
float[][] neurons;
float[][][] weights;
float fitness; // fitness is the measure of how well the ai did
public void NeuralNetworkConstructor (int[] layers)
{
this.layers = new int[layers.Length];
for (int i = 0; i < layers.Length; i++)
{
this.layers[i] = layers[i];
}
InitNeurons();
InitWeights();
}
public void CopyWeights (float[][][] copyWeights)
{
for (int i = 0; i < weights.Length; i++) // iterator
{
for (int j = 0; j < weights[i].Length; j++)
{
for (int k = 0; k < weights[i][k].Length; k++)
{
weights[i][j][k] = copyWeights[i][j][k];
// Setting weights to the copy weights
}
}
}
}
public void NeuralNetworkConstructor (NeuralNetwork copyNetwork)
{
layers = copyNetwork.layers;
neurons = copyNetwork.neurons;
weights = copyNetwork.weights;
}
void InitNeurons ()
{
// Neuron Initialization
List<float[]> neuronsList = new List<float[]>();
for (int i = 0; i < layers.Length; i++) //run through all layers
{
neuronsList.Add(new float[layers[i]]); //convert list to array
}
neurons = neuronsList.ToArray();
}
void InitWeights ()
{
List<float[][]> weightsList = new List<float[][]>();
for (int i = 1; i < layers.Length; i++)
{
List<float[]> layerWeightList = new List<float[]>();
int neuronsInPreviousLyaer = layers[i - 1];
for (int j = 0; j < neurons[i].Length; j++)
{
float[] neuronWeights = new float[neuronsInPreviousLyaer]; //neurons weights
for (int k = 0; k < neuronsInPreviousLyaer; k++)
{
// Give random weights to neuron weights
neuronWeights[k] = UnityEngine.Random.Range(-.5f, .5f);
}
layerWeightList.Add(neuronWeights);
}
weightsList.Add(layerWeightList.ToArray());
}
weights = weightsList.ToArray();
}
public float[] FeedForward (float[] inputs) // Giving the neural network the inputs
{
for (int i = 0; i < inputs.Length; i++)
{
neurons[0][i] = inputs[i];
}
for (int i = 1; i < layers.Length; i++)
{
for (int j = 0; j < neurons[i].Length; j++)
{
float value = .25f;
for (int k = 0; k < neurons[i - 1].Length; k++)
{
value += weights[i - 1][j][k] * neurons[i - 1][k];
}
neurons[i][j] = (float)Math.Tanh(value);
}
}
return neurons[neurons.Length - 1];
}
public void Mutate () // Changes neuron values around randomly
{
for (int i = 0; i < weights.Length; i++) // Iterator
{
for (int j = 0; j < weights[i].Length; j++)
{
for (int k = 0; k < weights[i][j].Length; k++)
{
float weight = weights[i][j][k];
//mutate weight value
// random number
int rand = UnityEngine.Random.Range(0, 4);
if (rand == 1)
weight = -weight; //flip the sign of the weight
else if (rand == 2)
weight = UnityEngine.Random.Range(-.5f, .5f); //make it a new random number
else if (rand == 3)
{
//increase by 0% to 100%
float factor = UnityEngine.Random.value + 1;
weight *= factor;
}
else if (rand == 4)
{
//decrease by 0% to 100%
float factor = UnityEngine.Random.value;
weight *= factor;
}
weights[i][j][k] = weight;
}
}
}
}
#region fitness // commands to change the fitness
public void AddFitness (float val)
{
fitness += val;
}
public void SetFitness (float val)
{
fitness = val;
}
public float GetFitness ()
{
return fitness;
}
#endregion
public int CompareTo (NeuralNetwork other)
{
if (fitness > other.fitness)
return 1;
else if (fitness == other.fitness)
return 0;
else if (fitness < other.fitness)
return -1;
else
return 0;
}
}
the manager is responsible for placing the ai in the first place, and actually making them cycle, keeping the best half only
using System.Collections.Generic;
using UnityEngine;
public class Manager : MonoBehaviour
{
public float timeToLetTrain;
public int numberOfAiToSpawn;
List<GameObject> ai;
public GameObject aiPrefab;
bool isTraining;
private void Start ()
{
ai = new List<GameObject>();
CreateObject(numberOfAiToSpawn);
}
private void CreateObject (int amount)
{
for (int i = 0; i < amount; i++)
{
// Create GameObject For Ai
GameObject g = (GameObject)Instantiate(aiPrefab);
ai.Add(g);
// Create New Ai
int[] x = new int[3];
x[0] = 5;
x[1] = 4;
x[2] = 1;
NeuralNetwork n = g.GetComponent<NeuralNetwork>();
n.NeuralNetworkConstructor(x);
}
}
private void Update ()
{
if (!isTraining)
StartTraining(); // Starts training right as timer is done
}
void StartTraining ()
{
Invoke(nameof(EndTraining), timeToLetTrain);
isTraining = true; // Tells the computer that we've started training
}
void EndTraining ()
{
Debug.Log("Ending training...");
isTraining = false;
ai = Sort(); // Sorts the neural networks by ascending order in which is best
// Makes the sorting descending order
// Making duplicates of the best half
List<GameObject> bestHalf = GetBestHalf(); // Gets best half
DeleteBadVersions(bestHalf); // Delete bad half
CreateMutatedVersions(); // Creates and mutates the best half
ResetPositions(); // Resets positions for a controlled variable
}
private void ResetPositions ()
{
foreach (GameObject g in ai)
{
Transform t = g.transform;
t.position = Vector2.zero;
Rigidbody2D rb = g.GetComponent<Rigidbody2D>();
rb.angularVelocity = 0;
rb.velocity = Vector2.zero;
}
}
private void DeleteBadVersions (List<GameObject> whatToKeep)
{
ai.Clear();
ai = whatToKeep; // MAYBE CORRECT THIS ERROR BUG
Debug.LogWarning("this might be a bug, not sure tho. this message is just for future reference");
}
List<GameObject> Sort ()
{
List<GameObject> val = new List<GameObject>();
List<NeuralNetwork> x = new List<NeuralNetwork>();
for (int i = 0; i < ai.Count; i++)
{
NeuralNetwork networkToAdd = ai[i].GetComponent<NeuralNetwork>(); // Gets the neural network for each gameobject
x.Add(networkToAdd); // Assigns it to the temporary list
}
x.Sort();
for (int i = 0; i < x.Count; i++)
val.Add(x[i].gameObject);
return val;
}
List<GameObject> GetBestHalf ()
{
List<GameObject> val = new List<GameObject>();
for (int i = 0; i < ai.Count / 2; i++)
{
val.Add(ai[i]);
Debug.Log(ai[i]);
}
return val;
}
void CreateMutatedVersions ()
{
for (int i = 0; i < ai.Count; i++)
{
Debug.Log("Total Loops: " + i);
GameObject g = Instantiate(ai[i]);
ai.Add(g);
NeuralNetwork n = g.GetComponent<NeuralNetwork>();
n.NeuralNetworkConstructor(ai[i].GetComponent<NeuralNetwork>());
n.Mutate();
}
}
}
the follow script is attached to the ai and is supposed to make it move
using UnityEngine;
public class Follow : MonoBehaviour
{
public NeuralNetwork n;
Rigidbody2D rb;
GameObject target;
private void Awake ()
{
rb = GetComponent<Rigidbody2D>();
target = GameObject.FindGameObjectWithTag("Player");
}
private void FixedUpdate ()
{
rb.velocity = new Vector2(0, -1);
GiveFitnessPoints();
float[] inputs = new float[5];
inputs[0] = rb.angularVelocity;
inputs[1] = target.transform.position.x;
inputs[2] = target.transform.position.y;
inputs[3] = transform.position.x;
inputs[4] = transform.position.y;
float[] output = n.FeedForward(inputs);
rb.angularVelocity = output[0];
}
void GiveFitnessPoints ()
{
float distance = Vector2.Distance(transform.position, target.transform.position);
float points = ( -distance / 10 ) + 100;
n.SetFitness(points);
}
}
Your answer
Follow this Question
Related Questions
Properties of Artificail Intellegence in Unity Game Engine 0 Answers
Light detecting + Light lowers variable 2 Answers
AI Player Jerky Movement - Overcoming Obstacle 0 Answers
How do I make an Active 3D AI Ragdoll like in this video? 1 Answer
Unity2D Check which direction the enemy AI is heading? 1 Answer