/// <summary> /// The deep copy constructor /// </summary> /// <param name="source">Source instance</param> public ReservoirSettings(ReservoirSettings source) { SettingsName = source.SettingsName; InputCoding = source.InputCoding; InputDuration = source.InputDuration; SpectralRadius = source.SpectralRadius; PoolSettingsCollection = null; if (source.PoolSettingsCollection != null) { PoolSettingsCollection = new List <PoolSettings>(source.PoolSettingsCollection.Count); foreach (PoolSettings srcPoolSettings in source.PoolSettingsCollection) { PoolSettingsCollection.Add(srcPoolSettings.DeepClone()); } } PoolsInterconnectionCollection = null; if (source.PoolsInterconnectionCollection != null) { PoolsInterconnectionCollection = new List <PoolsInterconnection>(source.PoolsInterconnectionCollection.Count); foreach (PoolsInterconnection poolsInterConn in source.PoolsInterconnectionCollection) { PoolsInterconnectionCollection.Add(poolsInterConn.DeepClone()); } } return; }
//Methods /// <summary> /// See the base. /// </summary> public override bool Equals(object obj) { if (obj == null) { return(false); } ReservoirSettings cmpSettings = obj as ReservoirSettings; if (SettingsName != cmpSettings.SettingsName || InputCoding != cmpSettings.InputCoding || InputDuration != cmpSettings.InputDuration || SpectralRadius != cmpSettings.SpectralRadius || (PoolSettingsCollection == null && cmpSettings.PoolSettingsCollection != null) || (PoolSettingsCollection != null && cmpSettings.PoolSettingsCollection == null) || (PoolSettingsCollection != null && PoolSettingsCollection.Count != cmpSettings.PoolSettingsCollection.Count) || (PoolsInterconnectionCollection == null && cmpSettings.PoolsInterconnectionCollection != null) || (PoolsInterconnectionCollection != null && cmpSettings.PoolsInterconnectionCollection == null) || (PoolsInterconnectionCollection != null && PoolsInterconnectionCollection.Count != cmpSettings.PoolsInterconnectionCollection.Count) ) { return(false); } if (PoolSettingsCollection != null) { for (int i = 0; i < PoolSettingsCollection.Count; i++) { if (!Equals(PoolSettingsCollection[i], cmpSettings.PoolSettingsCollection[i])) { return(false); } } } if (PoolsInterconnectionCollection != null) { for (int i = 0; i < PoolsInterconnectionCollection.Count; i++) { if (!Equals(PoolsInterconnectionCollection[i], cmpSettings.PoolsInterconnectionCollection[i])) { return(false); } } } return(true); }
/// <summary> /// Creates the instance and initializes it from given xml element. /// This is the preferred way to instantiate State Machine settings. /// </summary> /// <param name="elem"> /// Xml data containing State Machine settings. /// Content of xml element is always validated against the xml schema. /// </param> public StateMachineSettings(XElement elem) { //Validation ElemValidator validator = new ElemValidator(); Assembly assemblyRCNet = Assembly.GetExecutingAssembly(); validator.AddXsdFromResources(assemblyRCNet, "RCNet.Neural.Network.SM.StateMachineSettings.xsd"); validator.AddXsdFromResources(assemblyRCNet, "RCNet.RCNetTypes.xsd"); XElement stateMachineSettingsElem = validator.Validate(elem, "rootElem"); //Parsing //Randomizer seek RandomizerSeek = int.Parse(stateMachineSettingsElem.Attribute("randomizerSeek").Value); //Neural preprocessor NeuralPreprocessorConfig = new NeuralPreprocessorSettings(stateMachineSettingsElem.Descendants("neuralPreprocessor").First()); //Readout layer ReadoutLayerConfig = new ReadoutLayerSettings(stateMachineSettingsElem.Descendants("readoutLayer").First()); //Mapper XElement mapperSettingsElem = stateMachineSettingsElem.Descendants("mapper").FirstOrDefault(); if(mapperSettingsElem != null) { //Create mapper object MapperCfg = new MapperSettings(); //Loop through mappings foreach(XElement mapElem in mapperSettingsElem.Descendants("map")) { //Readout unit name string readoutUnitName = mapElem.Attribute("readoutUnitName").Value; int readoutUnitIdx = -1; for (int i = 0; i < ReadoutLayerConfig.ReadoutUnitCfgCollection.Count; i++) { if(ReadoutLayerConfig.ReadoutUnitCfgCollection[i].Name == readoutUnitName) { readoutUnitIdx = i; break; } else if(i == ReadoutLayerConfig.ReadoutUnitCfgCollection.Count - 1) { throw new Exception($"Name {readoutUnitName} not found among readout units."); } } //Allowed pools List<MapperSettings.AllowedPool> allowedPools = new List<MapperSettings.AllowedPool>(); XElement allowedPoolsElem = mapElem.Descendants("allowedPools").FirstOrDefault(); if (allowedPoolsElem != null) { foreach (XElement allowedPoolElem in allowedPoolsElem.Descendants("pool")) { //Reservoir instance name string reservoirInstanceName = allowedPoolElem.Attribute("reservoirInstanceName").Value; int reservoirInstanceIdx = -1; for (int i = 0; i < NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection.Count; i++) { if (NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection[i].InstanceName == reservoirInstanceName) { reservoirInstanceIdx = i; break; } else if (i == NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection.Count - 1) { throw new Exception($"Name {reservoirInstanceName} not found among resevoir instances."); } } //Pool name string reservoirCfgName = NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection[reservoirInstanceIdx].Settings.SettingsName; ReservoirSettings reservoirSettings = NeuralPreprocessorConfig.ReservoirInstanceDefinitionCollection[reservoirInstanceIdx].Settings; string poolName = allowedPoolElem.Attribute("poolName").Value; int poolIdx = -1; for (int i = 0; i < reservoirSettings.PoolSettingsCollection.Count; i++) { if (reservoirSettings.PoolSettingsCollection[i].Name == poolName) { poolIdx = i; break; } else if (i == reservoirSettings.PoolSettingsCollection.Count - 1) { throw new Exception($"Name {poolName} not found among resevoir's pools."); } } allowedPools.Add(new MapperSettings.AllowedPool { _reservoirInstanceIdx = reservoirInstanceIdx, _poolIdx = poolIdx }); } MapperCfg.PoolsMap.Add(readoutUnitName, allowedPools); } //Allowed routed input fields List<int> allowedRoutedFieldsIdxs = new List<int>(); XElement allowedInputFieldsElem = mapElem.Descendants("allowedInputFields").FirstOrDefault(); List<string> routedInputFieldNames = NeuralPreprocessorConfig.InputConfig.RoutedFieldNameCollection(); if (allowedInputFieldsElem != null) { foreach (XElement allowedInputFieldElem in allowedInputFieldsElem.Descendants("field")) { //Input field name string inputFieldName = allowedInputFieldElem.Attribute("name").Value; int routedFieldIdx = routedInputFieldNames.IndexOf(inputFieldName); if (routedFieldIdx == -1) { throw new Exception($"Name {inputFieldName} not found among input fields allowed to be routed to readout."); } allowedRoutedFieldsIdxs.Add(routedFieldIdx); } MapperCfg.RoutedInputFieldsMap.Add(readoutUnitName, allowedRoutedFieldsIdxs); } } } return; }
/// <summary> /// Creates the deep copy instance of this instance /// </summary> public ReservoirSettings DeepClone() { ReservoirSettings clone = new ReservoirSettings(this); return(clone); }
/// <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; }