public BpNeuron(int Layer, int NeuronNumber, NeuronClass NeuronType, ArtificialNetwork AINetwork) { this.Location = new Vector2(Layer, NeuronNumber); this.NeuronType = NeuronType; this.Bias = NeuralFunctions.NextDouble(MIN, MAX); this.AINetwork = AINetwork; }
public unsafe override async Task <double> Fire(List <double> Inputsf, NetworkState State) { if (!((BackPropagationNetwork)this.AINetwork).TrainingMode) { if (((BackPropagationNetwork)this.AINetwork).HiddenLayers + 1 == this.GetLocation().X) { Program.WriteLine("NeuronType: " + this.ToString()); Program.WriteLine("Editing neuron class from HIDDEN to OUTPUT"); this.NeuronType = NeuronClass.OUTPUT; } } //Console.SetOut(Program.Debug); //Console.WriteLine("Firing Neuron " + this.ToString()); List <double> Weights = GetWeights(Inputsf.Count, State); //Console.WriteLine("Received Weights, count = " + Weights.Count); List <double> Inputs = Inputsf.ToList(); if (Inputs.Count != Weights.Count) { throw new BrainFireException("The number of inputs != the number of weights. Aborting"); } if (State == NetworkState.FORWARD_PROPAGATION) { if (NeuronType == NeuronClass.HIDDEN) { //simply multiply and sum. Then run through Sigmoid function double value = 0.0; for (int i = 0; i < Inputs.Count; i++) { value += Inputs[i] * Weights[i]; } //Console.WriteLine("Total Sum: " + value); value += this.Bias; //Console.WriteLine("Total Sum (Bias) : " + value); value = NeuralFunctions.SimpleSquash(value); //Console.WriteLine("Sigmoid: " + value); this.Output = value; } else if (NeuronType == NeuronClass.OUTPUT) { //multiply and sum, then calculate this neurons error. Then, update the bias term double value = 0.0; for (int i = 0; i < Inputs.Count; i++) { value += Inputs[i] * Weights[i]; } value += this.Bias; //Program.WriteLine("Total Sum: " + value); Console.SetOut(Program.ConsoleOut); this.Output = NeuralFunctions.SimpleSquash(value); Console.SetOut(Program.Debug); //NeuralFunctions.TanSigmoid(value, &value); if (((BackPropagationNetwork)this.AINetwork).TrainingMode) { //Console.WriteLine("Sigmoid: " + value); double T = ((BackPropagationNetwork)this.AINetwork).ExpectedOutputs[this.GetLocation().Y]; this.DeltaKOutput = this.Output * (1 - this.Output) * (T - this.Output); //Console.WriteLine("DeltaK: " + this.DeltaKOutput); //Update bias double DeltaBias = this.DeltaKOutput * ((BackPropagationNetwork)this.AINetwork).LearningRate; //Console.WriteLine("Delta Bias: " + DeltaBias); this.DeltaBiasOutput = DeltaBias; this.Bias += this.DeltaBiasOutput; //Console.WriteLine("New Bias: " + Bias); } //this.Output = this.DeltaKOutput; } } else if (State == NetworkState.BACK_PROPAGATION) { if (NeuronType == NeuronClass.HIDDEN) { //primary role of the neuron in this state is to update weights and biases //required Inputs[] are DeltaK values from output neuron double DeltaX = 0.0; for (int i = 0; i < Inputs.Count; i++) { //Console.WriteLine("Operation[+]: " + Inputs[i] + " x " + Weights[i]); DeltaX += Weights[i] * Inputs[i]; } //Console.WriteLine("Total Sum: " + DeltaX); //get previous output DeltaX = DeltaX * (1 - this.Output) * this.Output; //Console.WriteLine("DeltaX: " + DeltaX); double DeltaBias = DeltaX * ((BackPropagationNetwork)this.AINetwork).LearningRate; //Console.WriteLine("Delta Bias: " + DeltaBias); //Console.WriteLine("Old Bias: " + this.Bias); if (this.DeltaW == null) { this.DeltaW = DeltaX * ((BackPropagationNetwork)this.AINetwork).LearningRate * this.Output; for (int i = 0; i < Inputs.Count; i++) { ((BackPropagationNetwork)this.AINetwork).Weights[this.GetLocation().X][i + (this.Location.Y * Inputs.Count)] += this.DeltaW; } } else { double DeltaWCur = DeltaX * ((BackPropagationNetwork)this.AINetwork).LearningRate * this.Output; this.DeltaW = DeltaWCur + (((BackPropagationNetwork)this.AINetwork).Momentum * this.DeltaW); //Momentum term for (int i = 0; i < Inputs.Count; i++) { ((BackPropagationNetwork)this.AINetwork).Weights[this.GetLocation().X][i + (this.Location.Y * Inputs.Count)] += this.DeltaW; } } this.Bias += DeltaBias; //Console.WriteLine("New Bias: " + this.Bias); this.Output = DeltaX; } else if (NeuronType == NeuronClass.INPUT) { for (int i = 0; i < Inputs.Count; i++) { double WeightDelta = Inputs[i] * ((BackPropagationNetwork)this.AINetwork).LearningRate * this.InputNeuronInput; //Console.WriteLine("Weight Before: " + ((BackPropagationNetwork)this.AINetwork).Weights[this.GetLocation().X][i + (this.Location.Y * Inputs.Count)]); //Console.WriteLine("Weight Delta: " + WeightDelta); ((BackPropagationNetwork)this.AINetwork).Weights[this.GetLocation().X][i + (this.Location.Y * Inputs.Count)] += WeightDelta; //Console.WriteLine("New Weight: " + ((BackPropagationNetwork)this.AINetwork).Weights[this.GetLocation().X][i + (this.Location.Y * Inputs.Count)]); } } } Console.SetOut(Program.Debug); Console.WriteLine("Output: " + this.Output); return(this.Output); }