/// <summary> /// Construct a NEAT link. /// </summary> /// <param name="weight">The weight between the two neurons.</param> /// <param name="fromNeuron">The source neuron.</param> /// <param name="toNeuron">The target neuron.</param> /// <param name="recurrent">Is this a recurrent link.</param> public NEATLink(double weight, NEATNeuron fromNeuron, NEATNeuron toNeuron, bool recurrent) { this.weight = weight; this.fromNeuron = fromNeuron; this.toNeuron = toNeuron; this.recurrent = recurrent; }
/// <summary> /// Convert the genes to an actual network. /// </summary> public override void Decode() { NEATPattern pattern = new NEATPattern(); IList<NEATNeuron> neurons = pattern.Neurons; foreach (IGene gene in Neurons.Genes) { NEATNeuronGene neuronGene = (NEATNeuronGene)gene; NEATNeuron neuron = new NEATNeuron( neuronGene.NeuronType, neuronGene.Id, neuronGene .SplitY, neuronGene.SplitX, neuronGene .ActivationResponse); neurons.Add(neuron); } // now to create the links. foreach (IGene gene in Links.Genes) { NEATLinkGene linkGene = (NEATLinkGene)gene; if (linkGene.Enabled) { int element = GetElementPos(linkGene.FromNeuronID); NEATNeuron fromNeuron = neurons[element]; element = GetElementPos(linkGene.ToNeuronID); NEATNeuron toNeuron = neurons[element]; NEATLink link = new NEATLink(linkGene.Weight, fromNeuron, toNeuron, linkGene.IsRecurrent); fromNeuron.OutputboundLinks.Add(link); toNeuron.InboundLinks.Add(link); } } pattern.NEATActivation = (((NEATTraining)GA).NeatActivationFunction); pattern.ActivationFunction = (((NEATTraining)GA).OutputActivationFunction); pattern.InputNeurons = (inputCount); pattern.OutputNeurons = (outputCount); pattern.Snapshot = ((NEATTraining)GA).Snapshot; Organism = pattern.Generate(); }
/// <summary> /// Compute the output from this synapse. /// </summary> /// <param name="input">The input to this synapse.</param> /// <returns>The output from this synapse.</returns> public INeuralData Compute(INeuralData input) { INeuralData result = new BasicNeuralData(ToNeuronCount); if (this.neurons.Count == 0) { throw new NeuralNetworkError("This network has not been evolved yet, it has no neurons in the NEAT synapse."); } int flushCount = 1; if (snapshot) { flushCount = networkDepth; } // iterate through the network FlushCount times for (int i = 0; i < flushCount; ++i) { int outputIndex = 0; int index = 0; result.Clear(); // populate the input neurons while (neurons[index].NeuronType == NEATNeuronType.Input) { neurons[index].Output = input[index]; index++; } // set the bias neuron neurons[index++].Output = 1; while (index < neurons.Count) { NEATNeuron currentNeuron = neurons[index]; double sum = 0; foreach (NEATLink link in currentNeuron.InboundLinks) { double weight = link.Weight; double neuronOutput = link.FromNeuron.Output; sum += weight * neuronOutput; } double[] d = new double[1]; d[0] = sum / currentNeuron.ActivationResponse; activationFunction.ActivationFunction(d, 0, 1); neurons[index].Output = d[0]; if (currentNeuron.NeuronType == NEATNeuronType.Output) { result.Data[outputIndex++] = currentNeuron.Output; } index++; } } return(result); }