/// <summary> /// Setup the network logic, read parameters from the network. /// </summary> /// <param name="network">The network that this logic class belongs to.</param> public override void Init(BasicNetwork network) { base.Init(network); // hold references to parts of the network we will need later this.thermalLayer = this.Network.GetLayer(BasicNetwork.TAG_INPUT); this.thermalSynapse = this.Network.Structure.FindSynapse(this.thermalLayer, this.thermalLayer, true); this.currentState = new BiPolarNeuralData(this.thermalLayer.NeuronCount); }
/// <summary> /// Setup the network logic, read parameters from the network. /// </summary> /// <param name="network">The network that this logic class belongs to.</param> public override void Init(BasicNetwork network) { base.Init(network); this.layerF1 = this.Network.GetLayer(ART1Pattern.TAG_F1); this.layerF2 = this.Network.GetLayer(ART1Pattern.TAG_F2); this.inhibitF2 = new bool[this.layerF2.NeuronCount]; this.synapseF1toF2 = this.Network.Structure.FindSynapse(this.layerF1, this.layerF2, true); this.synapseF2toF1 = this.Network.Structure.FindSynapse(this.layerF2, this.layerF1, true); this.outputF1 = new BiPolarNeuralData(this.layerF1.NeuronCount); this.outputF2 = new BiPolarNeuralData(this.layerF2.NeuronCount); this.a1 = this.Network.GetPropertyDouble(ARTLogic.PROPERTY_A1); this.b1 = this.Network.GetPropertyDouble(ARTLogic.PROPERTY_B1); this.c1 = this.Network.GetPropertyDouble(ARTLogic.PROPERTY_C1); this.d1 = this.Network.GetPropertyDouble(ARTLogic.PROPERTY_D1); this.l = this.Network.GetPropertyDouble(ARTLogic.PROPERTY_L); this.vigilance = this.Network.GetPropertyDouble(ARTLogic.PROPERTY_VIGILANCE); this.noWinner = this.layerF2.NeuronCount; Reset(); }
/// <summary> /// Compute the output for the BasicNetwork class. /// </summary> /// <param name="input">The input to the network.</param> /// <param name="useHolder">The NeuralOutputHolder to use.</param> /// <returns>The output from the network.</returns> public override INeuralData Compute(INeuralData input, NeuralOutputHolder useHolder) { if (!(input is BiPolarNeuralData)) { String str = "Input to ART1 logic network must be BiPolarNeuralData."; #if logging if (logger.IsErrorEnabled) { logger.Error(str); } #endif throw new NeuralNetworkError(str); } BiPolarNeuralData output = new BiPolarNeuralData(this.layerF1.NeuronCount); Compute((BiPolarNeuralData)input, output); return output; }
/// <summary> /// Set the input to the neural network. /// </summary> /// <param name="input">The input.</param> private void SetInput(BiPolarNeuralData input) { double activation; for (int i = 0; i < this.layerF1.NeuronCount; i++) { activation = (input.GetBoolean(i) ? 1 : 0) / (1 + this.a1 * ((input.GetBoolean(i) ? 1 : 0) + this.b1) + this.c1); this.outputF1.SetBoolean(i, (activation > 0)); } }
/// <summary> /// Get the magnitude of the specified input. /// </summary> /// <param name="input">The input to calculate the magnitude for.</param> /// <returns>The magnitude of the specified pattern.</returns> public double Magnitude(BiPolarNeuralData input) { double result; result = 0; for (int i = 0; i < this.layerF1.NeuronCount; i++) { result += input.GetBoolean(i) ? 1 : 0; } return result; }
/// <summary> /// Copy the output from the network to another object. /// </summary> /// <param name="output">The target object for the output from the network.</param> private void GetOutput(BiPolarNeuralData output) { for (int i = 0; i < this.layerF2.NeuronCount; i++) { output.SetBoolean(i, this.outputF2.GetBoolean(i)); } }
/// <summary> /// Compute the output from the F1 layer. /// </summary> /// <param name="input">The input to the F1 layer.</param> private void ComputeF1(BiPolarNeuralData input) { double sum, activation; for (int i = 0; i < this.layerF1.NeuronCount; i++) { sum = this.synapseF1toF2.WeightMatrix[i, this.winner] * (this.outputF2.GetBoolean(this.winner) ? 1 : 0); activation = ((input.GetBoolean(i) ? 1 : 0) + this.d1 * sum - this.b1) / (1 + this.a1 * ((input.GetBoolean(i) ? 1 : 0) + this.d1 * sum) + this.c1); this.outputF1.SetBoolean(i, activation > 0); } }
/// <summary> /// Compute the output from the ART1 network. This can be called directly /// or used by the BasicNetwork class. Both input and output should be /// bipolar numbers. /// </summary> /// <param name="input">The input to the network.</param> /// <param name="output">The output from the network.</param> public void Compute(BiPolarNeuralData input, BiPolarNeuralData output) { int i; bool resonance, exhausted; double magnitudeInput1, magnitudeInput2; for (i = 0; i < this.layerF2.NeuronCount; i++) { this.inhibitF2[i] = false; } resonance = false; exhausted = false; do { SetInput(input); ComputeF2(); GetOutput(output); if (this.winner != this.noWinner) { ComputeF1(input); magnitudeInput1 = Magnitude(input); magnitudeInput2 = Magnitude(this.outputF1); if ((magnitudeInput2 / magnitudeInput1) < this.vigilance) { this.inhibitF2[this.winner] = true; } else { resonance = true; } } else { exhausted = true; } } while (!(resonance || exhausted)); if (resonance) { AdjustWeights(); } }