Esempio n. 1
0
        public static bool VerifyParametersGradient(LayerBase layer, int batchSize = 1)
        {
            Tensor.SetOpMode(Tensor.OpMode.CPU);
            var inputs = GenerateInputsForLayer(layer, batchSize);

            var output         = layer.FeedForward(inputs);
            var outputGradient = new Tensor(output.Shape);

            outputGradient.FillWithValue(1);

            layer.BackProp(outputGradient);

            var paramsAndGrads = layer.GetParametersAndGradients();

            if (paramsAndGrads.Count == 0)
            {
                return(true);
            }

            var result = new Tensor(output.Shape);

            var parameters = paramsAndGrads[0].Parameters;
            var gradients  = paramsAndGrads[0].Gradients;

            for (var i = 0; i < parameters.Shape.Length; i++)
            {
                result.Zero();

                float oldValue = parameters.GetFlat(i);
                parameters.SetFlat(oldValue + DERIVATIVE_EPSILON, i);
                var output1 = layer.FeedForward(inputs).Clone();
                parameters.SetFlat(oldValue - DERIVATIVE_EPSILON, i);
                var output2 = layer.FeedForward(inputs).Clone();

                parameters.SetFlat(oldValue, i);

                output1.Sub(output2, result);

                var approxGrad = new float[output.Shape.Length];
                for (int j = 0; j < output.Shape.Length; j++)
                {
                    approxGrad[j] = result.GetFlat(j) / (2.0f * DERIVATIVE_EPSILON);
                }

                var approxGradient = approxGrad.Sum();
                if (Math.Abs(approxGradient - gradients.GetFlat(i)) > 0.02)
                {
                    Debug.Assert(false, $"Parameter gradient validation failed at parameter {i}, expected {approxGradient} actual {gradients.GetFlat(i)}!");
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 2
0
        public static bool VerifyInputGradient(LayerBase layer, int batchSize = 1)
        {
            Tensor.SetOpMode(Tensor.OpMode.CPU);
            var inputs = GenerateInputsForLayer(layer, batchSize);

            var output         = layer.FeedForward(inputs);
            var outputGradient = new Tensor(output.Shape);

            outputGradient.FillWithValue(1);

            layer.BackProp(outputGradient);

            var result = new Tensor(output.Shape);

            for (int n = 0; n < inputs.Length; ++n)
            {
                var input = inputs[n];
                for (int i = 0; i < input.Shape.Length; ++i)
                {
                    result.Zero();

                    var oldValue = input.GetFlat(i);

                    input.SetFlat(oldValue - DERIVATIVE_EPSILON, i);
                    var output1 = layer.FeedForward(inputs).Clone();
                    input.SetFlat(oldValue + DERIVATIVE_EPSILON, i);
                    var output2 = layer.FeedForward(inputs).Clone();

                    input.SetFlat(oldValue, i);

                    output2.Sub(output1, result);

                    var   approxGrad     = new float[output.Shape.Length];
                    float approxGradient = 0;
                    for (int j = 0; j < output.Shape.Length; j++)
                    {
                        approxGrad[j]   = result.GetFlat(j) / (2.0f * DERIVATIVE_EPSILON);
                        approxGradient += approxGrad[j];
                    }

                    if (Math.Abs(approxGradient - layer.InputsGradient[n].GetFlat(i)) > 0.02)
                    {
                        Debug.Assert(false, $"Input gradient validation failed at element {i} of input {n}, expected {approxGradient} actual {layer.InputsGradient[n].GetFlat(i)}!");
                        return(false);
                    }
                }
            }

            return(true);
        }