1 namespace SpikingNeuronNetwork.Test
4 using Lib.NeuronModels;
6 using Microsoft.VisualStudio.TestTools.UnitTesting;
8 using System.Collections.Generic;
23 const int numInputs = 3;
24 const int numNeurons = 3;
25 const double weightIni = 0.01;
27 new Dictionary<string, string>
30 {
"Method",
"EventDriven"}
33 var trainingPattern = GetSimpleSpikeSet(numInputs + 1);
36 Assert.IsFalse(trainer.StartTraining());
45 const int numInputs = 3;
46 const int numNeurons = 1;
47 const int neuronIndex = numInputs + numNeurons - 1;
48 const double weightIni = 0.01;
49 var thetaNeuronNetwork =
new SpikingNeuronNetwork(numInputs, numNeurons, typeof(
ThetaNeuron), weightIni,
new Dictionary<string, string> { {
"Io",
"0.001" }, {
"Method",
"EventDriven" } });
51 var trainingPatterns = GetSimpleSpikeSet(neuronIndex);
53 Assert.IsTrue(trainer.StartTraining());
55 ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
64 var numNeuronsPerLayer =
new List<int> { 3, 1 };
65 const int numInputs = 3;
66 const double weightIni = 0.001;
67 var thetaNeuronNetwork =
new SpikingNeuronNetwork(numInputs, numNeuronsPerLayer, typeof(
ThetaNeuron), weightIni,
new Dictionary<string, string> { {
"Io",
"0.001" }, {
"Method",
"EventDriven" } });
69 var trainingPatterns = GetSimpleSpikeSet(numInputs + numNeuronsPerLayer.Sum() - 1);
71 Assert.IsTrue(trainer.StartTraining());
73 ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
82 const int numInputs = 3;
83 const int numNeurons = 2;
84 const double weightIni = 0.01;
85 var thetaNeuronNetwork =
new SpikingNeuronNetwork(numInputs,
new List<int> { numNeurons }, typeof(
ThetaNeuron), weightIni,
new Dictionary<string, string> { {
"Io",
"0.001"}, {
"Method",
"EventDriven"} });
87 var trainingPatterns = GetTwoOutputNeuronSpikeSet();
89 Assert.IsTrue(trainer.StartTraining());
91 ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
100 const int numInputs = 3;
101 const int numNeurons = 1;
102 const int neuronIndex = numInputs + numNeurons - 1;
103 const double weightIni = 0.01;
104 var thetaNeuronNetwork =
new SpikingNeuronNetwork(numInputs, numNeurons, typeof(
ThetaNeuron), weightIni,
new Dictionary<string, string> { {
"Io",
"0.001" }, {
"Method",
"EventDriven" } });
106 var trainingPatterns = GetSimpleSpikeSet(neuronIndex);
108 Assert.IsTrue(trainer.StartTraining());
110 ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
119 var numNeuronsPerLayer =
new List<int> { 3, 1 };
120 const int numInputs = 3;
121 const double weightIni = 0.0001;
122 var thetaNeuronNetwork =
new SpikingNeuronNetwork(numInputs, numNeuronsPerLayer, typeof(
ThetaNeuron), weightIni,
new Dictionary<string, string> { {
"Io",
"0.001" }, {
"Method",
"EventDriven" } });
124 var trainingPatterns = GetSimpleSpikeSet(numInputs + numNeuronsPerLayer.Sum() - 1);
126 Assert.IsTrue(trainer.StartTraining());
128 ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
137 const int numInputs = 3;
138 const int numNeurons = 1;
139 const int neuronIndex = numInputs + numNeurons - 1;
140 const double weightIni = 0.01;
141 const double learningRate = 1e-5;
142 const double maximumErrorAfterTraining = 0.01;
143 var thetaNeuronNetwork =
new SpikingNeuronNetwork(numInputs, numNeurons, typeof(
ThetaNeuron), weightIni,
new Dictionary<string, string> { {
"Io",
"0.001"}, {
"Method",
"EventDriven"} });
144 var trainingPatterns = GetSimpleSpikeSet(neuronIndex);
147 foreach (var trainingPattern
in trainingPatterns)
149 thetaNeuronNetwork.ResetNetwork();
150 var neuronFiringHistories = thetaNeuronNetwork.RunSpikingNeuronNetwork(trainingPattern.InputSpikes);
153 var postSpikeDerivatives = thetaNeuronNetwork.CalculatePostSpikeDerivatives(neuronFiringHistories[neuronIndex]);
154 var postSpikeDerivativesNumerical = thetaNeuronNetwork.CalculatePostSpikeDerivativeNumerical(neuronFiringHistories[neuronIndex]);
155 Assert.AreEqual(postSpikeDerivatives.Count, postSpikeDerivativesNumerical.Count);
156 for (var j = 0; j < postSpikeDerivatives.Count; j++)
158 Assert.IsTrue(Math.Abs(postSpikeDerivatives[j] - postSpikeDerivativesNumerical[j]) <
TestHelper.
Epsilon);
162 var errorDerivativeParameters = trainNetwork.CalculateErrorDerivative(neuronFiringHistories, trainingPattern.OutputSpikes);
163 var errorDerivativeParametersNumerical = trainNetwork.CalculateErrorDerivativeNumerical(neuronFiringHistories, trainingPattern.OutputSpikes);
164 Assert.AreEqual(errorDerivativeParameters.GetSynapses().Count, errorDerivativeParametersNumerical.GetSynapses().Count);
165 foreach (var synapse
in errorDerivativeParameters.GetSynapses())
167 Assert.IsTrue(Math.Pow(Math.Abs(errorDerivativeParameters.GetErrorDerivative(synapse) - errorDerivativeParametersNumerical.GetErrorDerivative(synapse)), 2) < TestHelper.Epsilon);
172 #region Helper Methods
174 private static void ValidateEachPatternResponse(IEnumerable<SpikeSet> trainingPatterns,
SpikingNeuronNetwork thetaNeuronNetwork)
176 foreach (var trainingPattern
in trainingPatterns)
178 thetaNeuronNetwork.ResetNetwork();
179 var neuronFiringHistories =
180 thetaNeuronNetwork.RunSpikingNeuronNetwork(trainingPattern.InputSpikes.ToList());
181 foreach (var outputNeuronIndex
in thetaNeuronNetwork.GetOutputLayerNeuronIndices())
183 var index = outputNeuronIndex;
184 var currentOutputSpikes = trainingPattern.OutputSpikes.Where(x => x.NeuronIndex == index).ToList();
186 var error = errorCalculator.GetError(currentOutputSpikes, neuronFiringHistories[outputNeuronIndex].OutputSpikes);
187 Assert.IsTrue(error < 0.1);
196 private static List<SpikeSet> GetTwoOutputNeuronSpikeSet()
198 var spikeSetList = GetSimpleSpikeSet(3);
199 spikeSetList[0].OutputSpikes.Add(
new Spike { Time = 7, NeuronIndex = 4 });
200 spikeSetList[1].OutputSpikes.Add(
new Spike { Time = 15, NeuronIndex = 4 });
209 private static List<SpikeSet> GetSimpleSpikeSet(
int outputNeuronIndex)
211 var inputSpikeTimes1 =
new List<Spike>
213 new Spike { Time = 2, NeuronIndex = 0},
214 new Spike { Time = 1, NeuronIndex = 1},
215 new Spike { Time = 2.1, NeuronIndex = 2}
217 var outputSpikeTimes1 =
new List<Spike>
219 new Spike {Time = 15, NeuronIndex = outputNeuronIndex}
221 var inputSpikeTimes2 =
new List<Spike>
223 new Spike { Time = 1, NeuronIndex = 0},
224 new Spike { Time = 2.1, NeuronIndex = 2}
226 var outputSpikeTimes2 =
new List<Spike>
228 new Spike {Time = 7, NeuronIndex = outputNeuronIndex}
230 return new List<SpikeSet>
234 InputSpikes = inputSpikeTimes1,
235 OutputSpikes = outputSpikeTimes1
239 InputSpikes = inputSpikeTimes2,
240 OutputSpikes = outputSpikeTimes2
void ThetaNeuronNetworkSimpleTrainBatch()
Tests the ability to batch train a single-layer spiking neuron network with one output neuron ...
TrainingMethod
Training Method Enum
void ThetaNeuronNetworkCheckErrorGradient()
Tests the error gradient calculation by comparing numerically and analytically derivaed values ...
void ThetaNeuronNetworkTwoOutputNeuronsTrainBatch()
Tests the ability to batch train a single-layer spiking neuron network with two output neurons ...
Tests ability to train a spiking neuron network
void ThetaNeuronNetworkAttemptTrainNonLayeredNetwork()
Tests that attempts to train a non-layered spiking neuron network return false
static double Epsilon
Small value is used when comparing floats in various tests
Steepest Descent Training Class, inherits from ITrainingAlgorithm
void ThetaNeuronNetworkLayeredTrainOnline()
Tests the ability to online train a two-layered spiking neuron network
Set of helper methods for various spiking neuron network tests
void ThetaNeuronNetworkSimpleTrainOnline()
Tests the ability to online train a single-layer spiking neuron network with one output neuron ...
void ThetaNeuronNetworkLayeredTrainBatch()
Tests the ability to batch train a two-layered spiking neuron network
Spiking Neuron Network Class
Sum of Squared Spiking Error Class