private void GenerateNeurons(int inputCount, int outputCount, int hiddenCount, int neuronsPerLayer) { // Create container for neurons Inputs = new Neuron[inputCount]; Outputs = new Neuron[outputCount]; HiddenLayers = new Neuron[hiddenCount][]; // Generate input neurons for (int i = 0; i < Inputs.Length; i++) { Inputs[i] = new Neuron(); Inputs[i].Type = Neuron.NeuronType.InputNeuron; Inputs[i].ID = "Input" + i; Inputs[i].LayerIndex = i; Inputs[i].InputConnections = new Neuron[inputCount]; Inputs[i].Weight = new float[neuronsPerLayer]; } //Generate output neurons for (int i = 0; i < Outputs.Length; i++) { Outputs[i] = new Neuron(); Outputs[i].Type = Neuron.NeuronType.OutputNeuron; Outputs[i].ID = "Output" + i; Outputs[i].LayerIndex = i; Outputs[i].InputConnections = new Neuron[neuronsPerLayer]; Outputs[i].Weight = new float[neuronsPerLayer]; } //Generate input neurons for (int iteration = 1; iteration < HiddenLayers.Length; iteration++) { HiddenLayers[iteration] = new Neuron[neuronsPerLayer]; for (int i = 0; i < HiddenLayers[iteration].Length; i++) { HiddenLayers[iteration][i] = new Neuron(); HiddenLayers[iteration][i].Type = Neuron.NeuronType.HiddenNeuron; HiddenLayers[iteration][i].ID = "Neuron" + i; HiddenLayers[iteration][i].LayerIndex = i; HiddenLayers[iteration][i].InputConnections = new Neuron[neuronsPerLayer]; HiddenLayers[iteration][i].Weight = new float[neuronsPerLayer]; } } //Generate input neurons of the first layer, to configure them with the inputs HiddenLayers[0] = new Neuron[neuronsPerLayer]; for (int i = 0; i < HiddenLayers[0].Length; i++) { HiddenLayers[0][i] = new Neuron(); HiddenLayers[0][i].Type = Neuron.NeuronType.HiddenNeuron; HiddenLayers[0][i].ID = "Neuron" + i; HiddenLayers[0][i].LayerIndex = i; HiddenLayers[0][i].InputConnections = new Neuron[inputCount]; HiddenLayers[0][i].Weight = new float[inputCount]; } AllLayers = new Neuron[HiddenLayers.Length + 2][]; Array.Copy(HiddenLayers, 0, AllLayers, 1, HiddenLayers.Length); AllLayers[0] = Inputs; AllLayers[AllLayers.Length - 1] = Outputs; }
private static float Delta_i(Neuron neuron, float targetOutput, float currentOutput) { neuron.Delta_i = derivative(neuron.Activation) * (targetOutput - currentOutput); return(neuron.Delta_i); }
private void ParseStructureStream(Stream structure) { BinaryReader reader = new BinaryReader(structure); int layerAmount = reader.ReadInt32(); int inputCount = reader.ReadInt32(); int[] hiddenCount = new int[layerAmount - 2]; for (int i = 0; i < layerAmount - 2; i++) { hiddenCount[i] = reader.ReadInt32(); } int outputCount = reader.ReadInt32(); int[] layers = new int[layerAmount]; layers[0] = inputCount; layers[layers.Length - 1] = outputCount; for (int i = 1; i < layerAmount - 1; i++) { layers[i] = hiddenCount[i - 1]; } GenerateNeurons(layers); for (int i = 0; i < inputCount; i++) { Inputs[i].OutputConnections = HiddenLayers[0]; } for (int iteration = 0; iteration < hiddenCount.Length; iteration++) { for (int iter = 0; iter < hiddenCount[iteration]; iter++) { Neuron targetNeuron = HiddenLayers[iteration][iter]; targetNeuron.InputConnections = AllLayers[iteration]; targetNeuron.OutputConnections = AllLayers[iteration + 2]; targetNeuron.Weight = new float[targetNeuron.InputConnections.Length]; for (int i = 0; i < targetNeuron.Weight.Length; i++) { targetNeuron.Weight[i] = reader.ReadSingle(); } } } for (int iter = 0; iter < outputCount; iter++) { Neuron targetNeuron = Outputs[iter]; targetNeuron.InputConnections = HiddenLayers[HiddenLayers.Length - 1]; targetNeuron.OutputConnections = new Neuron[] { targetNeuron }; targetNeuron.Weight = new float[targetNeuron.InputConnections.Length]; for (int i = 0; i < targetNeuron.Weight.Length; i++) { targetNeuron.Weight[i] = reader.ReadSingle(); } } for (int i = 0; i < inputCount; i++) { Neuron targetNeuron = Inputs[i]; targetNeuron.InputConnections = new Neuron[] { targetNeuron }; targetNeuron.OutputConnections = HiddenLayers[0]; targetNeuron.Weight = new float[1]; } structure.Seek(0, SeekOrigin.Begin); }
static public float[][][] Backpropagate(Brain brain, float TweakAmount, int outputNum, int expectedNum) { Neuron[][] layers = new Neuron[brain.HiddenLayers.Length + 1][]; Array.Copy(brain.AllLayers, 1, layers, 0, brain.AllLayers.Length - 1); float[] targetOutput = new float[10]; targetOutput[expectedNum] = 1.0F; float[][][] allChanges = new float[layers.Length][][]; for (int layerNum = layers.Length - 1; layerNum >= 0; layerNum--) { Neuron[] layer = layers[layerNum]; float[][] neuronChanges = new float[layer.Length][]; for (int neuronNum = 0; neuronNum < layer.Length; neuronNum++) { Neuron neuron = layer[neuronNum]; float[] weightChanges = new float[neuron.Weight.Length]; for (int i = 0; i < neuron.Weight.Length; i++) { float deltaW = 0.0F; if (neuron.Type == Neuron.NeuronType.HiddenNeuron) { float delta_i = Delta_i(layers, layerNum, neuronNum, targetOutput); float activation_j = brain.AllLayers[layerNum][i].Activation; deltaW = DeltaW(TweakAmount, delta_i, activation_j); } else { float delta_i = Delta_i(neuron, targetOutput[neuronNum], Neuron.ReLU(neuron.Activation)); float activation_j = brain.AllLayers[layerNum][i].Activation; deltaW = DeltaW(TweakAmount, delta_i, activation_j); } if (!float.IsNaN(deltaW)) { weightChanges[i] = deltaW; neuron.Weight[i] += deltaW; } } neuronChanges[neuronNum] = weightChanges; } allChanges[layerNum] = neuronChanges; } return(allChanges); }
public object Clone() { Brain brain = new Brain(); brain.BrainStructureString = this.BrainStructureString; brain.Inputs = new Neuron[this.Inputs.Length]; brain.Outputs = new Neuron[this.Outputs.Length]; brain.HiddenLayers = new Neuron[this.HiddenLayers.Length][]; brain.AllLayers = new Neuron[this.AllLayers.Length][]; brain.activationFunction = this.activationFunction; for (int i = 0; i < Inputs.Length; i++) { brain.Inputs[i] = this.Inputs[i].Clone() as Neuron; } for (int i = 0; i < Outputs.Length; i++) { brain.Outputs[i] = this.Outputs[i].Clone() as Neuron; } for (int iter = 0; iter < HiddenLayers.Length; iter++) { brain.HiddenLayers[iter] = new Neuron[HiddenLayers[iter].Length]; for (int i = 0; i < HiddenLayers[iter].Length; i++) { brain.HiddenLayers[iter][i] = this.HiddenLayers[iter][i].Clone() as Neuron; } } Array.Copy(brain.HiddenLayers, 0, brain.AllLayers, 1, brain.HiddenLayers.Length); brain.AllLayers[0] = brain.Inputs; brain.AllLayers[AllLayers.Length - 1] = brain.Outputs; for (int iter = 0; iter < brain.AllLayers.Length; iter++) { for (int i = 0; i < brain.AllLayers[iter].Length; i++) { Neuron target = brain.AllLayers[iter][i]; if (target.Type != Neuron.NeuronType.OutputNeuron) { target.OutputConnections = brain.AllLayers[iter + 1]; } if (target.Type != Neuron.NeuronType.InputNeuron) { target.InputConnections = brain.AllLayers[iter - 1]; } if (target.Type == Neuron.NeuronType.InputNeuron) { target.InputConnections = new Neuron[] { target }; } if (target.Type == Neuron.NeuronType.OutputNeuron) { target.OutputConnections = new Neuron[] { target }; } } } return(brain); }