Нейронная сеть в C # - NaNs и Infinity - PullRequest
0 голосов
/ 28 декабря 2018

Может быть, кто-то здесь, я могу помочь мне.Я немного застрял.Прямо сейчас я пытаюсь написать свою собственную нейронную сеть на C #.Я получил это работает несколько (это работает с XOR).Это простая нейронная сеть с входом, скрытием и выводом, и я использую ReLU в качестве функции активации.Моя проблема в том, что когда я увеличиваю количество Скрытых Слоев до значения, превышающего ~ 16, я, как правило, получаю немного NaN или Infinites, что довольно быстро все запутывает.Я пытался уменьшить скорость обучения, но это не помогает.Я думаю, что проблема где-то в моей функции SGD, но я не могу ее найти, особенно потому, что она работает с меньшим количеством слоев.

Это функция:

private void SGD(double learningRate, double[] weightedSumHidden, double[] errors_output)
    {
        /*---------------------------------------------------------------
        * -- Calculate Delta of the weight between hidden and output --
        ---------------------------------------------------------------*/
        var HiddenTransposed = Hidden.Transpose();
        var deltaWeightOutput = HiddenTransposed.Dot(errors_output);
        double[,] deltaWeightOutput2D = Matrix.Create(deltaWeightOutput); //Convert to Matrix
        WeightsHiddenOutput = WeightsHiddenOutput.Add(deltaWeightOutput2D.Multiply(learningRate));

        /*---------------------------------------------------------------
         * -- Calculate Delta of the weight between input and hidden --
         ---------------------------------------------------------------*/
        //First we have to calculate the Error in the hidden nodes ...
        //Transposed because we are going Backwards through the Network
        var WHOTransposed = WeightsHiddenOutput.Transpose();
        //Moves the Error to the output layer
        var errors_hidden = WHOTransposed.Dot(errors_output);
        //Element Wise multiplication (schur product)
        weightedSumHidden = ApplyDerivativeReLU(weightedSumHidden);
        //Moves the Error backthrough the Neuron
        errors_hidden = errors_hidden.Multiply(weightedSumHidden);

        //... then we can Calculate the Delta
        var InputTransposed = Inputs.Transpose();
        var deltaWeightHidden = InputTransposed.Dot(errors_hidden);
        double[,] deltaWeightHidden2D = Matrix.Create(deltaWeightHidden); //Convert to Matrix
        deltaWeightHidden2D = Inputs.Transpose().Dot(deltaWeightHidden2D);

        /*---------------------------------------------------------------
         * --        Adjust Weights and Biases using the delta         --
         ---------------------------------------------------------------*/
        //The Biases just get adjusted by adding the Errors multiplied by the learning rate
        BiasOutput = BiasOutput.Add(errors_output.Multiply(learningRate)); //Output Bias
        BiasHidden = BiasHidden.Add(errors_hidden.Multiply(learningRate)); //Hidden Bias

        WeightsInputHidden = WeightsInputHidden.Add(deltaWeightHidden2D.Multiply(learningRate));           
    }

Если кто-то можетпомогите мне в этом, я был бы очень благодарен, я застрял на этом в течение нескольких дней.Я использовал это Руководство (http://neuralnetworksanddeeplearning.com/chap2.html) в качестве основы для своего кода. Также я использую Accord.Math для Matrix Math.

Спасибо!

1 Ответ

0 голосов
/ 19 июля 2019

Вы можете использовать их с точкой останова, чтобы проверить, где начинается ошибка:

if (double.IsNan(value))
if (double.IsInfinity(value))
if (float.IsNan(value))
if (float.IsInfinity(value))

У меня была такая же проблема (с NaN), и исключения помогли мне найти проблему:

if (double.IsNan(value) || double.IsIninity(value)) throw new Exception();

Инструменты отладки Visual Studio очень полезны - вы можете использовать точки останова для проверки значений в ваших объектах.

...