private Tuple <MyVector[], My2DMatrix[]> Backpropagate(MyVector input, MyVector diseredOutput, Cancel cancelFnc)
            {
                MyVector[]   parcDerivBiases  = new MyVector[NumOfLayers];
                My2DMatrix[] parcDerivWeights = new My2DMatrix[NumOfLayers];

                MyVector        activation  = new MyVector(input);
                List <MyVector> activations = new List <MyVector>(NumOfLayers)
                {
                    activation
                };

                // Feedfoward
                List <MyVector> weightedInputs = new List <MyVector>(NumOfLayers);

                for (int i = 1; i < NumOfLayers; i++)
                {
                    if (cancelFnc != null && cancelFnc())
                    {
                        return(null);
                    }
                    MyVector weightedInput = (m_weights[i] * activation) + m_biases[i];
                    weightedInputs.Add(weightedInput);
                    activation = weightedInput.ApplyFunction(Sigmoid);
                    activations.Add(activation);
                }

                // Backpropagate
                MyVector delta = CrossEntrophyDelta(activations[activations.Count - 1], diseredOutput);

                parcDerivBiases[parcDerivBiases.Length - 1]   = delta;
                parcDerivWeights[parcDerivWeights.Length - 1] = new My2DMatrix(delta, activations[activations.Count - 2]);
                for (int l = 2; l < NumOfLayers; l++)
                {
                    if (cancelFnc != null && cancelFnc())
                    {
                        return(null);
                    }
                    MyVector weightedInput = weightedInputs[weightedInputs.Count - l];
                    var      spv           = weightedInput.ApplyFunction(SigmoidPrime);
                    delta = (m_weights[m_weights.Length - l + 1].Transpose() * delta) * spv;
                    parcDerivBiases[parcDerivBiases.Length - l]   = delta;                                                         // the error
                    parcDerivWeights[parcDerivWeights.Length - l] = new My2DMatrix(delta, activations[activations.Count - l - 1]); // error times the activation from the previous layer (vector times vector^T creates  matrix)
                }
                return(new Tuple <MyVector[], My2DMatrix[]>(parcDerivBiases, parcDerivWeights));
            }