Spiking Neuron Network Simulator  1.0
Simulation and training of spiking neuron networks, primarily theta neurons
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Pages
SpikingNeuronNetworkTrainingTests.cs
Go to the documentation of this file.
1 namespace SpikingNeuronNetwork.Test
2 {
3  using Lib;
4  using Lib.NeuronModels;
5  using Lib.Training;
6  using Microsoft.VisualStudio.TestTools.UnitTesting;
7  using System;
8  using System.Collections.Generic;
9  using System.Linq;
10 
14  [TestClass]
16  {
20  [TestMethod]
22  {
23  const int numInputs = 3;
24  const int numNeurons = 3;
25  const double weightIni = 0.01;
26  var thetaNeuronNetwork = new SpikingNeuronNetwork(numInputs, numNeurons, typeof (ThetaNeuron), weightIni,
27  new Dictionary<string, string>
28  {
29  {"Io", "0.001"},
30  {"Method", "EventDriven"}
31  });
32 
33  var trainingPattern = GetSimpleSpikeSet(numInputs + 1);
34  var trainer = new TrainNetwork(thetaNeuronNetwork, trainingPattern, 1e-5, 0.01, 1e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(),
35  TrainingMethod.Batch);
36  Assert.IsFalse(trainer.StartTraining());
37  }
38 
42  [TestMethod]
44  {
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" } });
50 
51  var trainingPatterns = GetSimpleSpikeSet(neuronIndex);
52  var trainer = new TrainNetwork(thetaNeuronNetwork, trainingPatterns, 1e-5, 0.01, 1e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(), TrainingMethod.Batch);
53  Assert.IsTrue(trainer.StartTraining());
54 
55  ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
56  }
57 
61  [TestMethod]
63  {
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" } });
68 
69  var trainingPatterns = GetSimpleSpikeSet(numInputs + numNeuronsPerLayer.Sum() - 1);
70  var trainer = new TrainNetwork(thetaNeuronNetwork, trainingPatterns, 1e-5, 0.01, 1e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(), TrainingMethod.Batch);
71  Assert.IsTrue(trainer.StartTraining());
72 
73  ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
74  }
75 
79  [TestMethod]
81  {
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"} });
86 
87  var trainingPatterns = GetTwoOutputNeuronSpikeSet();
88  var trainer = new TrainNetwork(thetaNeuronNetwork, trainingPatterns, 1e-5, 0.01, 1e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(), TrainingMethod.Batch);
89  Assert.IsTrue(trainer.StartTraining());
90 
91  ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
92  }
93 
97  [TestMethod]
99  {
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" } });
105 
106  var trainingPatterns = GetSimpleSpikeSet(neuronIndex);
107  var trainer = new TrainNetwork(thetaNeuronNetwork, trainingPatterns, 1e-5, 0.01, 1e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(), TrainingMethod.Online);
108  Assert.IsTrue(trainer.StartTraining());
109 
110  ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
111  }
112 
116  [TestMethod]
118  {
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" } });
123 
124  var trainingPatterns = GetSimpleSpikeSet(numInputs + numNeuronsPerLayer.Sum() - 1);
125  var trainer = new TrainNetwork(thetaNeuronNetwork, trainingPatterns, 1e-5, 0.01, 4e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(), TrainingMethod.Online);
126  Assert.IsTrue(trainer.StartTraining());
127 
128  ValidateEachPatternResponse(trainingPatterns, thetaNeuronNetwork);
129  }
130 
134  [TestMethod]
136  {
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);
145  var trainNetwork = new TrainNetwork(thetaNeuronNetwork, trainingPatterns, learningRate, maximumErrorAfterTraining, 1e4, new SumOfSquaredSpikingError(), new SteepestDescentTraining(), TrainingMethod.Batch);
146 
147  foreach (var trainingPattern in trainingPatterns)
148  {
149  thetaNeuronNetwork.ResetNetwork();
150  var neuronFiringHistories = thetaNeuronNetwork.RunSpikingNeuronNetwork(trainingPattern.InputSpikes);
151 
152  // Check Gradient Calculations For Post Spike Derivatives
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++)
157  {
158  Assert.IsTrue(Math.Abs(postSpikeDerivatives[j] - postSpikeDerivativesNumerical[j]) < TestHelper.Epsilon);
159  }
160 
161  // Check Gradient Calculations For Error Derivatives
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())
166  {
167  Assert.IsTrue(Math.Pow(Math.Abs(errorDerivativeParameters.GetErrorDerivative(synapse) - errorDerivativeParametersNumerical.GetErrorDerivative(synapse)), 2) < TestHelper.Epsilon);
168  }
169  }
170  }
171 
172  #region Helper Methods
173 
174  private static void ValidateEachPatternResponse(IEnumerable<SpikeSet> trainingPatterns, SpikingNeuronNetwork thetaNeuronNetwork)
175  {
176  foreach (var trainingPattern in trainingPatterns)
177  {
178  thetaNeuronNetwork.ResetNetwork();
179  var neuronFiringHistories =
180  thetaNeuronNetwork.RunSpikingNeuronNetwork(trainingPattern.InputSpikes.ToList());
181  foreach (var outputNeuronIndex in thetaNeuronNetwork.GetOutputLayerNeuronIndices())
182  {
183  var index = outputNeuronIndex; // to prevent foreach closure
184  var currentOutputSpikes = trainingPattern.OutputSpikes.Where(x => x.NeuronIndex == index).ToList();
185  var errorCalculator = new SumOfSquaredSpikingError();
186  var error = errorCalculator.GetError(currentOutputSpikes, neuronFiringHistories[outputNeuronIndex].OutputSpikes);
187  Assert.IsTrue(error < 0.1);
188  }
189  }
190  }
191 
196  private static List<SpikeSet> GetTwoOutputNeuronSpikeSet()
197  {
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 });
201  return spikeSetList;
202  }
203 
209  private static List<SpikeSet> GetSimpleSpikeSet(int outputNeuronIndex)
210  {
211  var inputSpikeTimes1 = new List<Spike>
212  {
213  new Spike { Time = 2, NeuronIndex = 0},
214  new Spike { Time = 1, NeuronIndex = 1},
215  new Spike { Time = 2.1, NeuronIndex = 2}
216  };
217  var outputSpikeTimes1 = new List<Spike>
218  {
219  new Spike {Time = 15, NeuronIndex = outputNeuronIndex}
220  };
221  var inputSpikeTimes2 = new List<Spike>
222  {
223  new Spike { Time = 1, NeuronIndex = 0},
224  new Spike { Time = 2.1, NeuronIndex = 2}
225  };
226  var outputSpikeTimes2 = new List<Spike>
227  {
228  new Spike {Time = 7, NeuronIndex = outputNeuronIndex}
229  };
230  return new List<SpikeSet>
231  {
232  new SpikeSet
233  {
234  InputSpikes = inputSpikeTimes1,
235  OutputSpikes = outputSpikeTimes1
236  },
237  new SpikeSet
238  {
239  InputSpikes = inputSpikeTimes2,
240  OutputSpikes = outputSpikeTimes2
241  }
242  };
243  }
244 
245  #endregion
246  }
247 }
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 ...
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
Definition: TestHelper.cs:18
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
Definition: TestHelper.cs:13
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