//Constructor /// <summary> /// Creates an initialized instance /// </summary> /// <param name="inputFieldIdx">Index of correspondent reservoir input field.</param> /// <param name="inputRange"> /// Range of input value. /// It is very recommended to have input values normalized and standardized before /// they are passed as an input. /// </param> public InputAnalogNeuron(int inputFieldIdx, Interval inputRange) { Placement = new NeuronPlacement(inputFieldIdx, -1, inputFieldIdx, inputFieldIdx, 0, 0); _inputRange = inputRange.DeepClone(); StimuliStat = new BasicStat(); TransmissionFreqStat = new BasicStat(); Reset(false); return; }
//Methods /// <summary> /// Computes the Euclidean distance from another neuron within the pool /// </summary> /// <param name="party">Another neuron placement within the same pool.</param> public double ComputeEuclideanDistance(NeuronPlacement party) { double sum = 0; for (int i = 0; i < Coordinates.Length; i++) { sum += ((double)(Coordinates[i] - party.Coordinates[i])).Power(2); } return(Math.Sqrt(sum)); }
//Constructor /// <summary> /// Creates an initialized instance /// </summary> /// <param name="inputFieldIdx">Index of corresponding reservoir input field.</param> /// <param name="inputRange"> /// Range of input value. /// It is very recommended to have input values normalized and standardized before /// they are passed to input neuron. /// </param> /// <param name="inputCodingFractions">Number of coding fractions (see SpikeTrainConverter to understand)</param> public InputSpikingNeuron(int inputFieldIdx, Interval inputRange, int inputCodingFractions) { Placement = new NeuronPlacement(inputFieldIdx, -1, inputFieldIdx, inputFieldIdx, 0, 0); _inputRange = new Interval(inputRange.Min.Bound(), inputRange.Max.Bound()); _signalConverter = new SignalConverter(_inputRange, inputCodingFractions); StimuliStat = new BasicStat(); TransmissionSignalStat = new BasicStat(); Reset(false); return; }
//Constructor /// <summary> /// Creates an initialized instance /// </summary> /// <param name="placement">Home pool identificator and neuron placement within the pool.</param> /// <param name="transmissionSignalType">Type of the neuron's signal (Excitatory/Inhibitory).</param> /// <param name="activation">Instantiated activation function.</param> /// <param name="bias">Constant bias.</param> public ReservoirSpikingNeuron(NeuronPlacement placement, CommonEnums.NeuronSignalType transmissionSignalType, IActivationFunction activation, double bias ) { _firingRate = new FiringRate(); Placement = placement; TransmissionSignalType = transmissionSignalType; Bias = bias; //Check whether function is spiking if (activation.OutputSignalType != ActivationFactory.FunctionOutputSignalType.Spike) { throw new ArgumentException("Activation function is not spiking.", "activation"); } _activation = activation; StimuliStat = new BasicStat(); StatesStat = new BasicStat(); TransmissionSignalStat = new BasicStat(); TransmissionFreqStat = new BasicStat(); Reset(false); return; }
//Constructor /// <summary> /// Creates an initialized instance /// </summary> /// <param name="placement">Home pool identificator and neuron placement within the pool.</param> /// <param name="transmissionSignalType">Type of the neuron's signal (Excitatory/Inhibitory).</param> /// <param name="activation">Instantiated activation function.</param> /// <param name="bias">Constant bias.</param> /// <param name="retainmentRatio">Retainment ratio.</param> public ReservoirAnalogNeuron(NeuronPlacement placement, CommonEnums.NeuronSignalType transmissionSignalType, IActivationFunction activation, double bias, double retainmentRatio ) { Placement = placement; TransmissionSignalType = transmissionSignalType; Bias = bias; //Check whether function is analog if (activation.OutputSignalType != ActivationFactory.FunctionOutputSignalType.Analog) { throw new ArgumentException("Activation function is not analog.", "activation"); } _activation = activation; _retainmentRatio = retainmentRatio; StimuliStat = new BasicStat(); StatesStat = new BasicStat(); TransmissionSignalStat = new BasicStat(); TransmissionFreqStat = new BasicStat(); Reset(false); return; }
/// <summary> /// Instantiates the reservoir /// </summary> /// <param name="instanceName">The name of the reservoir instance</param> /// <param name="numOfInputNodes">Number of reservoir inputs</param> /// <param name="inputRange">Range of input values</param> /// <param name="settings">Reservoir settings</param> /// <param name="augmentedStates">Specifies whether this reservoir will add augmented states to output predictors</param> /// <param name="randomizerSeek"> /// A value greater than or equal to 0 will always ensure the same initialization of the internal /// random number generator and therefore the same reservoir structure, which is good for tuning purposes. /// A value less than 0 causes a fully random initialization each time creating a reservoir instance. /// </param> public Reservoir(string instanceName, int numOfInputNodes, Interval inputRange, ReservoirSettings settings, bool augmentedStates, int randomizerSeek = -1) { //Set instance name _instanceName = instanceName; //Copy settings _settings = settings.DeepClone(); //Random generator initialization if (randomizerSeek < 0) { _rand = new Random(); } else { _rand = new Random(randomizerSeek); } //Prepare neuron buffers //Input neurons _inputNeurons = new INeuron[numOfInputNodes]; for (int i = 0; i < numOfInputNodes; i++) { if (_settings.InputCoding == CommonEnums.InputCodingType.Analog) { //Analog input _inputNeurons[i] = new InputAnalogNeuron(i, inputRange); } else { //Spiking input _inputNeurons[i] = new InputSpikingNeuron(i, inputRange, _settings.InputDuration); } } //Pools _numOfPredictors = 0; List <INeuron> allNeurons = new List <INeuron>(); int neuronGlobalFlatIdx = 0; int totalNumOfNeurons = 0; _poolNeuronsCollection = new List <INeuron[]>(_settings.PoolSettingsCollection.Count); for (int poolID = 0; poolID < _settings.PoolSettingsCollection.Count; poolID++) { PoolSettings poolSettings = _settings.PoolSettingsCollection[poolID]; totalNumOfNeurons += poolSettings.Dim.Size; _numOfPredictors += poolSettings.RouteToReadout ? poolSettings.Dim.Size : 0; INeuron[] poolNeurons = new INeuron[poolSettings.Dim.Size]; //Retainment rates double[] retRates = new double[poolSettings.Dim.Size]; retRates.Populate(0); if (poolSettings.RetainmentNeuronsFeature) { int[] indices = new int[poolSettings.Dim.Size]; indices.ShuffledIndices(_rand); int numOfRetNeurons = (int)Math.Round(poolSettings.RetainmentNeuronsDensity * poolSettings.Dim.Size, 0); for (int i = 0; i < numOfRetNeurons; i++) { retRates[indices[i]] = _rand.NextDouble(poolSettings.RetainmentMinRate, poolSettings.RetainmentMaxRate, false, RandomClassExtensions.DistributionType.Uniform); } } //Neuron signal types distribution CommonEnums.NeuronSignalType[] sigTypes = new CommonEnums.NeuronSignalType[poolSettings.Dim.Size]; sigTypes.Populate(CommonEnums.NeuronSignalType.Excitatory); int[] inhibitoryIndices = new int[poolSettings.Dim.Size]; inhibitoryIndices.ShuffledIndices(_rand); int numOfInhibitoryNeurons = (int)Math.Round(poolSettings.InhibitoryNeuronsDensity * poolSettings.Dim.Size, 0); for (int i = 0; i < numOfInhibitoryNeurons; i++) { sigTypes[inhibitoryIndices[i]] = CommonEnums.NeuronSignalType.Inhibitory; } //Instantiate neurons int neuronPoolIdx = 0; for (int x = 0; x < poolSettings.Dim.X; x++) { for (int y = 0; y < poolSettings.Dim.Y; y++) { for (int z = 0; z < poolSettings.Dim.Z; z++) { NeuronPlacement placement = new NeuronPlacement(neuronGlobalFlatIdx, poolID, neuronPoolIdx, x, y, z); IActivationFunction activation = null; double bias = 0; if (sigTypes[neuronPoolIdx] == CommonEnums.NeuronSignalType.Excitatory) { //Activation and bias for Excitatory neuron activation = ActivationFactory.Create(poolSettings.ExcitatoryActivation); bias = _rand.NextDouble(poolSettings.ExcitatoryBias.Min, poolSettings.ExcitatoryBias.Max, poolSettings.ExcitatoryBias.RandomSign, poolSettings.ExcitatoryBias.DistrType); } else { //Activation and bias for Inhibitory neuron activation = ActivationFactory.Create(poolSettings.InhibitoryActivation); bias = _rand.NextDouble(poolSettings.InhibitoryBias.Min, poolSettings.InhibitoryBias.Max, poolSettings.InhibitoryBias.RandomSign, poolSettings.InhibitoryBias.DistrType); } //Neuron instance if (activation.OutputSignalType == ActivationFactory.FunctionOutputSignalType.Spike) { //Spiking neuron poolNeurons[neuronPoolIdx] = new ReservoirSpikingNeuron(placement, sigTypes[neuronPoolIdx], activation, bias ); } else { //Analog neuron poolNeurons[neuronPoolIdx] = new ReservoirAnalogNeuron(placement, sigTypes[neuronPoolIdx], activation, bias, retRates[neuronPoolIdx] ); } allNeurons.Add(poolNeurons[neuronPoolIdx]); ++neuronPoolIdx; ++neuronGlobalFlatIdx; } } } _poolNeuronsCollection.Add(poolNeurons); } //All neurons flat structure _neurons = allNeurons.ToArray(); //Interconnections //Banks allocations _neuronInputConnectionsCollection = new List <ISynapse> [totalNumOfNeurons]; _neuronNeuronConnectionsCollection = new List <ISynapse> [totalNumOfNeurons]; for (int n = 0; n < totalNumOfNeurons; n++) { _neuronInputConnectionsCollection[n] = new List <ISynapse>(); _neuronNeuronConnectionsCollection[n] = new List <ISynapse>(); } //Wiring setup //Pools internal connections for (int poolID = 0; poolID < _poolNeuronsCollection.Count; poolID++) { //Input connection SetPoolInputConnections(poolID, _settings.PoolSettingsCollection[poolID]); //Pool interconnection if (_settings.PoolSettingsCollection[poolID].InterconnectionAvgDistance > 0) { //Required to keep average distance SetPoolDistInterconnections(poolID, _settings.PoolSettingsCollection[poolID]); } else { //Not required to keep average distance SetPoolRandInterconnections(poolID, _settings.PoolSettingsCollection[poolID]); } } //Add pool to pool connections foreach (ReservoirSettings.PoolsInterconnection poolsInterConn in _settings.PoolsInterconnectionCollection) { SetPool2PoolInterconnections(poolsInterConn); } //Spectral radius if (_settings.SpectralRadius > 0) { double maxEigenValue = ComputeMaxEigenValue(); if (maxEigenValue == 0) { throw new Exception("Invalid reservoir weights. Max eigenvalue is 0."); } double scale = _settings.SpectralRadius / maxEigenValue; //Scale internal weights foreach (List <ISynapse> connCollection in _neuronNeuronConnectionsCollection) { foreach (ISynapse conn in connCollection) { conn.Weight *= scale; } } } //Augmented states _augmentedStatesFeature = augmentedStates; return; }