/// <summary> Test function to iterate through all learning rates and momentums with different numbers of neurons and layers. </summary>
        private void RateTestBtn_Click(object sender, EventArgs e)
        {
            //Setup paths and lists.
            string dataFile = "";
            string path     = "";

            //Normalise file.
            List <string> outputTitles = GetFile(false, ref path, ref dataFile, (int)(outputsUpDown.Value));

            if (outputTitles == null)
            {
                return;
            }

            //False when percentage split, true when cross validation.
            bool validation = true;

            //Save network to file.
            if (!Directory.Exists(path + "tests"))
            {
                Directory.CreateDirectory(path + "tests");
            }

            string header = path + "tests" + @"\Results" + dataFile;

            using (StreamWriter sw = new StreamWriter(header))
            {
                sw.WriteLine(String.Format("Error,Network Type,Layers,Neurons,Learning Rate,Momentum"));
            }

            // initialize input and output values.
            Data info = new Data(); info = info.ReturnInfo(path + @"normal\" + dataFile.Replace(".csv", "Normal.csv"), outputTitles, sampleBar.Value, validation);

            if (info == null)
            {
                return;
            }

            //Setup network.
            List <NeuralNetwork> networkList = new List <NeuralNetwork>
            {
                new EncogNeuralNetwork(),
                new EncogDeepNeuralNetwork(),
                new AccordNeuralNetwork(),
                new AccordDeepNeuralNetwork()
            };

            List <BestNetwork> bestList = new List <BestNetwork>();

            foreach (NeuralNetwork network in networkList)
            {
                bestList.Add(network.CalculateBest(info, header));
            }

            BestNetwork best = bestList[0];

            int index = 0;
            int count = 0;

            foreach (BestNetwork b in bestList)
            {
                double error = b.Error;

                if (error < best.Error)
                {
                    best  = b;
                    index = count;
                }

                count++;
            }

            output.Text += "The best netork is: " + networkList[index].GetType().ToString().Replace("ENP1.", "")
                           + "\nLayers: " + best.Layers + "\nNeurons: " + best.Neurons + "\nLearning Rate: " + best.LearningRate
                           + "\nMomentum: " + best.Momentum + "\nInaccuracy: " + best.Error;
        }
        private BestNetwork BestLearningRate(Data info, string path, int layers, int neurons)
        {
            float lr        = 0.1F;
            bool  complete  = false;
            bool  firstPass = true;
            bool  increase  = true;

            BestNetwork best = BestMomentum(info, path, layers, neurons, lr);

            while (!complete)
            {
                if (firstPass)
                {
                    lr = 0.5F;
                }
                else if (increase)
                {
                    lr += 0.1F;
                }
                else
                {
                    lr -= 0.1F;
                }

                if (Math.Round(lr, 1) == 0.1F || Math.Round(lr, 1) == 1.0F)
                {
                    complete = true;
                }

                BestNetwork newest = BestMomentum(info, path, layers, neurons, lr);

                if (firstPass)
                {
                    if (newest.Error < best.Error)
                    {
                        best     = newest;
                        increase = true;
                    }
                    else if (newest.Error == best.Error)
                    {
                        complete = true;
                    }
                    else
                    {
                        increase = false;
                    }

                    firstPass = false;
                }
                else
                {
                    if (newest.Error < best.Error)
                    {
                        best = newest;
                    }
                    else
                    {
                        complete = true;
                    }
                }
            }

            return(best);
        }
        private BestNetwork BestMomentum(Data info, string path, int layers, int neurons, float lr)
        {
            bool complete  = false;
            bool firstPass = true;
            bool increase  = true;

            BestNetwork best = new BestNetwork
            {
                Momentum     = 0.1F,
                LearningRate = lr,
                Neurons      = neurons,
                Layers       = layers
            };

            best.Error = Train(info, lr, best.Momentum);

            while (!complete)
            {
                if (firstPass)
                {
                    best.Momentum = 0.5F;
                }
                else if (increase)
                {
                    best.Momentum += 0.1F;
                }
                else
                {
                    best.Momentum -= 0.1F;
                }

                if (Math.Round(best.Momentum, 1) == 0.1F || Math.Round(best.Momentum, 1) == 1.0F)
                {
                    complete = true;
                }

                double newest = Train(info, lr, best.Momentum);

                if (firstPass)
                {
                    if (newest < best.Error)
                    {
                        best.Error = newest;
                        increase   = true;
                    }
                    else if (newest == best.Error)
                    {
                        complete = true;
                    }
                    else
                    {
                        increase = false;
                    }

                    firstPass = false;
                }
                else
                {
                    if (newest < best.Error)
                    {
                        best.Error = newest;
                    }
                    else
                    {
                        complete = true;
                    }
                }
            }

            using (StreamWriter sw = new StreamWriter(path, true))
            {
                sw.WriteLine(String.Format(
                                 "{0},{1},{2},{3},{4},{5}", best.Error, GetType().ToString().Replace("ENP1.", ""), layers, neurons, Math.Round(lr, 1), Math.Round(best.Momentum, 1))); //"ENP1" must change to reflect solution name (name.) if ever changed.
            }

            return(best);
        }
        public BestNetwork CalculateBest(Data info, string path)
        {
            int  layers    = 1;
            bool complete  = false;
            bool firstPass = true;
            bool increase  = true;

            BestNetwork best = BestNeurons(info, path, layers);;

            if (GetType().ToString().Replace("ENP1.", "") == "EncogDeepNeuralNetwork")
            {
                return(best);
            }

            while (!complete)
            {
                if (firstPass)
                {
                    layers = 2;
                }
                else if (increase)
                {
                    layers += 1;
                }
                else
                {
                    layers -= 1;
                }

                if (layers == 1 || layers == 5)
                {
                    complete = true;
                }

                BestNetwork newest = BestNeurons(info, path, layers);

                if (firstPass)
                {
                    if (newest.Error < best.Error)
                    {
                        best     = newest;
                        increase = true;
                    }
                    else if (newest.Error == best.Error)
                    {
                        complete = true;
                    }
                    else
                    {
                        increase = false;
                    }

                    firstPass = false;
                }
                else
                {
                    if (newest.Error < best.Error)
                    {
                        best = newest;
                    }
                    else
                    {
                        complete = true;
                    }
                }
            }

            return(best);
        }
        private BestNetwork BestNeurons(Data info, string path, int layers)
        {
            int  neurons   = 5;
            bool complete  = false;
            bool firstPass = true;
            bool increase  = true;

            Create(info.InputNumber, layers, neurons, info.OutputNumber);
            BestNetwork best = BestLearningRate(info, path, layers, neurons);

            while (!complete)
            {
                if (firstPass)
                {
                    neurons = 25;
                }
                else if (increase)
                {
                    neurons += 5;
                }
                else
                {
                    neurons -= 5;
                }

                if (neurons == 5 || neurons == 50)
                {
                    complete = true;
                }

                Create(info.InputNumber, layers, neurons, info.OutputNumber);
                BestNetwork newest = BestLearningRate(info, path, layers, neurons);

                if (firstPass)
                {
                    if (newest.Error < best.Error)
                    {
                        best     = newest;
                        increase = true;
                    }
                    else if (newest.Error == best.Error)
                    {
                        complete = true;
                    }
                    else
                    {
                        increase = false;
                    }

                    firstPass = false;
                }
                else
                {
                    if (newest.Error < best.Error)
                    {
                        best = newest;
                    }
                    else
                    {
                        complete = true;
                    }
                }
            }

            return(best);
        }