public Neuron[] LoadNeuronsFromLayerIndex(IReadOnlyNeuronLayer neuronLayer, uint index) { // Get the neuron layer node from the index. XmlNode neuronLayerNode = loadedFile.SelectSingleNode($"{MainNodeName}/{NeuronLayerNodeName}[@{IndexAttributeName}={index}]"); // Get the neuron nodes from the layer node. XmlNodeList neuronNodes = neuronLayerNode.SelectNodes(NeuronNodeName); // Create an array of neurons to fill the layer. Neuron[] neurons = new Neuron[neuronNodes.Count]; // Create and add each neuron to the array. for (uint i = 0; i < neurons.Length; i++) { // The neuron node. XmlNode currentNeuronNode = neuronNodes[(int)i]; // Parse the bias. if (!(currentNeuronNode.Attributes.GetNamedItem(BiasAttributeName) is XmlNode biasAttributeNode) || !float.TryParse(biasAttributeNode.Value, out float bias)) { throw new Exception($"Neuron's bias attribute was missing or incorrect. Layer index {neuronLayer.Index}, neuron index {i}."); } // Create the neuron. neurons[i] = new Neuron(neuronLayer, bias, i); } // Return the neuron array. return(neurons); }
public void SaveNeuronLayer(IReadOnlyNeuronLayer neuronLayer) { // Create a new neuron layer node. XmlNode neuronLayerNode = saveFile.CreateElement(NeuronLayerNodeName); // Add the index attribute. neuronLayerNode.Attributes.Append(createAttributeWithValue(saveFile, IndexAttributeName, neuronLayer.Index)); // Add each neuron to the neuron layer. for (uint i = 0; i < neuronLayer.Count; i++) { // Create a new neuron node. XmlNode neuronNode = saveFile.CreateElement(NeuronNodeName); // Create the bias and index attributes. neuronNode.Attributes.Append(createAttributeWithValue(saveFile, IndexAttributeName, neuronLayer[i].Index)); neuronNode.Attributes.Append(createAttributeWithValue(saveFile, BiasAttributeName, neuronLayer[i].Bias)); // Append the neuron node to the neuron layer node. neuronLayerNode.AppendChild(neuronNode); } // Append the neuron layer to the main node. saveFile.SelectSingleNode(MainNodeName).AppendChild(neuronLayerNode); }
/// <summary> Saves the network using the given <paramref name="networkSaver"/>. </summary> /// <param name="networkSaver"> The <see cref="INetworkSaver"/> used to save the network. </param> public void Save(INetworkSaver networkSaver) { // Save the learning rate. networkSaver.SaveLearningRate(LearningRate); // Save each neuron layer. for (int i = 0; i < neuronLayers.Length; i++) { networkSaver.SaveNeuronLayer(neuronLayers[i]); } // Save each weight layer. for (uint i = 0; i < weightLayers.Length; i++) { // Create the weight layer entry. networkSaver.CreateWeightLayer(i); // Get the previous neuron layer. IReadOnlyNeuronLayer previousLayer = weightLayers[i].PreviousNeuronLayer; // Go over each neuron in the weight layer's previous neuron layer. for (uint previousNeuronID = 0; previousNeuronID < previousLayer.Count; previousNeuronID++) { foreach (uint nextNeuronID in weightLayers[i].GetNextLayerConnections(previousLayer[previousNeuronID])) { networkSaver.SaveWeight(i, previousNeuronID, nextNeuronID, weightLayers[i].GetWeightBetweenNeurons(previousLayer[previousNeuronID], weightLayers[i].NextNeuronLayer[nextNeuronID])); } } } // Save the network to file. networkSaver.Save(); }
/// <summary> Creates an array of <see cref="Neuron"/>s with random biases. </summary> /// <param name="neuronLayer"> The <see cref="IReadOnlyNeuronLayer"/> that will contain the <see cref="Neuron"/>s. </param> /// <param name="count"> The amount of <see cref="Neuron"/>s to create. </param> /// <param name="random"> The <see cref="Random"/> object used to randomise the biases. </param> /// <returns> An array of <see cref="Neuron"/>s with random biases. </returns> private static Neuron[] randomiseNeurons(IReadOnlyNeuronLayer neuronLayer, int count, Random random) { Neuron[] newNeurons = new Neuron[count]; for (uint i = 0; i < count; i++) { newNeurons[i] = new Neuron(neuronLayer, random, i); } return(newNeurons); }
/// <summary> Creates a new <see cref="NeuronLayerChange"/> for the given <paramref name="neuronLayer"/>. </summary> /// <param name="neuronLayer"> The <see cref="IReadOnlyNeuronLayer"/> whose changes are being stored. </param> public NeuronLayerChange(IReadOnlyNeuronLayer neuronLayer) { // Set the neuron layer. NeuronLayer = neuronLayer ?? throw new ArgumentNullException(nameof(neuronLayer)); // Initialise the bias changes and deltas. biasChanges = new float[neuronLayer.Count]; delta = new float[neuronLayer.Count]; }
/// <summary> Creates a new <see cref="Neuron"/> contained by the given <paramref name="neuronLayer"/> with the given <paramref name="id"/>, <paramref name="activationFunction"/>, and <paramref name="bias"/>. </summary> /// <param name="neuronLayer"> The containing <see cref="IReadOnlyNeuronLayer"/>. </param> /// <param name="activationFunction"> The <see cref="IActivationFunction"/> to use. </param> /// <param name="bias"> The new <see cref="Bias"/> of this <see cref="Neuron"/>. </param> /// <param name="id"> The index of this <see cref="Neuron"/> within the containing <see cref="NeuronLayer"/>. </param> public Neuron(IReadOnlyNeuronLayer neuronLayer, IActivationFunction activationFunction, float bias, uint id) { // Set the containing layer. NeuronLayer = neuronLayer ?? throw new ArgumentNullException(nameof(neuronLayer)); // Set the activation function. this.activationFunction = activationFunction ?? throw new ArgumentNullException(nameof(activationFunction)); // Set the bias. Bias = bias; // Set the ID. Index = id; }
/// <summary> Creates a new <see cref="WeightLayer"/> for the given <paramref name="neuralNetwork"/> with the given <paramref name="index"/> and linked to the given <paramref name="nextNeuronLayer"/> and <paramref name="previousNeuronLayer"/>. </summary> /// <param name="neuralNetwork"> The <see cref="IReadOnlyNeuralNetwork"/> this <see cref="WeightLayer"/> is for. </param> /// <param name="index"> The index of this new <see cref="WeightLayer"/>. </param> /// <param name="previousNeuronLayer"> The previous <see cref="NeuronLayer"/> that this <see cref="WeightLayer"/> is linked to. </param> /// <param name="nextNeuronLayer"> The next <see cref="NeuronLayer"/> that this <see cref="WeightLayer"/> is linked to. </param> public WeightLayer(IReadOnlyNeuralNetwork neuralNetwork, uint index, ILinkableNeuronLayer previousNeuronLayer, ILinkableNeuronLayer nextNeuronLayer) { // Set the index. Index = index; // Set references. NeuralNetwork = neuralNetwork; PreviousNeuronLayer = previousNeuronLayer; NextNeuronLayer = nextNeuronLayer; // Link the previous and next layers to this layer. previousNeuronLayer.NextWeightLayer = this; nextNeuronLayer.PreviousWeightLayer = this; // Initialise dictionaries. previousNeuronConnectionsByID = new Dictionary <uint, Dictionary <uint, weightConnection> >(previousNeuronLayer.Count); nextNeuronConnectionsByID = new Dictionary <uint, Dictionary <uint, weightConnection> >(nextNeuronLayer.Count); }
/// <summary> Creates a new <see cref="Neuron"/> contained by the given <paramref name="neuronLayer"/> with the given <paramref name="id"/>, <paramref name="activationFunction"/>, and randomised <paramref name="Bias"/>. </summary> /// <param name="neuronLayer"> The containing <see cref="IReadOnlyNeuronLayer"/>. </param> /// <param name="activationFunction"> The <see cref="IActivationFunction"/> to use. </param> /// <param name="random"> The <see cref="Random"/> object used to randomise the <see cref="Bias"/>. </param> /// <param name="id"> The index of this <see cref="Neuron"/> within the containing <see cref="NeuronLayer"/>. </param> //public Neuron(IReadOnlyNeuronLayer neuronLayer, IActivationFunction activationFunction, Random random, uint id) : this(neuronLayer, activationFunction, (float)(random.NextDouble() * 2) - 1, id) { } public Neuron(IReadOnlyNeuronLayer neuronLayer, IActivationFunction activationFunction, Random random, uint id) : this(neuronLayer, activationFunction, (float)random.NextDouble() - 0.5f, id) { }
/// <summary> Creates a new <see cref="Neuron"/> contained by the given <paramref name="neuronLayer"/> with the given <paramref name="id"/> and randomised <see cref="Bias"/>. </summary> /// <param name="neuronLayer"> The containing <see cref="IReadOnlyNeuronLayer"/>. </param> /// <param name="random"> The <see cref="Random"/> object used to randomise the <see cref="Bias"/>. </param> /// <param name="id"> The index of this <see cref="Neuron"/> within the containing <see cref="NeuronLayer"/>. </param> public Neuron(IReadOnlyNeuronLayer neuronLayer, Random random, uint id) : this(neuronLayer, defaultActivationFunction, random, id) { }
/// <summary> Creates a new <see cref="Neuron"/> contained by the given <paramref name="neuronLayer"/> with the given <paramref name="id"/> and <paramref name="bias"/>. </summary> /// <param name="neuronLayer"> The containing <see cref="IReadOnlyNeuronLayer"/>. </param> /// <param name="bias"> The new <see cref="Bias"/> of this <see cref="Neuron"/>. </param> /// <param name="id"> The index of this <see cref="Neuron"/> within the containing <see cref="NeuronLayer"/>. </param> public Neuron(IReadOnlyNeuronLayer neuronLayer, float bias, uint id) : this(neuronLayer, defaultActivationFunction, bias, id) { }