private void TrainPersonNeuralNetwork(
            Dictionary<Person, List<double[]>[]> trainingMfccs,
            Dictionary<Person, List<double[]>[]> testMfccs,
            double[] input, double[][] answer, Person person,
            PerceptronWrapper network)
        {
            GnuPlot plot = new GnuPlot(
                person.FullName,
                @"D:\GIT\nnetwork_mini_pw\charts\plot_" + person.FullName.Replace(' ', '_') + ".png"
                );
            plot.BeginPlot();

            List<double[]>[] personMfccs = null;
            int iterations = 0;

            while (iterations < MaxIterationCounts) {
                double expectedAnswer;

                if (Random.NextDouble() < algorithmParams.TCoef) {
                    expectedAnswer      = 0.0d;
                    Person otherPerson  = SelectOtherPerson(person);
                    personMfccs         = trainingMfccs[otherPerson];
                }
                else {
                    expectedAnswer      = 1.0d;
                    personMfccs         = trainingMfccs[person];
                }

                DrawInputData(input, personMfccs);

                double scale            = Math.Sqrt(1.0 + iterations);
                double newLearningRate  = algorithmParams.LearningRate / scale;
                double newMomentum      = algorithmParams.Momentum / scale;

                answer[0][0] = expectedAnswer;
                network.Train(newLearningRate, 1, newMomentum,
                    new[] { input },
                    answer);

                iterations++;

                if (iterations % 1000 == 0) {
                    double testResult   = TestPersonNeuralNetwork(person, testMfccs, input);
                    double learnResult  = TestPersonNeuralNetwork(person, trainingMfccs, input);
                    AddPlotPoint(plot, iterations, learnResult, testResult);

                    if (testResult <= TestSetMaxError)
                    {
                        break;
                    }
                }
            }

            plot.AddAlgorithmParamsToTitle(algorithmParams);
            plot.End2Plot();
        }
        private double TestPersonNeuralNetwork(Person testedPerson, Dictionary<Person, List<double[]>[]> testSet, double[] input)
        {
            PerceptronWrapper   network     = neuralNetworks[testedPerson];
            double              error       = 0.0;
            int                 testCases   = 0;

            foreach (Person person in people) {
                double  answer          = (person == testedPerson) ? 1.0 : 0.0;
                var     personTestSet   = testSet[person];

                foreach (var testFile in personTestSet) {
                    var testArray = testFile.ToArray();

                    for (int inputBegining = 0; inputBegining < testArray.Length - algorithmParams.SignalFramesCount; inputBegining++) {

                        CopyInputData(input, testArray, inputBegining);
                        double networkAnswer = network.Compute(new[] { input })[0][0];

                        if (answer > THRESHOLD || answer < (1.0f - THRESHOLD)) {
                            error += Math.Pow(answer - networkAnswer, 2.0f);
                            testCases++;
                        }
                    }
                }
            }

            return error / testCases;
        }
 private static string GetRecognitionPlotFileName(Person person)
 {
     return @"D:\GIT\nnetwork_mini_pw\charts\rplot_" + person.FullName.Replace(' ', '_') + ".png";
 }
        /// <summary>
        /// Losowo wybiera osobe rozna od przekazanej jako parametr.
        /// </summary>
        /// <param name="person"></param>
        /// <returns></returns>
        private Person SelectOtherPerson(Person person)
        {
            int     otherPersonIndex    = Random.Next(people.Count);
            Person  otherPerson         = people[otherPersonIndex];

            if (otherPerson == person) {
                int otherPersonsCount   = people.Count - 1;
                Debug.Assert(otherPersonsCount >= 1);

                int newOtherPersonIndex = otherPersonIndex + Random.Next(otherPersonsCount) + 1;
                otherPerson = people[newOtherPersonIndex % people.Count];
            }

            return otherPerson;
        }
 private void AddNewPerson()
 {
     var newPerson = new Person {FirstName = "Neural", SurName = "Network"};
     people.Add(newPerson);
     People.MoveCurrentTo(newPerson);
 }