/// <summary> /// Clones the neuron /// </summary> /// <param name="neuron"></param> public Neuron(Neuron neuron) { _weights = new List <double>(neuron._weights); }
public Weight(Neuron input, double value) { this.inputNeuron = input; this.value = value; }
public Link(double value, Neuron source) { Value = value; SourceNeuron = source; }
public void AddLink(double value, Neuron source) { Links.Add(new Link(value, source)); }
/// <summary> /// Creates the network. /// </summary> /// <param name="NeuronsAndLayers">The struct of the network. For instance, "4+ 15+ 5 3" whare '+' means bias. Watch readme</param> /// <param name="randMin">Minimal random weight of synapse.</param> /// <param name="randMax">Maximal random weight of synapse.</param> public NeuralNetwork(string NeuronsAndLayers, double randMin, double randMax) { Random rand = new Random(); string[] neuronsSTR = NeuronsAndLayers?.Split(' '); Network = new Neuron[neuronsSTR.Length][]; withoutBiasLength = new uint[neuronsSTR.Length]; System.Collections.ArrayList biases = new System.Collections.ArrayList(); for (i = 0; i < neuronsSTR.Length; ++i) //Count of neurons in each layer { try //Check if there are biases { uint index = Convert.ToUInt32(neuronsSTR[i]); Network[i] = new Neuron[index]; withoutBiasLength[i] = index; } catch (Exception) //If bias is in the layer then { if (i == neuronsSTR.Length - 1) { throw new Exception("You cannot add biases to OUTPUT layers"); } else { biases.Add(i); uint index = Convert.ToUInt32(neuronsSTR[i].Substring(0, neuronsSTR[i].Length - 1)) + 1; Network[i] = new Neuron[index]; //Convert only count of neurons without bias(+) Network[i][index - 1].value = 1; withoutBiasLength[i] = index - 1; } } } previousWeights = new double[Network.Length][]; //Distribution of values in weights of Neural Network and initializing PreviousWeights for (i = 0; i < Network.Length - 1; ++i) // Every layer in this NeuralNetwork { previousWeights[i] = new double[Network[i].Length * withoutBiasLength[i + 1]]; uint countOfWeights = 0; for (j = 0; j < Network[i].Length; ++j) // Every neuron in layer[i] { Network[i][j].weights = new double[withoutBiasLength[i + 1]]; for (uint a = 0; a < Network[i][j].weights.Length; ++a) // Every weight from neuron[i][j] { previousWeights[i][countOfWeights] = 0; //PrewiosWeight on the first iteration = 0 ++countOfWeights; weightWasZeroREPEAT: Network[i][j].weights[a] = Math.Round(rand.NextDouble() * (randMax - randMin) + randMin, 5); //Random value for the weight if (Network[i][j].weights[a] == 0) { goto weightWasZeroREPEAT; //Value of weight cannot be 0 } } } } //Creating a copy of NeuralNetwork to work with it deltaNetwork = new Neuron[Network.Length][]; for (i = 0; i < Network.Length; ++i) { deltaNetwork[i] = new Neuron[Network[i].Length]; for (j = 0; j < Network[i].Length; ++j) { deltaNetwork[i][j] = Network[i][j]; } } }
private static void train() { double[,] inputs = { { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, { 0, 1, 0 }, { 0, 1, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 1, 1 }, { 0, 0, 0 } }; // desired results double[] results = { 1, 1, 2, 3, 2, 3, 3, 1, 2 }; double max = -1; // find max value for (int i = 0; i < results.Length; i++) { if (results[i] > max) { max = results[i]; } } // normalizing for (int i = 0; i < results.Length; i++) { results[i] /= max; } // creating the neurons List <Neuron> hiddenNeurons = new List <Neuron>(numberOfneurons); for (int i = 0; i < numberOfneurons; i++) { hiddenNeurons.Add(new Neuron()); } Neuron outputNeuron = new Neuron(); // random weights foreach (Neuron hiddenNeuron in hiddenNeurons) { hiddenNeuron.randomizeWeights(); } outputNeuron.randomizeWeights(); int epoch = 0; Retry: epoch++; for (int i = 0; i < inputs.GetLength(0); i++) { // 1) forward propagation (calculates output) outputNeuron.inputs = fillIN(inputs[i, 0], inputs[i, 1], inputs[i, 2], hiddenNeurons); Console.WriteLine("{0} and {1} and {2} = {3}", inputs[i, 0], inputs[i, 1], inputs[i, 2], outputNeuron.output * numberOfneurons); // 2) back propagation (adjusts weights) // adjusts the weight of the output neuron, based on its error outputNeuron.error = sigmoid.derivative(outputNeuron.output) * (results[i] - outputNeuron.output); outputNeuron.adjustWeights(); // then adjusts the hidden neurons' weights, based on their errors for (int j = 0; j < numberOfneurons; j++) { hiddenNeurons[j].error = sigmoid.derivative(hiddenNeurons[j].output) * outputNeuron.error * outputNeuron.weights[j]; } foreach (Neuron hiddenNeuron in hiddenNeurons) { hiddenNeuron.adjustWeights(); } } if (epoch < 10000) { goto Retry; } Console.WriteLine(); Console.WriteLine("Network have been trained successfully"); while (true) { Console.WriteLine("________________________"); Console.WriteLine("Print your binary values"); Console.Write("value 1: "); int value1 = Convert.ToInt32(Console.ReadLine()); Console.Write("value 2: "); int value2 = Convert.ToInt32(Console.ReadLine()); Console.Write("value 3: "); int value3 = Convert.ToInt32(Console.ReadLine()); outputNeuron.inputs = fillIN(value1, value2, value3, hiddenNeurons); Console.WriteLine("result : " + (outputNeuron.output * max).ToString("0")); } }