private void TrainNetwork(ref NetworkTrainingParameters parameters)
 {
     ComputeOutputGradients(parameters.ExpectedResult, parameters.OutputGradients);
     ComputeHiddenGradients(parameters.OutputGradients, parameters.HiddenGradients);
     UpdateHiddenWeights(parameters.LeaningRate, parameters.Momentum, parameters.HiddenGradients);
     UpdateHiddenBiases(parameters.LeaningRate, parameters.Momentum, parameters.HiddenGradients);
     UpdateHiddenOutputWeights(parameters.LeaningRate, parameters.Momentum, parameters.OutputGradients);
     UpdateOutputBiases(parameters.LeaningRate, parameters.Momentum, parameters.OutputGradients);
 }
        public void Train(NeuralNetworkTrainingData data)
        {
            var trainingParameters = new NetworkTrainingParameters(_numberOfOutputNodes, _numberOfHiddenNodes)
            {
                LeaningRate = data.LearnRate,
                Momentum = data.Momentum
            };

            var inputVector = new double[_numberOfInputNodes];

            for (var i = 0; i < data.MaxEpochs; i++)
            {
                var sequence = NeuralNetworkHelpers.Randomize(data.TrainingData.Length);

                foreach(var index in sequence)
                {
                    Array.Copy(data.TrainingData[index], inputVector, _numberOfInputNodes);
                    Array.Copy(data.TrainingData[index], _numberOfInputNodes, trainingParameters.ExpectedResult, 0, _numberOfOutputNodes);

                    ComputeOutputs(inputVector);
                    TrainNetwork(ref trainingParameters);
                }
            }
        }