private void BackPropagate(params double[] targets)
        {
            NumCalc++;

            int actual = targets.ToList().IndexOf(targets.Max());

            double[] outputs   = OutputLayer.Select(a => a.Value).ToArray();
            int      predicted = outputs.ToList().IndexOf(outputs.Max());

            if (actual == predicted)
            {
                Accuracy += 1;
            }

            int i = 0;

            OutputLayer.ForEach(a => a.CalculateGradient(targets[i++]));
            HiddenLayers.Reverse();
            HiddenLayers.ForEach(a => a.AsParallel().ForAll(b => b.CalculateGradient()));
            HiddenLayers.ForEach(a => a.AsParallel().ForAll(b => b.UpdateWeights(LearnRate, Momentum)));
            HiddenLayers.Reverse();
            OutputLayer.AsParallel().ForAll(a => a.UpdateWeights(LearnRate, Momentum));

            i = 0;
            double error = OutputLayer.Sum(a => Math.Abs(a.CalculateError(targets[i++])));

            Error += error;

            if (NumCalc % 1000 == 0)
            {
                Console.WriteLine($"Error: {Error / 1000 / 10} NumCalc: {NumCalc} Accuracy: {Accuracy / 10.0}");
                Error    = 0;
                Accuracy = 0;
            }
        }
        private void ForwardPropagate(params double[] inputs)
        {
            int i = 0;

            InputLayer.ForEach(a => a.Value = inputs[i++]);
            HiddenLayers.ForEach(a => a.AsParallel().ForAll(b => b.CalculateValue()));
            OutputLayer.AsParallel().ForAll(a => a.CalculateValue());
        }