public void NodeMutate(double MutationProbability = 0.1, double MutationAmount = 2.0) { if (MutationProbability < 0 || MutationProbability > 1) { throw new ArgumentException("A probability must be a value between 0 and 1.", "MutationProbablity"); } else if (MutationAmount <= 0) { throw new ArgumentException("The mutation amount must be greater than 0.", "MutationAmount"); } for (int i = 0; i < AllNeurons.Count; i++) { foreach (NeatConnection aNeatConnection in (AllNeurons[i] as NeatNeuron).IncomingConnections) { if (aNeatConnection.Enabled && TheRandomizer.NextDouble() < MutationProbability) { int NewNeuronIndex = i; if (NewNeuronIndex > TotalNeuronCount - OutputNeuronCount) { NewNeuronIndex = TotalNeuronCount - OutputNeuronCount; } NeatNeuron NewNeuron = InsertNeuron(NewNeuronIndex); NewNeuron.IncomingConnections.Add(new NeatConnection(TheRandomizer.NextDouble() * (MutationAmount * 2) - MutationAmount, aNeatConnection.OtherNeuronKey)); aNeatConnection.OtherNeuronKey = NewNeuron.Key; } } } }
public void CalculateGpuArrays(List <NeatGpuDimensions> Dimensions, List <NeatGpuIndicies> Indicies, List <NeatGpuConnection> Connections, int BufferInputNeuronIndex, ref int BufferNeuronValuesIndex, ref int BufferOutputNeuronIndex, ref int BufferTotalNeuronCount, ref int BufferOutputNeuronCount) { //Indicies.Add(new NeatGpuIndicies()); Indicies.Add(new NeatGpuIndicies(Connections.Count, BufferInputNeuronIndex, BufferNeuronValuesIndex, BufferOutputNeuronIndex)); int ConnectionsCount = 0; for (int i = InputNeuronCount + 1; i < AllNeurons.Count; i++) { NeatNeuron CurrentNeuron = AllNeurons[i] as NeatNeuron; foreach (NeatConnection aNeatConnection in CurrentNeuron.IncomingConnections) { if (aNeatConnection.Enabled) { Connections.Add(new NeatGpuConnection((int)aNeatConnection.OtherNeuronKey, (int)CurrentNeuron.Key, aNeatConnection.Weight)); ConnectionsCount++; } } } Dimensions.Add(new NeatGpuDimensions(InputNeuronCount, OutputNeuronCount, TotalNeuronCount, ConnectionsCount)); BufferNeuronValuesIndex += TotalNeuronCount; BufferOutputNeuronIndex += OutputNeuronCount; BufferTotalNeuronCount += TotalNeuronCount; BufferOutputNeuronCount += OutputNeuronCount; }
public void AddConnectionMutate(double MutationAmount = 2.0) { if (MutationAmount <= 0) { throw new ArgumentException("A the mutation amount must be greater than 0.", "MutationAmount"); } int FirstNeuronIndex = TheRandomizer.Next(AllNeurons.Count - OutputNeuronCount); int SecondNeuronIndex = FirstNeuronIndex; while (FirstNeuronIndex == SecondNeuronIndex) { SecondNeuronIndex = TheRandomizer.Next(InputNeuronCount + 1, AllNeurons.Count); } if (FirstNeuronIndex > SecondNeuronIndex) { int Tmp = SecondNeuronIndex; SecondNeuronIndex = FirstNeuronIndex; FirstNeuronIndex = Tmp; } NeatNeuron FirstNeuron = AllNeurons[FirstNeuronIndex] as NeatNeuron; NeatNeuron SecondNeuron = AllNeurons[SecondNeuronIndex] as NeatNeuron; foreach (NeatConnection aNeatConnection in SecondNeuron.IncomingConnections) { if (aNeatConnection.OtherNeuronKey == FirstNeuron.Key) { return; } } SecondNeuron.IncomingConnections.Add(new NeatConnection(TheRandomizer.NextDouble() * (MutationAmount * 2) - MutationAmount, FirstNeuron.Key)); }
private NeatNeuron InsertNeuron(int index, NeatNeuronType TheNeuronType = NeatNeuronType.Hidden) { NeatNeuron NewNeuron = new NeatNeuron((uint)AllNeurons.Count, TheNeuronType); AllNeurons.Insert(index, (uint)AllNeurons.Count, NewNeuron); return(NewNeuron); }
private NeatNeuron AddNeuron(NeatNeuronType TheNeuronType = NeatNeuronType.Hidden) { NeatNeuron NewNeuron = new NeatNeuron((uint)AllNeurons.Count, TheNeuronType); AllNeurons.Add((uint)AllNeurons.Count, NewNeuron); return(NewNeuron); }
public void Serialize(Stream TheStream) { using (BinaryWriter TheBinaryWriter = new BinaryWriter(TheStream)) { TheBinaryWriter.Write(InputNeuronCount); TheBinaryWriter.Write(OutputNeuronCount); TheBinaryWriter.Write(TopAncestorSeed); TheBinaryWriter.Write(TheRandomizer.Next()); TheBinaryWriter.Write(AllNeurons.Count); foreach (DictionaryEntry aDictionaryEntry in AllNeurons) { TheBinaryWriter.Write((uint)aDictionaryEntry.Key); NeatNeuron TheNeuron = aDictionaryEntry.Value as NeatNeuron; TheBinaryWriter.Write((int)TheNeuron.TheNeuronType); TheBinaryWriter.Write(TheNeuron.IncomingConnections.Count); foreach (NeatConnection aNeatConnection in TheNeuron.IncomingConnections) { TheBinaryWriter.Write(aNeatConnection.Weight); TheBinaryWriter.Write(aNeatConnection.OtherNeuronKey); TheBinaryWriter.Write(aNeatConnection.Enabled); } } } }
public NeatNeuralNetwork(Stream TheStream) { using (BinaryReader TheBinaryReader = new BinaryReader(TheStream)) { InputNeuronCount = TheBinaryReader.ReadInt32(); OutputNeuronCount = TheBinaryReader.ReadInt32(); AllNeurons = new OrderedDictionary(InputNeuronCount + OutputNeuronCount + 1); TopAncestorSeed = TheBinaryReader.ReadInt32(); TheRandomizer = new System.Random(TheBinaryReader.ReadInt32()); int AllNeuronsCount = TheBinaryReader.ReadInt32(); for (int i = 0; i < AllNeuronsCount; i++) { uint Key = TheBinaryReader.ReadUInt32(); NeatNeuronType TheNeuronType = (NeatNeuronType)TheBinaryReader.ReadInt32(); NeatNeuron TheNeuron = new NeatNeuron(Key, TheNeuronType); int IncomingConnectionsCount = TheBinaryReader.ReadInt32(); for (int j = 0; j < IncomingConnectionsCount; j++) { double TheWeight = TheBinaryReader.ReadDouble(); uint OtherNeuronKey = TheBinaryReader.ReadUInt32(); bool Enabled = TheBinaryReader.ReadBoolean(); TheNeuron.IncomingConnections.Add(new NeatConnection(TheWeight, OtherNeuronKey, Enabled)); } AllNeurons.Add(Key, TheNeuron); } } }
public NeatNeuron(NeatNeuron Main) { this.Key = Main.Key; this.Value = Main.Value; foreach (NeatConnection aNeatConnection in Main.IncomingConnections) { this.IncomingConnections.Add(new NeatConnection(aNeatConnection)); } this.TheNeuronType = Main.TheNeuronType; }
public double[] FeedForward(double[] Input) { // Validation Checks if (Input == null) { throw new ArgumentException("The input array cannot be set to null.", "Input"); } else if (Input.Length != InputNeuronCount) { throw new ArgumentException("The input array's length does not match the number of neurons in the input layer.", "Input"); } double[] Result = new double[OutputNeuronCount]; for (int i = 0; i < InputNeuronCount; i++) { (AllNeurons[i] as NeatNeuron).Value = (Input[i]); } (AllNeurons[InputNeuronCount] as NeatNeuron).Value = 1; for (int i = InputNeuronCount + 1; i < AllNeurons.Count; i++) { NeatNeuron CurrentNeuron = AllNeurons[i] as NeatNeuron; CurrentNeuron.Value = 0; foreach (NeatConnection aNeatConnection in CurrentNeuron.IncomingConnections) { if (aNeatConnection.Enabled) { CurrentNeuron.Value += aNeatConnection.Weight * ((AllNeurons[aNeatConnection.OtherNeuronKey] as NeatNeuron).Value); } } CurrentNeuron.Value = ReLU(CurrentNeuron.Value); } for (int i = 0; i < OutputNeuronCount; i++) { Result[i] = ReLU((AllNeurons[i + AllNeurons.Count - OutputNeuronCount] as NeatNeuron).Value); } return(Result); }