public Layer(LayerCreationInfo layerCreationInfo, bool IsNetworkUsingBias, LayerType type, double minWeight, double maxWeight) { LayerNo = layerCreationInfo.LayerNo; PreviousLayerNeuronsCount = layerCreationInfo.PreviousLayerNeuronsCount; LayerActivationFunction = layerCreationInfo.LayerActivationFunction; this.Type = type; this.MinWeight = minWeight; this.MaxWeight = maxWeight; Neurons = new List <Neuron>(); for (int i = 0; i < layerCreationInfo.HowManyNeuronsPerLayer; i++) { Neurons.Add(new Neuron( LayerNo == 0 ? 1 : PreviousLayerNeuronsCount, layerCreationInfo.LayerNo, false, layerCreationInfo.LayerActivationFunction, MinWeight, MaxWeight)); } if (IsNetworkUsingBias && type != LayerType.OUTPUT) { Neurons.Last().IsBias = true; } }
public static double Derivative(double x, NeuralNetwork.ActivationFunction activationFunction) { switch (activationFunction) { case NeuralNetwork.ActivationFunction.SIGMOID: return(DerivativeSigmoid(x)); case NeuralNetwork.ActivationFunction.TANH: return(DerivativeTanh(x)); default: throw new Exception("Counting derivative for not implemented case"); } }
public static double ActivationFunction(double value, NeuralNetwork.ActivationFunction activationFunction) { double result = 0.0; switch (activationFunction) { case NeuralNetwork.ActivationFunction.TANH: // someone says: "approximation is correct to 30 decimals", so: if (value < -20.0) { result = -1.0; } else if (value > 20.0) { result = 1.0; } else { result = Math.Tanh(value); } break; case NeuralNetwork.ActivationFunction.SIGMOID: result = 1.0 / (1.0 + Math.Exp(-value)); break; case NeuralNetwork.ActivationFunction.SINUSOID: result = Math.Sin(value); break; case NeuralNetwork.ActivationFunction.BINARY_STEP: result = value < 0 ? 0 : 1; break; case NeuralNetwork.ActivationFunction.NO_FUNCTION: result = value; break; default: throw new Exception("Function " + activationFunction.ToString() + "not implemented in CountOutput!"); } return(result); }
public Neuron(int inputsCount, int layerNo, bool isBias, NeuralNetwork.ActivationFunction activationFunction, double biasValue = -1.0) { IsBias = isBias; BiasValue = biasValue; LayerNo = layerNo; this.ActivationFunction = activationFunction; Inputs = new List <Input>(); PreviousInputs = new List <Input>(); for (int inputNo = 0; inputNo < inputsCount; inputNo++) { Inputs.Add(new Input(inputNo)); PreviousInputs.Add(new Input(inputNo)); } ResetNeuron(); }
private static void LearnNetworkOption() { long DEFAULT_MAX_EPOCH_NO = 10000; long DEFAULT_COLLECT_SPARSE_HISTORY_EVERY = 1000; double DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP = 0.99; int inputCount = 2; int outputCount = 1; List <int> defaultHiddenLayersNeuronsCount = new List <int> { 20, 20 }; List <int> hiddenLayersNeuronsCount = new List <int>(); String filename = "data.csv"; String str = null; bool networkUseBias = true; NeuralNetwork.ActivationFunction activationFunction = NeuralNetwork.ActivationFunction.NO_FUNCTION; double learningRatio = 0.1; double momentum = 0.7; double minErrorPercentageToStop = DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP; long maxEpochNo = 0; long writeOnConsoleEveryEpoch = 1000; bool randomOrderOfLearningData = true; List <LearnSample> learningData = new List <LearnSample>(); long collectSparseHistoryEvery = 1000; bool dataLoopRunning = true; List <Layer> layers = new List <Layer>(); #region Data preparation while (dataLoopRunning) { learningRatio = 0.1; //minErrorPercentageToStop = DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP; filename = "data.csv"; Console.Clear(); Console.WriteLine("Creating and learning Neural Networks"); bool ok = false; while (!ok) { Console.Write("Input neurons count: "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : inputCount.ToString(); ok = int.TryParse(str, out inputCount); if (ok) { ok = (inputCount > 0); } if (!ok) { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Hidden layers neurons count, coma sepparated: [20, 20] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; ok = true; if (str.Length > 0) { String[] tab = str.Split(','); for (int i = 0; i < tab.Length; i++) { int val = 0; ok = int.TryParse(tab[i], out val); if (ok) { ok = (val > 0); } if (!ok) { break; } hiddenLayersNeuronsCount.Add(val); } } else { hiddenLayersNeuronsCount = defaultHiddenLayersNeuronsCount; } if (!ok) { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Output neurons count: "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : outputCount.ToString(); ok = int.TryParse(str, out outputCount); if (ok) { ok = (outputCount > 0); } if (!ok) { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Activation function of neurons Sigmoid/Tanh: [S/t] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; str = str.ToLower(); if (str.Length == 0) { str = "s"; } ok = (str == "s" || str == "t"); if (ok) { activationFunction = (str == "s") ? NeuralNetwork.ActivationFunction.SIGMOID : NeuralNetwork.ActivationFunction.TANH; } else { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Using bias? [n/Y] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; str = str.ToLower(); if (str.Length == 0) { str = "y"; } ok = (str == "n" || str == "y"); if (ok) { networkUseBias = (str == "y"); } else { Console.WriteLine("This value is not allowed."); } } Console.WriteLine("What should stops learning?"); Console.WriteLine("0 - minimum percentage error or maximum number of epochs"); Console.WriteLine("1 - minimum percentage error"); Console.WriteLine("2 - maximum number of epochs"); Console.WriteLine("3 - only F2 key"); ok = false; while (!ok) { int choice = 0; Console.Write("Your choice? [3] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; if (str.Length == 0) { choice = 3; ok = true; } else { ok = int.TryParse(str, out choice); } if (ok) { switch (choice) { case 0: ok = false; while (!ok) { Console.Write("Maximum number of epochs: [" + DEFAULT_MAX_EPOCH_NO + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; if (str.Length > 0) { ok = long.TryParse(str, out maxEpochNo); if (ok) { ok = (maxEpochNo > 0); } } else { maxEpochNo = DEFAULT_MAX_EPOCH_NO; ok = true; } if (!ok) { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Minimum percentage error: [" + DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; if (str.Length > 0) { ok = double.TryParse(str, out minErrorPercentageToStop); if (ok) { ok = (minErrorPercentageToStop > 0); } } else { minErrorPercentageToStop = DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP; ok = true; } if (!ok) { Console.WriteLine("This value is not allowed."); } } break; case 1: ok = false; while (!ok) { Console.Write("Minimum percentage error: [" + DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; if (str.Length > 0) { ok = double.TryParse(str, out minErrorPercentageToStop); if (ok) { ok = (minErrorPercentageToStop > 0); } } else { minErrorPercentageToStop = DEFAULT_MIN_ERR_PERCENTAGE_TO_STOP; ok = true; } if (!ok) { Console.WriteLine("This value is not allowed."); } } maxEpochNo = 0; break; case 2: ok = false; while (!ok) { Console.Write("Maximum number of epochs: [" + DEFAULT_MAX_EPOCH_NO + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; if (str.Length > 0) { ok = long.TryParse(str, out maxEpochNo); if (ok) { ok = (maxEpochNo > 0); } } else { maxEpochNo = DEFAULT_MAX_EPOCH_NO; ok = true; } if (!ok) { Console.WriteLine("This value is not allowed."); } } minErrorPercentageToStop = 0; break; case 3: minErrorPercentageToStop = 0; maxEpochNo = 0; break; default: ok = false; break; } } if (!ok) { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Learning ratio: [" + learningRatio + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; str = str.Replace('.', ','); double newLearningRatio = learningRatio; if (str.Length > 0) { ok = double.TryParse(str, out newLearningRatio); if (ok) { ok = (newLearningRatio > 0); } } else { ok = true; } if (ok) { learningRatio = newLearningRatio; } else { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Momentum: [" + momentum + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; str = str.Replace('.', ','); double newMomentum = momentum; if (str.Length > 0) { ok = double.TryParse(str, out newMomentum); if (ok) { ok = (newMomentum > 0); } } else { ok = true; } if (ok) { momentum = newMomentum; } else { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("Should the order of the learning data be random? [n/Y] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; str = str.ToLower(); if (str.Length == 0) { str = "y"; } ok = (str == "n" || str == "y"); if (ok) { randomOrderOfLearningData = (str == "y"); } else { Console.WriteLine("This value is not allowed."); } } ok = false; while (!ok) { Console.Write("File with learning data: [" + filename + "] "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; if (str.Length == 0) { str = filename; } FileInfo fi = new FileInfo(str); ok = fi.Exists; if (!ok) { Console.WriteLine("File not exists."); } else { filename = str; Console.WriteLine("Loading teaching elements from file..."); ok = LoadTeachingElements(inputCount, outputCount, out learningData, filename); if (ok) { Console.WriteLine("Teaching elements loaded."); dataLoopRunning = false; } else { Console.Write("Do you want to provide new data [d] or try another file [F]? "); str = TAKE_PARAMETERS_FROM_USER ? Console.ReadLine() : ""; str = str.ToLower(); if (str.Length == 0) { str = "f"; } ok = (str == "d" || str == "f"); if (ok) { if (str == "f") { ok = false; } else { break; } } else { Console.WriteLine("This value is not allowed."); } } } } } #endregion #region Layers creation int layerNo = 0; LayerCreationInfo inputLci = new LayerCreationInfo(); inputLci.HowManyNeuronsPerLayer = inputCount + (networkUseBias ? 1 : 0); inputLci.LayerActivationFunction = activationFunction; inputLci.LayerNo = layerNo++; inputLci.PreviousLayerNeuronsCount = 0; layers.Add(new Layer(inputLci, networkUseBias, Layer.LayerType.INPUT, -0.5, +0.5)); foreach (int hiddenLayerNeurons in hiddenLayersNeuronsCount) { LayerCreationInfo hiddenLci = new LayerCreationInfo(); hiddenLci.HowManyNeuronsPerLayer = hiddenLayerNeurons + (networkUseBias ? 1 : 0); hiddenLci.LayerActivationFunction = activationFunction; hiddenLci.PreviousLayerNeuronsCount = layers.ElementAt(layerNo - 1).Neurons.Count; hiddenLci.LayerNo = layerNo++; layers.Add(new Layer(hiddenLci, networkUseBias, Layer.LayerType.HIDDEN, -0.5, +0.5)); } LayerCreationInfo outputLci = new LayerCreationInfo(); outputLci.HowManyNeuronsPerLayer = outputCount; outputLci.LayerActivationFunction = activationFunction; outputLci.PreviousLayerNeuronsCount = layers.ElementAt(layerNo - 1).Neurons.Count; outputLci.LayerNo = layerNo++; layers.Add(new Layer(outputLci, networkUseBias, Layer.LayerType.OUTPUT, -0.5, +0.5)); #endregion NeuralNetwork neuralNetwork = new NeuralNetwork( new Topology() { Layers = layers, IsNetworkUsingBiases = networkUseBias, OutputCount = outputCount }, -0.5, +0.5, NeuralNetwork.LearningMethod.NOT_LINEAR, "NN", collectSparseHistoryEvery ); LearnNetwork(neuralNetwork, networkUseBias, learningData, learningRatio, momentum, minErrorPercentageToStop, maxEpochNo, randomOrderOfLearningData, writeOnConsoleEveryEpoch, true); String prefix = DateTime.Now.ToString("yyyyMMdd_HHmmss"); String saveNetworkFilename = prefix + "_Network.nnc"; String saveErrorsFilename = prefix + "_Errors.csv"; neuralNetwork.SaveNetworkToFile(saveNetworkFilename); // neuralNetwork.SaveErrorsToFile(saveErrorsFilename); Console.WriteLine(); Console.Write("Press any key to go to main menu... "); Console.ReadKey(); }
public Neuron(double value, NeuralNetwork.ActivationFunction activationFunction) { Value = activationFunction(value); }