private void BackwardsPhase(double[] outputs, double[,] hiddenResults, double eta)
        {
            var deltasOs = _algorithm.ProcessDeltaOs(outputs, _trainingTargets);

            var deltasHs = new Double[hiddenResults.RowLength(), hiddenResults.ColumnLength()];

            for (int i = 0; i < deltasHs.RowLength(); i++)
            {
                for (int j = 0; j < deltasHs.ColumnLength(); j++)
                {
                    // deltasHs[i, j] = deltasHs[i, j] + hiddenResults[i, j] * deltasOs[i] * _outputWeights[j];
                    var deltaOWeight = deltasOs[i] * _outputWeights[j];
                    deltasHs[i, j] = hiddenResults[i, j] * _beta * (1 - hiddenResults[i, j]) * deltaOWeight;
                    var infinity = deltasHs[i, j];
                    if (double.IsNegativeInfinity(infinity))
                    {
                        deltasHs[i, j] = double.MinValue;
                    }
                    else if (double.IsPositiveInfinity(infinity))
                    {
                        deltasHs[i, j] = double.MaxValue;
                    }
                }
            }

            for (int i = 0; i < _hiddenWeights.RowLength(); i++)
            {
                for (int j = 0; j < _hiddenWeights.ColumnLength(); j++)
                {
                    double fullUpdate = 0;
                    for (int k = 0; k < _trainingInput.RowLength(); k++)
                    {
                        var update = eta * _trainingInput[k, i] * deltasHs[k, j];
                        fullUpdate += update;
                        var infinity = fullUpdate;
                        if (double.IsNegativeInfinity(infinity))
                        {
                            fullUpdate = double.MinValue;
                        }
                        else if (double.IsPositiveInfinity(infinity))
                        {
                            fullUpdate = double.MaxValue;
                        }
                    }
                    var momentum = _momentum * _lastHiddenUpdates[i, j];
                    fullUpdate += momentum;
                    _lastHiddenUpdates[i, j] = fullUpdate;
                    _hiddenWeights[i, j]     = _hiddenWeights[i, j] - fullUpdate;
                    var infinity1 = _hiddenWeights[i, j];
                    if (double.IsNegativeInfinity(infinity1))
                    {
                        _hiddenWeights[i, j] = double.MinValue;
                    }
                    else if (double.IsPositiveInfinity(infinity1))
                    {
                        _hiddenWeights[i, j] = double.MaxValue;
                    }
                }
            }

            for (int i = 0; i < _outputWeights.Length; i++)
            {
                double fullUpdate = 0;
                for (int k = 0; k < hiddenResults.RowLength(); k++)
                {
                    var update = eta * hiddenResults[k, i] * deltasOs[k];
                    fullUpdate += update;
                }
                var momentum = _momentum * _lastOutputUpdates[i];
                fullUpdate += momentum;

                var infinity = fullUpdate;
                if (double.IsNegativeInfinity(infinity))
                {
                    fullUpdate = double.MinValue;
                }
                else if (double.IsPositiveInfinity(infinity))
                {
                    fullUpdate = double.MaxValue;
                }

                _outputWeights[i]     = _outputWeights[i] - fullUpdate;
                _lastOutputUpdates[i] = fullUpdate;

                var infinity1 = _outputWeights[i];
                if (double.IsNegativeInfinity(infinity1))
                {
                    _outputWeights[i] = double.MinValue;
                }
                else if (double.IsPositiveInfinity(infinity1))
                {
                    _outputWeights[i] = double.MaxValue;
                }
            }
        }