/// <summary> Links the given <paramref name="previousNeuron"/> to the <paramref name="nextNeuron"/> with the given <paramref name="weight"/>. </summary> /// <param name="previousNeuron"> The <see cref="IReadOnlyNeuron"/> in the <see cref="PreviousNeuronLayer"/>. </param> /// <param name="nextNeuron"> The <see cref="IReadOnlyNeuron"/> in the <see cref="NextNeuronLayer"/>. </param> /// <param name="weight"> The weight to set. </param> public void LinkNeurons(IReadOnlyNeuron previousNeuron, IReadOnlyNeuron nextNeuron, float weight) { #if DEBUG ensureValid(previousNeuron, nextNeuron); #endif // Create the connection. weightConnection weightConnection = new weightConnection(previousNeuron.Index, nextNeuron.Index, weight); // Add the previous connection using the previous neuron. if (previousNeuronConnectionsByID.TryGetValue(previousNeuron.Index, out Dictionary <uint, weightConnection> previousNeuronConnections)) { previousNeuronConnections.Add(nextNeuron.Index, weightConnection); } else { previousNeuronConnectionsByID.Add(previousNeuron.Index, new Dictionary <uint, weightConnection>() { { nextNeuron.Index, weightConnection } }); } // Add the next connection using the next neuron. if (nextNeuronConnectionsByID.TryGetValue(nextNeuron.Index, out Dictionary <uint, weightConnection> nextNeuronConnections)) { nextNeuronConnections.Add(previousNeuron.Index, weightConnection); } else { nextNeuronConnectionsByID.Add(nextNeuron.Index, new Dictionary <uint, weightConnection>() { { previousNeuron.Index, weightConnection } }); } }
/// <summary> Gets the weight between the given <paramref name="previousNeuron"/> and <paramref name="nextNeuron"/>. </summary> /// <param name="previousNeuron"> The <see cref="IReadOnlyNeuron"/> in the <see cref="PreviousNeuronLayer"/>. </param> /// <param name="nextNeuron"> The <see cref="IReadOnlyNeuron"/> in the <see cref="NextNeuronLayer"/>. </param> /// <returns> The weight between the given <paramref name="previousNeuron"/> and <paramref name="nextNeuron"/>. </returns> public float GetWeightBetweenNeurons(IReadOnlyNeuron previousNeuron, IReadOnlyNeuron nextNeuron) { #if DEBUG ensureValid(previousNeuron, nextNeuron); #endif return(previousNeuronConnectionsByID[previousNeuron.Index][nextNeuron.Index].Weight); }
/// <summary> Gets the change of weight between the given <paramref name="nextNeuron"/> and <paramref name="previousNeuron"/>. </summary> /// <param name="previousNeuron"> The neuron in the previous <see cref="NeuronLayer"/>. </param> /// <param name="nextNeuron"> The neuron in the next <see cref="NeuronLayer"/>. </param> /// <returns> The weight between the given <paramref name="nextNeuron"/> and <paramref name="previousNeuron"/>. </returns> public float GetWeightChangeBetweenNeurons(IReadOnlyNeuron previousNeuron, IReadOnlyNeuron nextNeuron) { #if DEBUG // Ensure the neurons are for this weight layer. ensureValidity(previousNeuron, nextNeuron); #endif // Return the weight. return(nextNeuronConnections[nextNeuron.Index][previousNeuron.Index]); }
private void ensureValidity(IReadOnlyNeuron previousNeuron, IReadOnlyNeuron nextNeuron) { if (previousNeuron.NeuronLayer.NextWeightLayer != WeightLayer) { throw new Exception("Neuron mismatch, previous neuron is not in the expected layer."); } if (nextNeuron.NeuronLayer.PreviousWeightLayer != WeightLayer) { throw new Exception("Neuron mismatch, next neuron is not in the expected layer."); } }
/// <summary> Sets the delta for the given <paramref name="neuron"/> to the given <paramref name="newDelta"/>. </summary> /// <param name="neuron"> The <see cref="IReadOnlyNeuron"/> whose delta is being set. </param> /// <param name="newDelta"> The new value of the delta. </param> public void SetDelta(IReadOnlyNeuron neuron, float newDelta) { #if DEBUG // Ensure this is the correct layer for the given neuron. if (neuron.NeuronLayer != NeuronLayer) { throw new Exception("Layer mismatch."); } #endif // Set the delta. delta[neuron.Index] = newDelta; }
/// <summary> Adds the given <paramref name="biasChange"/> to the bias for the given <paramref name="neuron"/>. </summary> /// <param name="neuron"> The <see cref="IReadOnlyNeuron"/> who bias is being changed. </param> /// <param name="biasChange"> The change to the bias. </param> public void AddBias(IReadOnlyNeuron neuron, float biasChange) { #if DEBUG // Ensure this is the correct layer for the given neuron. if (neuron.NeuronLayer != NeuronLayer) { throw new Exception("Layer mismatch."); } #endif // Add the bias change. biasChanges[neuron.Index] += biasChange; }
/// <summary> Gets the change to bias for the given <paramref name="neuron"/>. </summary> /// <param name="neuron"> The <see cref="IReadOnlyNeuron"/> whose bias change is desired. </param> /// <returns> The change to bias for the given <paramref name="neuron"/>. </returns> public float GetBias(IReadOnlyNeuron neuron) { #if DEBUG // Ensure this is the correct layer for the given neuron. if (neuron.NeuronLayer != NeuronLayer) { throw new Exception("Layer mismatch."); } #endif // Return the bias change. return(biasChanges[neuron.Index]); }
/// <summary> Adds the given <paramref name="weightChange"/> to the connection between the given <paramref name="nextNeuron"/> and <paramref name="previousNeuron"/>. </summary> /// <param name="previousNeuron"> The neuron in the previous <see cref="NeuronLayer"/>. </param> /// <param name="nextNeuron"> The neuron in the next <see cref="NeuronLayer"/>. </param> /// <param name="weightChange"> The amount of weight to change. </param> public void AddWeightChangeBetweenNeurons(IReadOnlyNeuron previousNeuron, IReadOnlyNeuron nextNeuron, float weightChange) { #if DEBUG // Ensure the neurons are for this weight layer. ensureValidity(previousNeuron, nextNeuron); #endif // If there is no change to be made, do nothing. if (weightChange == 0) { return; } // Add the weight. nextNeuronConnections[nextNeuron.Index][previousNeuron.Index] += weightChange; }
private void ensureValid(IReadOnlyNeuron previousNeuron, IReadOnlyNeuron nextNeuron) { // Ensure the given neurons are not null. if (previousNeuron is null) { throw new ArgumentNullException(nameof(previousNeuron)); } if (nextNeuron is null) { throw new ArgumentNullException(nameof(nextNeuron)); } // Ensure that the layers of the given neurons match. if (previousNeuron.NeuronLayer != PreviousNeuronLayer) { throw new Exception("Given previous neuron was not part of the previous layer of this weight layer."); } if (nextNeuron.NeuronLayer != NextNeuronLayer) { throw new Exception("Given next neuron was not part of the next layer of this weight layer."); } }
/// <summary> Gets an <see cref="IEnumerable"/> for the given <paramref name="previousNeuron"/>'s connections to the <see cref="NextNeuronLayer"/>. </summary> /// <param name="previousNeuron"></param> /// <returns></returns> public IEnumerable <uint> GetNextLayerConnections(IReadOnlyNeuron previousNeuron) => previousNeuronConnectionsByID[previousNeuron.Index].Keys.AsEnumerable();
/// <summary> Gets an <see cref="IEnumerable"/> for the given <paramref name="nextNeuron"/>'s connections to the <see cref="PreviousNeuronLayer"/>. </summary> /// <param name="nextNeuron"></param> /// <returns></returns> public IEnumerable <uint> GetPreviousLayerConnections(IReadOnlyNeuron nextNeuron) => nextNeuronConnectionsByID[nextNeuron.Index].Keys.AsEnumerable();